Skip to content

Commit 34a6a8f

Browse files
committed
auto merge of #15975 : dotdash/rust/unwind_lifetimes, r=pcwalton
Currently we don't emit lifetime end markers when translating the unwinding code. I omitted that when I added the support for lifetime intrinsics, because I initially made the mistake of just returning true in clean_on_unwind(). That caused almost all calls to be translated as invokes, leading to quite awful results. To correctly emit the lifetime end markers, we must differentiate between cleanup that requires unwinding and such cleanup that just wants to emit code during unwinding.
2 parents cf1381c + b13cad3 commit 34a6a8f

File tree

1 file changed

+21
-8
lines changed

1 file changed

+21
-8
lines changed

src/librustc/middle/trans/cleanup.rs

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ pub struct CachedEarlyExit {
6868
}
6969

7070
pub trait Cleanup {
71+
fn must_unwind(&self) -> bool;
7172
fn clean_on_unwind(&self) -> bool;
7273
fn trans<'a>(&self, bcx: &'a Block<'a>) -> &'a Block<'a>;
7374
}
@@ -252,7 +253,7 @@ impl<'a> CleanupMethods<'a> for FunctionContext<'a> {
252253
if !ty::type_needs_drop(self.ccx.tcx(), ty) { return; }
253254
let drop = box DropValue {
254255
is_immediate: false,
255-
on_unwind: ty::type_needs_unwind_cleanup(self.ccx.tcx(), ty),
256+
must_unwind: ty::type_needs_unwind_cleanup(self.ccx.tcx(), ty),
256257
val: val,
257258
ty: ty,
258259
zero: false
@@ -278,7 +279,7 @@ impl<'a> CleanupMethods<'a> for FunctionContext<'a> {
278279
if !ty::type_needs_drop(self.ccx.tcx(), ty) { return; }
279280
let drop = box DropValue {
280281
is_immediate: false,
281-
on_unwind: ty::type_needs_unwind_cleanup(self.ccx.tcx(), ty),
282+
must_unwind: ty::type_needs_unwind_cleanup(self.ccx.tcx(), ty),
282283
val: val,
283284
ty: ty,
284285
zero: true
@@ -304,7 +305,7 @@ impl<'a> CleanupMethods<'a> for FunctionContext<'a> {
304305
if !ty::type_needs_drop(self.ccx.tcx(), ty) { return; }
305306
let drop = box DropValue {
306307
is_immediate: true,
307-
on_unwind: ty::type_needs_unwind_cleanup(self.ccx.tcx(), ty),
308+
must_unwind: ty::type_needs_unwind_cleanup(self.ccx.tcx(), ty),
308309
val: val,
309310
ty: ty,
310311
zero: false
@@ -793,10 +794,10 @@ impl<'a> CleanupScope<'a> {
793794
}
794795

795796
fn needs_invoke(&self) -> bool {
796-
/*! True if this scope has cleanups for use during unwinding */
797+
/*! True if this scope has cleanups that need unwinding */
797798

798799
self.cached_landing_pad.is_some() ||
799-
self.cleanups.iter().any(|c| c.clean_on_unwind())
800+
self.cleanups.iter().any(|c| c.must_unwind())
800801
}
801802

802803
fn block_name(&self, prefix: &str) -> String {
@@ -864,15 +865,19 @@ impl EarlyExitLabel {
864865

865866
pub struct DropValue {
866867
is_immediate: bool,
867-
on_unwind: bool,
868+
must_unwind: bool,
868869
val: ValueRef,
869870
ty: ty::t,
870871
zero: bool
871872
}
872873

873874
impl Cleanup for DropValue {
875+
fn must_unwind(&self) -> bool {
876+
self.must_unwind
877+
}
878+
874879
fn clean_on_unwind(&self) -> bool {
875-
self.on_unwind
880+
self.must_unwind
876881
}
877882

878883
fn trans<'a>(&self, bcx: &'a Block<'a>) -> &'a Block<'a> {
@@ -900,6 +905,10 @@ pub struct FreeValue {
900905
}
901906

902907
impl Cleanup for FreeValue {
908+
fn must_unwind(&self) -> bool {
909+
true
910+
}
911+
903912
fn clean_on_unwind(&self) -> bool {
904913
true
905914
}
@@ -921,10 +930,14 @@ pub struct LifetimeEnd {
921930
}
922931

923932
impl Cleanup for LifetimeEnd {
924-
fn clean_on_unwind(&self) -> bool {
933+
fn must_unwind(&self) -> bool {
925934
false
926935
}
927936

937+
fn clean_on_unwind(&self) -> bool {
938+
true
939+
}
940+
928941
fn trans<'a>(&self, bcx: &'a Block<'a>) -> &'a Block<'a> {
929942
base::call_lifetime_end(bcx, self.ptr);
930943
bcx

0 commit comments

Comments
 (0)