diff --git a/src/librustc/middle/trans/_match.rs b/src/librustc/middle/trans/_match.rs index fe5252c423cce..419fcffba3686 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) -> 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) -> 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 dbdb99d3ccd94..68d8ab3f04c6f 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 4ea895c89bf25..f69a8af9c08d3 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)) }