about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc/middle/trans/_match.rs27
-rw-r--r--src/librustc/middle/trans/base.rs25
-rw-r--r--src/librustc/middle/trans/datum.rs8
3 files changed, 44 insertions, 16 deletions
diff --git a/src/librustc/middle/trans/_match.rs b/src/librustc/middle/trans/_match.rs
index fe5252c423c..419fcffba36 100644
--- a/src/librustc/middle/trans/_match.rs
+++ b/src/librustc/middle/trans/_match.rs
@@ -892,7 +892,12 @@ fn insert_lllocals<'a>(mut bcx: &'a Block<'a>, bindings_map: &BindingsMap,
             TrByCopy(llbinding) => {
                 let llval = Load(bcx, binding_info.llmatch);
                 let datum = Datum::new(llval, binding_info.ty, Lvalue);
+                call_lifetime_start(bcx, llbinding);
                 bcx = datum.store_to(bcx, llbinding);
+                match cs {
+                    Some(cs) => bcx.fcx.schedule_lifetime_end(cs, llbinding),
+                    _ => {}
+                }
 
                 llbinding
             },
@@ -906,7 +911,10 @@ fn insert_lllocals<'a>(mut bcx: &'a Block<'a>, bindings_map: &BindingsMap,
 
         let datum = Datum::new(llval, binding_info.ty, Lvalue);
         match cs {
-            Some(cs) => bcx.fcx.schedule_drop_and_zero_mem(cs, llval, binding_info.ty),
+            Some(cs) => {
+                bcx.fcx.schedule_drop_and_zero_mem(cs, llval, binding_info.ty);
+                bcx.fcx.schedule_lifetime_end(cs, binding_info.llmatch);
+            }
             _ => {}
         }
 
@@ -945,9 +953,17 @@ fn compile_guard<'a, 'b>(
     let val = unpack_datum!(bcx, expr::trans(bcx, guard_expr));
     let val = val.to_llbool(bcx);
 
+    for (_, &binding_info) in data.bindings_map.iter() {
+        match binding_info.trmode {
+            TrByCopy(llbinding) => call_lifetime_end(bcx, llbinding),
+            _ => {}
+        }
+    }
+
     return with_cond(bcx, Not(bcx, val), |bcx| {
         // Guard does not match: remove all bindings from the lllocals table
         for (_, &binding_info) in data.bindings_map.iter() {
+            call_lifetime_end(bcx, binding_info.llmatch);
             bcx.fcx.lllocals.borrow_mut().remove(&binding_info.id);
         }
         match chk {
@@ -988,6 +1004,7 @@ fn compile_submatch<'a, 'b>(
         let data = &m[0].data;
         for &(ref ident, ref value_ptr) in m[0].bound_ptrs.iter() {
             let llmatch = data.bindings_map.get(ident).llmatch;
+            call_lifetime_start(bcx, llmatch);
             Store(bcx, *value_ptr, llmatch);
         }
         match data.arm.guard {
@@ -1294,10 +1311,10 @@ fn create_bindings_map(bcx: &Block, pat: Gc<ast::Pat>) -> BindingsMap {
         match bm {
             ast::BindByValue(_)
                 if !ty::type_moves_by_default(tcx, variable_ty) => {
-                llmatch = alloca(bcx,
+                llmatch = alloca_no_lifetime(bcx,
                                  llvariable_ty.ptr_to(),
                                  "__llmatch");
-                trmode = TrByCopy(alloca(bcx,
+                trmode = TrByCopy(alloca_no_lifetime(bcx,
                                          llvariable_ty,
                                          bcx.ident(ident).as_slice()));
             }
@@ -1305,13 +1322,13 @@ fn create_bindings_map(bcx: &Block, pat: Gc<ast::Pat>) -> BindingsMap {
                 // in this case, the final type of the variable will be T,
                 // but during matching we need to store a *T as explained
                 // above
-                llmatch = alloca(bcx,
+                llmatch = alloca_no_lifetime(bcx,
                                  llvariable_ty.ptr_to(),
                                  bcx.ident(ident).as_slice());
                 trmode = TrByMove;
             }
             ast::BindByRef(_) => {
-                llmatch = alloca(bcx,
+                llmatch = alloca_no_lifetime(bcx,
                                  llvariable_ty,
                                  bcx.ident(ident).as_slice());
                 trmode = TrByRef;
diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs
index dbdb99d3ccd..68d8ab3f04c 100644
--- a/src/librustc/middle/trans/base.rs
+++ b/src/librustc/middle/trans/base.rs
@@ -1169,10 +1169,12 @@ pub fn alloc_ty(bcx: &Block, t: ty::t, name: &str) -> ValueRef {
 }
 
 pub fn alloca(cx: &Block, ty: Type, name: &str) -> ValueRef {
-    alloca_maybe_zeroed(cx, ty, name, false)
+    let p = alloca_no_lifetime(cx, ty, name);
+    call_lifetime_start(cx, p);
+    p
 }
 
-pub fn alloca_maybe_zeroed(cx: &Block, ty: Type, name: &str, zero: bool) -> ValueRef {
+pub fn alloca_no_lifetime(cx: &Block, ty: Type, name: &str) -> ValueRef {
     let _icx = push_ctxt("alloca");
     if cx.unreachable.get() {
         unsafe {
@@ -1180,14 +1182,19 @@ pub fn alloca_maybe_zeroed(cx: &Block, ty: Type, name: &str, zero: bool) -> Valu
         }
     }
     debuginfo::clear_source_location(cx.fcx);
-    let p = Alloca(cx, ty, name);
-    if zero {
-        let b = cx.fcx.ccx.builder();
-        b.position_before(cx.fcx.alloca_insert_pt.get().unwrap());
-        memzero(&b, p, ty);
-    } else {
-        call_lifetime_start(cx, p);
+    Alloca(cx, ty, name)
+}
+
+pub fn alloca_zeroed(cx: &Block, ty: Type, name: &str) -> ValueRef {
+    if cx.unreachable.get() {
+        unsafe {
+            return llvm::LLVMGetUndef(ty.ptr_to().to_ref());
+        }
     }
+    let p = alloca_no_lifetime(cx, ty, name);
+    let b = cx.fcx.ccx.builder();
+    b.position_before(cx.fcx.alloca_insert_pt.get().unwrap());
+    memzero(&b, p, ty);
     p
 }
 
diff --git a/src/librustc/middle/trans/datum.rs b/src/librustc/middle/trans/datum.rs
index 4ea895c89bf..f69a8af9c08 100644
--- a/src/librustc/middle/trans/datum.rs
+++ b/src/librustc/middle/trans/datum.rs
@@ -120,7 +120,11 @@ pub fn lvalue_scratch_datum<'a, A>(bcx: &'a Block<'a>,
      */
 
     let llty = type_of::type_of(bcx.ccx(), ty);
-    let scratch = alloca_maybe_zeroed(bcx, llty, name, zero);
+    let scratch = if zero {
+        alloca_zeroed(bcx, llty, name)
+    } else {
+        alloca(bcx, llty, name)
+    };
 
     // Subtle. Populate the scratch memory *before* scheduling cleanup.
     let bcx = populate(arg, bcx, scratch);
@@ -145,7 +149,7 @@ pub fn rvalue_scratch_datum(bcx: &Block,
      */
 
     let llty = type_of::type_of(bcx.ccx(), ty);
-    let scratch = alloca_maybe_zeroed(bcx, llty, name, false);
+    let scratch = alloca(bcx, llty, name);
     Datum::new(scratch, ty, Rvalue::new(ByRef))
 }