diff options
| author | bors <bors@rust-lang.org> | 2017-08-13 23:33:18 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2017-08-13 23:33:18 +0000 |
| commit | f3cf2062015200c0705ec2820dd02a7b9dc9bb22 (patch) | |
| tree | b149697c31af598a1db90730d72d8dca1d2cd8b8 /src/libcore | |
| parent | ab40a7cb0e01159a04d4cfffc432c6d77f1f23c8 (diff) | |
| parent | faf6b84304dbc96f7bf142973f394f820e390a4c (diff) | |
| download | rust-f3cf2062015200c0705ec2820dd02a7b9dc9bb22.tar.gz rust-f3cf2062015200c0705ec2820dd02a7b9dc9bb22.zip | |
Auto merge of #43836 - taleks:issue-39827, r=arielb1
Fix for issue #39827 *Cause of the issue* While preparing for `trans_intrinsic_call()` invoke arguments are processed with `trans_argument()` method which excludes zero-sized types from argument list (to be more correct - all arguments for which `ArgKind` is `Ignore` are filtered out). As result `volatile_store()` intrinsic gets one argument instead of expected address and value. *How it is fixed* Modification of the `trans_argument()` method may cause side effects, therefore change was implemented in `volatile_store()` intrinsic building code itself. Now it checks function signature and if it was specialised with zero-sized type, then emits `C_nil()` instead of accessing non-existing second argument.
Diffstat (limited to 'src/libcore')
| -rw-r--r-- | src/libcore/intrinsics.rs | 9 | ||||
| -rw-r--r-- | src/libcore/ptr.rs | 10 |
2 files changed, 16 insertions, 3 deletions
diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs index fdca8d00d7a..ad776c8605a 100644 --- a/src/libcore/intrinsics.rs +++ b/src/libcore/intrinsics.rs @@ -1044,20 +1044,23 @@ extern "rust-intrinsic" { /// a size of `count` * `size_of::<T>()` and an alignment of /// `min_align_of::<T>()` /// - /// The volatile parameter is set to `true`, so it will not be optimized out. + /// The volatile parameter is set to `true`, so it will not be optimized out + /// unless size is equal to zero. pub fn volatile_copy_nonoverlapping_memory<T>(dst: *mut T, src: *const T, count: usize); /// Equivalent to the appropriate `llvm.memmove.p0i8.0i8.*` intrinsic, with /// a size of `count` * `size_of::<T>()` and an alignment of /// `min_align_of::<T>()` /// - /// The volatile parameter is set to `true`, so it will not be optimized out. + /// The volatile parameter is set to `true`, so it will not be optimized out + /// unless size is equal to zero.. pub fn volatile_copy_memory<T>(dst: *mut T, src: *const T, count: usize); /// Equivalent to the appropriate `llvm.memset.p0i8.*` intrinsic, with a /// size of `count` * `size_of::<T>()` and an alignment of /// `min_align_of::<T>()`. /// - /// The volatile parameter is set to `true`, so it will not be optimized out. + /// The volatile parameter is set to `true`, so it will not be optimized out + /// unless size is equal to zero. pub fn volatile_set_memory<T>(dst: *mut T, val: u8, count: usize); /// Perform a volatile load from the `src` pointer. diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index 60cf1a20530..e35777d222c 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -384,6 +384,11 @@ pub unsafe fn write_unaligned<T>(dst: *mut T, src: T) { /// over time. That being said, the semantics will almost always end up pretty /// similar to [C11's definition of volatile][c11]. /// +/// The compiler shouldn't change the relative order or number of volatile +/// memory operations. However, volatile memory operations on zero-sized types +/// (e.g. if a zero-sized type is passed to `read_volatile`) are no-ops +/// and may be ignored. +/// /// [c11]: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf /// /// # Safety @@ -427,6 +432,11 @@ pub unsafe fn read_volatile<T>(src: *const T) -> T { /// over time. That being said, the semantics will almost always end up pretty /// similar to [C11's definition of volatile][c11]. /// +/// The compiler shouldn't change the relative order or number of volatile +/// memory operations. However, volatile memory operations on zero-sized types +/// (e.g. if a zero-sized type is passed to `write_volatile`) are no-ops +/// and may be ignored. +/// /// [c11]: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf /// /// # Safety |
