about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorAriel Ben-Yehuda <ariel.byd@gmail.com>2017-02-06 17:37:58 +0100
committerAriel Ben-Yehuda <ariel.byd@gmail.com>2017-02-08 22:23:21 +0100
commitffcfdcfe4c73fdd5ff7441a8f8e6a5d77b4e94ee (patch)
treeb70bce0641f1b826af58bc89e489b16a4c9453af /src
parent7ce1f5194c13cfbd90a40a19b93df3a2383b3b9d (diff)
downloadrust-ffcfdcfe4c73fdd5ff7441a8f8e6a5d77b4e94ee.tar.gz
rust-ffcfdcfe4c73fdd5ff7441a8f8e6a5d77b4e94ee.zip
Inline the function `with_lvalue_ref` into `trans_transmute`
The function was a footgun because it created `undef` references to
ZSTs, which could cause trouble were they to leak to user code.
Diffstat (limited to 'src')
-rw-r--r--src/librustc_trans/mir/block.rs36
-rw-r--r--src/librustc_trans/mir/lvalue.rs44
2 files changed, 31 insertions, 49 deletions
diff --git a/src/librustc_trans/mir/block.rs b/src/librustc_trans/mir/block.rs
index 356d3e7372b..9a4cfb6f984 100644
--- a/src/librustc_trans/mir/block.rs
+++ b/src/librustc_trans/mir/block.rs
@@ -11,7 +11,7 @@
 use llvm::{self, ValueRef, BasicBlockRef};
 use rustc_const_eval::{ErrKind, ConstEvalErr, note_const_eval_err};
 use rustc::middle::lang_items;
-use rustc::ty::{self, layout};
+use rustc::ty::{self, layout, TypeFoldable};
 use rustc::mir;
 use abi::{Abi, FnType, ArgType};
 use adt;
@@ -435,10 +435,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
 
                 if intrinsic == Some("transmute") {
                     let &(ref dest, target) = destination.as_ref().unwrap();
-                    self.with_lvalue_ref(&bcx, dest, |this, dest| {
-                        this.trans_transmute(&bcx, &args[0], dest);
-                    });
-
+                    self.trans_transmute(&bcx, &args[0], dest);
                     funclet_br(self, bcx, target);
                     return;
                 }
@@ -877,7 +874,34 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
     }
 
     fn trans_transmute(&mut self, bcx: &Builder<'a, 'tcx>,
-                       src: &mir::Operand<'tcx>, dst: LvalueRef<'tcx>) {
+                       src: &mir::Operand<'tcx>,
+                       dst: &mir::Lvalue<'tcx>) {
+        if let mir::Lvalue::Local(index) = *dst {
+            match self.locals[index] {
+                LocalRef::Lvalue(lvalue) => self.trans_transmute_into(bcx, src, &lvalue),
+                LocalRef::Operand(None) => {
+                    let lvalue_ty = self.monomorphized_lvalue_ty(dst);
+                    assert!(!lvalue_ty.has_erasable_regions());
+                    let lvalue = LvalueRef::alloca(bcx, lvalue_ty, "transmute_temp");
+                    self.trans_transmute_into(bcx, src, &lvalue);
+                    let op = self.trans_load(bcx, lvalue.llval, lvalue.alignment, lvalue_ty);
+                    self.locals[index] = LocalRef::Operand(Some(op));
+                }
+                LocalRef::Operand(Some(_)) => {
+                    let ty = self.monomorphized_lvalue_ty(dst);
+                    assert!(common::type_is_zero_size(bcx.ccx, ty),
+                            "assigning to initialized SSAtemp");
+                }
+            }
+        } else {
+            let dst = self.trans_lvalue(bcx, dst);
+            self.trans_transmute_into(bcx, src, &dst);
+        }
+    }
+
+    fn trans_transmute_into(&mut self, bcx: &Builder<'a, 'tcx>,
+                            src: &mir::Operand<'tcx>,
+                            dst: &LvalueRef<'tcx>) {
         let mut val = self.trans_operand(bcx, src);
         if let ty::TyFnDef(def_id, substs, _) = val.ty.sty {
             let llouttype = type_of::type_of(bcx.ccx, dst.ty.to_ty(bcx.tcx()));
diff --git a/src/librustc_trans/mir/lvalue.rs b/src/librustc_trans/mir/lvalue.rs
index 6800fa34152..2538f32031f 100644
--- a/src/librustc_trans/mir/lvalue.rs
+++ b/src/librustc_trans/mir/lvalue.rs
@@ -15,10 +15,9 @@ use rustc::mir::tcx::LvalueTy;
 use rustc_data_structures::indexed_vec::Idx;
 use adt;
 use builder::Builder;
-use common::{self, CrateContext, C_uint, C_undef};
+use common::{self, CrateContext, C_uint};
 use consts;
 use machine;
-use type_of::type_of;
 use type_of;
 use type_::Type;
 use value::Value;
@@ -416,47 +415,6 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
         result
     }
 
-    // Perform an action using the given Lvalue.
-    // If the Lvalue is an empty LocalRef::Operand, then a temporary stack slot
-    // is created first, then used as an operand to update the Lvalue.
-    //
-    // FIXME: this is only called from transmute; please remove it.
-    pub fn with_lvalue_ref<F, U>(&mut self, bcx: &Builder<'a, 'tcx>,
-                                 lvalue: &mir::Lvalue<'tcx>, f: F) -> U
-    where F: FnOnce(&mut Self, LvalueRef<'tcx>) -> U
-    {
-        if let mir::Lvalue::Local(index) = *lvalue {
-            match self.locals[index] {
-                LocalRef::Lvalue(lvalue) => f(self, lvalue),
-                LocalRef::Operand(None) => {
-                    let lvalue_ty = self.monomorphized_lvalue_ty(lvalue);
-                    assert!(!lvalue_ty.has_erasable_regions());
-                    let lvalue = LvalueRef::alloca(bcx, lvalue_ty, "lvalue_temp");
-                    let ret = f(self, lvalue);
-                    let op = self.trans_load(bcx, lvalue.llval, lvalue.alignment, lvalue_ty);
-                    self.locals[index] = LocalRef::Operand(Some(op));
-                    ret
-                }
-                LocalRef::Operand(Some(_)) => {
-                    // See comments in LocalRef::new_operand as to why
-                    // we always have Some in a ZST LocalRef::Operand.
-                    let ty = self.monomorphized_lvalue_ty(lvalue);
-                    if common::type_is_zero_size(bcx.ccx, ty) {
-                        // Pass an undef pointer as no stores can actually occur.
-                        let llptr = C_undef(type_of(bcx.ccx, ty).ptr_to());
-                        f(self, LvalueRef::new_sized(llptr, LvalueTy::from_ty(ty),
-                                                     Alignment::AbiAligned))
-                    } else {
-                        bug!("Lvalue local already set");
-                    }
-                }
-            }
-        } else {
-            let lvalue = self.trans_lvalue(bcx, lvalue);
-            f(self, lvalue)
-        }
-    }
-
     /// Adjust the bitwidth of an index since LLVM is less forgiving
     /// than we are.
     ///