about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEduard-Mihai Burtescu <edy.burt@gmail.com>2016-03-19 12:30:02 +0200
committerEduard-Mihai Burtescu <edy.burt@gmail.com>2016-03-19 12:30:02 +0200
commit5bf1e58bc0f999a8c179e8a641779bed2d2cad4e (patch)
treebd380d625fe758e97b40a2b90c414e57696019a1
parent835d2a952cf2cb127c47fe964fc1c60cff745653 (diff)
parent135d24dd039306daab7157c4c47963986c091d26 (diff)
downloadrust-5bf1e58bc0f999a8c179e8a641779bed2d2cad4e.tar.gz
rust-5bf1e58bc0f999a8c179e8a641779bed2d2cad4e.zip
Rollup merge of #32347 - Amanieu:volatile_fat_ptr, r=eddyb
Fix volatile stores of fat pointers

This was previously causing an LLVM assertion.

r? @eddyb
-rw-r--r--src/librustc_trans/trans/intrinsic.rs21
-rw-r--r--src/test/run-pass/volatile-fat-ptr.rs22
2 files changed, 35 insertions, 8 deletions
diff --git a/src/librustc_trans/trans/intrinsic.rs b/src/librustc_trans/trans/intrinsic.rs
index 0ad65e5dab4..49cacaac766 100644
--- a/src/librustc_trans/trans/intrinsic.rs
+++ b/src/librustc_trans/trans/intrinsic.rs
@@ -589,15 +589,20 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
         },
         (_, "volatile_store") => {
             let tp_ty = *substs.types.get(FnSpace, 0);
-            let val = if fn_ty.args[1].is_indirect() {
-                Load(bcx, llargs[1])
+            if type_is_fat_ptr(bcx.tcx(), tp_ty) {
+                VolatileStore(bcx, llargs[1], expr::get_dataptr(bcx, llargs[0]));
+                VolatileStore(bcx, llargs[2], expr::get_meta(bcx, llargs[0]));
             } else {
-                from_immediate(bcx, llargs[1])
-            };
-            let ptr = PointerCast(bcx, llargs[0], val_ty(val).ptr_to());
-            let store = VolatileStore(bcx, val, ptr);
-            unsafe {
-                llvm::LLVMSetAlignment(store, type_of::align_of(ccx, tp_ty));
+                let val = if fn_ty.args[1].is_indirect() {
+                    Load(bcx, llargs[1])
+                } else {
+                    from_immediate(bcx, llargs[1])
+                };
+                let ptr = PointerCast(bcx, llargs[0], val_ty(val).ptr_to());
+                let store = VolatileStore(bcx, val, ptr);
+                unsafe {
+                    llvm::LLVMSetAlignment(store, type_of::align_of(ccx, tp_ty));
+                }
             }
             C_nil(ccx)
         },
diff --git a/src/test/run-pass/volatile-fat-ptr.rs b/src/test/run-pass/volatile-fat-ptr.rs
new file mode 100644
index 00000000000..03ba5587fce
--- /dev/null
+++ b/src/test/run-pass/volatile-fat-ptr.rs
@@ -0,0 +1,22 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(volatile)]
+use std::ptr::{read_volatile, write_volatile};
+
+fn main() {
+    let mut x: &'static str = "test";
+    unsafe {
+        let a = read_volatile(&x);
+        assert_eq!(a, "test");
+        write_volatile(&mut x, "foo");
+        assert_eq!(x, "foo");
+    }
+}