]> git.lizzy.rs Git - rust.git/commitdiff
auto merge of #15975 : dotdash/rust/unwind_lifetimes, r=pcwalton
authorbors <bors@rust-lang.org>
Sat, 26 Jul 2014 03:31:22 +0000 (03:31 +0000)
committerbors <bors@rust-lang.org>
Sat, 26 Jul 2014 03:31:22 +0000 (03:31 +0000)
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.

src/librustc/middle/trans/cleanup.rs

index c14429b2086ab97be4484ea1d757ae64379252e8..cf2410f6571554d1589849e2bf7d59875617bfaa 100644 (file)
@@ -68,6 +68,7 @@ pub struct CachedEarlyExit {
 }
 
 pub trait Cleanup {
+    fn must_unwind(&self) -> bool;
     fn clean_on_unwind(&self) -> bool;
     fn trans<'a>(&self, bcx: &'a Block<'a>) -> &'a Block<'a>;
 }
@@ -252,7 +253,7 @@ fn schedule_drop_mem(&self,
         if !ty::type_needs_drop(self.ccx.tcx(), ty) { return; }
         let drop = box DropValue {
             is_immediate: false,
-            on_unwind: ty::type_needs_unwind_cleanup(self.ccx.tcx(), ty),
+            must_unwind: ty::type_needs_unwind_cleanup(self.ccx.tcx(), ty),
             val: val,
             ty: ty,
             zero: false
@@ -278,7 +279,7 @@ fn schedule_drop_and_zero_mem(&self,
         if !ty::type_needs_drop(self.ccx.tcx(), ty) { return; }
         let drop = box DropValue {
             is_immediate: false,
-            on_unwind: ty::type_needs_unwind_cleanup(self.ccx.tcx(), ty),
+            must_unwind: ty::type_needs_unwind_cleanup(self.ccx.tcx(), ty),
             val: val,
             ty: ty,
             zero: true
@@ -304,7 +305,7 @@ fn schedule_drop_immediate(&self,
         if !ty::type_needs_drop(self.ccx.tcx(), ty) { return; }
         let drop = box DropValue {
             is_immediate: true,
-            on_unwind: ty::type_needs_unwind_cleanup(self.ccx.tcx(), ty),
+            must_unwind: ty::type_needs_unwind_cleanup(self.ccx.tcx(), ty),
             val: val,
             ty: ty,
             zero: false
@@ -793,10 +794,10 @@ fn add_cached_early_exit(&mut self,
     }
 
     fn needs_invoke(&self) -> bool {
-        /*! True if this scope has cleanups for use during unwinding */
+        /*! True if this scope has cleanups that need unwinding */
 
         self.cached_landing_pad.is_some() ||
-            self.cleanups.iter().any(|c| c.clean_on_unwind())
+            self.cleanups.iter().any(|c| c.must_unwind())
     }
 
     fn block_name(&self, prefix: &str) -> String {
@@ -864,15 +865,19 @@ fn is_unwind(&self) -> bool {
 
 pub struct DropValue {
     is_immediate: bool,
-    on_unwind: bool,
+    must_unwind: bool,
     val: ValueRef,
     ty: ty::t,
     zero: bool
 }
 
 impl Cleanup for DropValue {
+    fn must_unwind(&self) -> bool {
+        self.must_unwind
+    }
+
     fn clean_on_unwind(&self) -> bool {
-        self.on_unwind
+        self.must_unwind
     }
 
     fn trans<'a>(&self, bcx: &'a Block<'a>) -> &'a Block<'a> {
@@ -900,6 +905,10 @@ pub struct FreeValue {
 }
 
 impl Cleanup for FreeValue {
+    fn must_unwind(&self) -> bool {
+        true
+    }
+
     fn clean_on_unwind(&self) -> bool {
         true
     }
@@ -921,10 +930,14 @@ pub struct LifetimeEnd {
 }
 
 impl Cleanup for LifetimeEnd {
-    fn clean_on_unwind(&self) -> bool {
+    fn must_unwind(&self) -> bool {
         false
     }
 
+    fn clean_on_unwind(&self) -> bool {
+        true
+    }
+
     fn trans<'a>(&self, bcx: &'a Block<'a>) -> &'a Block<'a> {
         base::call_lifetime_end(bcx, self.ptr);
         bcx