about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc_trans/mir/block.rs28
-rw-r--r--src/librustc_trans/mir/mod.rs27
2 files changed, 20 insertions, 35 deletions
diff --git a/src/librustc_trans/mir/block.rs b/src/librustc_trans/mir/block.rs
index 577c304d0f7..e259f7c20f2 100644
--- a/src/librustc_trans/mir/block.rs
+++ b/src/librustc_trans/mir/block.rs
@@ -863,32 +863,6 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
         bcx.llbb()
     }
 
-    pub fn init_cpad(&mut self, bb: mir::BasicBlock,
-        funclets: &mut IndexVec<mir::BasicBlock, Option<Funclet>>) {
-        let bcx = self.build_block(bb);
-        let data = &self.mir[bb];
-        debug!("init_cpad({:?})", data);
-
-        match self.cleanup_kinds[bb] {
-            CleanupKind::NotCleanup => {
-                funclets[bb] = None;
-            }
-            _ if !base::wants_msvc_seh(bcx.sess()) => {
-                funclets[bb] = Funclet::gnu();
-            }
-            CleanupKind::Internal { funclet: _ } => {
-                // FIXME: is this needed?
-                bcx.set_personality_fn(self.fcx.eh_personality());
-                funclets[bb] = None;
-            }
-            CleanupKind::Funclet => {
-                bcx.set_personality_fn(self.fcx.eh_personality());
-                let cleanup_pad = bcx.cleanup_pad(None, &[]);
-                funclets[bb] = Funclet::msvc(cleanup_pad);
-            }
-        };
-    }
-
     fn unreachable_block(&mut self) -> BasicBlockRef {
         self.unreachable_block.unwrap_or_else(|| {
             let bl = self.fcx.build_new_block("unreachable");
@@ -898,7 +872,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
         })
     }
 
-    fn build_block(&self, bb: mir::BasicBlock) -> BlockAndBuilder<'a, 'tcx> {
+    pub fn build_block(&self, bb: mir::BasicBlock) -> BlockAndBuilder<'a, 'tcx> {
         BlockAndBuilder::new(self.blocks[bb], self.fcx)
     }
 
diff --git a/src/librustc_trans/mir/mod.rs b/src/librustc_trans/mir/mod.rs
index 6f376251d9b..f8bd087b0da 100644
--- a/src/librustc_trans/mir/mod.rs
+++ b/src/librustc_trans/mir/mod.rs
@@ -36,6 +36,7 @@ use rustc_data_structures::indexed_vec::{IndexVec, Idx};
 
 pub use self::constant::trans_static_initializer;
 
+use self::analyze::CleanupKind;
 use self::lvalue::{LvalueRef};
 use rustc::mir::traversal;
 
@@ -315,18 +316,28 @@ pub fn trans_mir<'a, 'tcx: 'a>(
     // emitting should be enabled.
     debuginfo::start_emitting_source_locations(&mircx);
 
-    let mut visited = BitVector::new(mir.basic_blocks().len());
-
-    let mut rpo = traversal::reverse_postorder(&mir);
-
     let mut funclets: IndexVec<mir::BasicBlock, Option<Funclet>> =
         IndexVec::from_elem(None, mir.basic_blocks());
 
-    // Prepare each block for translation.
-    for (bb, _) in rpo.by_ref() {
-        mircx.init_cpad(bb, &mut funclets);
+    // If false, all funclets should be None (which is the default)
+    if base::wants_msvc_seh(fcx.ccx.sess()) {
+        for (bb, cleanup_kind) in mircx.cleanup_kinds.iter_enumerated() {
+            let bcx = mircx.build_block(bb);
+            match *cleanup_kind {
+                CleanupKind::Internal { .. } => {
+                    bcx.set_personality_fn(fcx.eh_personality());
+                }
+                CleanupKind::Funclet => {
+                    bcx.set_personality_fn(fcx.eh_personality());
+                    funclets[bb] = Funclet::msvc(bcx.cleanup_pad(None, &[]));
+                }
+                _ => {}
+            }
+        }
     }
-    rpo.reset();
+
+    let rpo = traversal::reverse_postorder(&mir);
+    let mut visited = BitVector::new(mir.basic_blocks().len());
 
     // Translate the body of each block using reverse postorder
     for (bb, _) in rpo {