From 682f867bbfff97e3aef55bdf228d279e45f25cd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Steinbrink?= Date: Fri, 30 Jan 2015 17:14:17 +0100 Subject: [PATCH] Add missing calls to llvm.lifetime.end intrinsics These missing calls lead to miscompilations with more recent LLVM versions. --- src/librustc_trans/trans/base.rs | 6 +++++- src/librustc_trans/trans/datum.rs | 4 ++++ src/librustc_trans/trans/intrinsic.rs | 9 +++++++-- 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs index 1195b9f084b..5e7ea67fd84 100644 --- a/src/librustc_trans/trans/base.rs +++ b/src/librustc_trans/trans/base.rs @@ -2007,7 +2007,11 @@ pub fn trans_named_tuple_constructor<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, let bcx = match dest { expr::SaveIn(_) => bcx, expr::Ignore => { - glue::drop_ty(bcx, llresult, result_ty, debug_loc) + let bcx = glue::drop_ty(bcx, llresult, result_ty, debug_loc); + if !type_is_zero_size(ccx, result_ty) { + call_lifetime_end(bcx, llresult); + } + bcx } }; diff --git a/src/librustc_trans/trans/datum.rs b/src/librustc_trans/trans/datum.rs index dd4ef97b88d..39d17f45ffa 100644 --- a/src/librustc_trans/trans/datum.rs +++ b/src/librustc_trans/trans/datum.rs @@ -199,6 +199,9 @@ impl KindOps for Rvalue { -> Block<'blk, 'tcx> { // No cleanup is scheduled for an rvalue, so we don't have // to do anything after a move to cancel or duplicate it. + if self.is_by_ref() { + call_lifetime_end(bcx, _val); + } bcx } @@ -320,6 +323,7 @@ impl<'tcx> Datum<'tcx, Rvalue> { ByValue => DatumBlock::new(bcx, self), ByRef => { let llval = load_ty(bcx, self.val, self.ty); + call_lifetime_end(bcx, self.val); DatumBlock::new(bcx, Datum::new(llval, self.ty, Rvalue::new(ByValue))) } } diff --git a/src/librustc_trans/trans/intrinsic.rs b/src/librustc_trans/trans/intrinsic.rs index 9bee2c5bbc6..35e91791855 100644 --- a/src/librustc_trans/trans/intrinsic.rs +++ b/src/librustc_trans/trans/intrinsic.rs @@ -243,7 +243,8 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, dest }; - fcx.pop_custom_cleanup_scope(cleanup_scope); + fcx.scopes.borrow_mut().last_mut().unwrap().drop_non_lifetime_clean(); + fcx.pop_and_trans_custom_cleanup_scope(bcx, cleanup_scope); return match dest { expr::SaveIn(d) => Result::new(bcx, d), @@ -268,7 +269,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, false, RustIntrinsic); - fcx.pop_custom_cleanup_scope(cleanup_scope); + fcx.scopes.borrow_mut().last_mut().unwrap().drop_non_lifetime_clean(); let call_debug_location = DebugLoc::At(call_info.id, call_info.span); @@ -276,9 +277,11 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, if name.get() == "abort" { let llfn = ccx.get_intrinsic(&("llvm.trap")); Call(bcx, llfn, &[], None, call_debug_location); + fcx.pop_and_trans_custom_cleanup_scope(bcx, cleanup_scope); Unreachable(bcx); return Result::new(bcx, C_undef(Type::nil(ccx).ptr_to())); } else if name.get() == "unreachable" { + fcx.pop_and_trans_custom_cleanup_scope(bcx, cleanup_scope); Unreachable(bcx); return Result::new(bcx, C_nil(ccx)); } @@ -765,6 +768,8 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, expr::SaveIn(_) => {} } + fcx.pop_and_trans_custom_cleanup_scope(bcx, cleanup_scope); + Result::new(bcx, llresult) }