about summary refs log tree commit diff
path: root/src/libcore
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2017-08-13 23:33:18 +0000
committerbors <bors@rust-lang.org>2017-08-13 23:33:18 +0000
commitf3cf2062015200c0705ec2820dd02a7b9dc9bb22 (patch)
treeb149697c31af598a1db90730d72d8dca1d2cd8b8 /src/libcore
parentab40a7cb0e01159a04d4cfffc432c6d77f1f23c8 (diff)
parentfaf6b84304dbc96f7bf142973f394f820e390a4c (diff)
downloadrust-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.rs9
-rw-r--r--src/libcore/ptr.rs10
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