]> git.lizzy.rs Git - rust.git/commitdiff
trans: Add early-out when translating unreachable controlflow expressions.
authorMichael Woerister <michaelwoerister@posteo>
Thu, 5 Mar 2015 09:46:45 +0000 (10:46 +0100)
committerMichael Woerister <michaelwoerister@posteo>
Thu, 5 Mar 2015 12:57:51 +0000 (13:57 +0100)
src/librustc_trans/trans/controlflow.rs
src/test/debuginfo/unreachable-locals.rs

index 85d0bc0319f308d93998463b3c2c410d5af30e53..9093f56d33accf8f6e269da1104468a92c2f7279 100644 (file)
@@ -40,6 +40,10 @@ pub fn trans_stmt<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
     let fcx = cx.fcx;
     debug!("trans_stmt({})", s.repr(cx.tcx()));
 
+    if cx.unreachable.get() {
+        return cx;
+    }
+
     if cx.sess().asm_comments() {
         add_span_comment(cx, s.span, &s.repr(cx.tcx()));
     }
@@ -76,6 +80,11 @@ pub fn trans_stmt<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
 pub fn trans_stmt_semi<'blk, 'tcx>(cx: Block<'blk, 'tcx>, e: &ast::Expr)
                                    -> Block<'blk, 'tcx> {
     let _icx = push_ctxt("trans_stmt_semi");
+
+    if cx.unreachable.get() {
+        return cx;
+    }
+
     let ty = expr_ty(cx, e);
     if cx.fcx.type_needs_drop(ty) {
         expr::trans_to_lvalue(cx, e, "stmt").bcx
@@ -89,6 +98,11 @@ pub fn trans_block<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                                mut dest: expr::Dest)
                                -> Block<'blk, 'tcx> {
     let _icx = push_ctxt("trans_block");
+
+    if bcx.unreachable.get() {
+        return bcx;
+    }
+
     let fcx = bcx.fcx;
     let mut bcx = bcx;
 
@@ -141,6 +155,11 @@ pub fn trans_if<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
            bcx.to_str(), if_id, bcx.expr_to_string(cond), thn.id,
            dest.to_string(bcx.ccx()));
     let _icx = push_ctxt("trans_if");
+
+    if bcx.unreachable.get() {
+        return bcx;
+    }
+
     let mut bcx = bcx;
 
     let cond_val = unpack_result!(bcx, expr::trans(bcx, cond).to_llbool());
@@ -214,6 +233,11 @@ pub fn trans_while<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                                body: &ast::Block)
                                -> Block<'blk, 'tcx> {
     let _icx = push_ctxt("trans_while");
+
+    if bcx.unreachable.get() {
+        return bcx;
+    }
+
     let fcx = bcx.fcx;
 
     //            bcx
@@ -257,6 +281,11 @@ pub fn trans_loop<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                               body: &ast::Block)
                               -> Block<'blk, 'tcx> {
     let _icx = push_ctxt("trans_loop");
+
+    if bcx.unreachable.get() {
+        return bcx;
+    }
+
     let fcx = bcx.fcx;
 
     //            bcx
@@ -296,12 +325,13 @@ pub fn trans_break_cont<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                                     exit: uint)
                                     -> Block<'blk, 'tcx> {
     let _icx = push_ctxt("trans_break_cont");
-    let fcx = bcx.fcx;
 
     if bcx.unreachable.get() {
         return bcx;
     }
 
+    let fcx = bcx.fcx;
+
     // Locate loop that we will break to
     let loop_id = match opt_label {
         None => fcx.top_loop_scope(),
@@ -341,6 +371,11 @@ pub fn trans_ret<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                              retval_expr: Option<&ast::Expr>)
                              -> Block<'blk, 'tcx> {
     let _icx = push_ctxt("trans_ret");
+
+    if bcx.unreachable.get() {
+        return bcx;
+    }
+
     let fcx = bcx.fcx;
     let mut bcx = bcx;
     let dest = match (fcx.llretslotptr.get(), retval_expr) {
@@ -372,6 +407,10 @@ pub fn trans_fail<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     let ccx = bcx.ccx();
     let _icx = push_ctxt("trans_fail_value");
 
+    if bcx.unreachable.get() {
+        return bcx;
+    }
+
     let v_str = C_str_slice(ccx, fail_str);
     let loc = bcx.sess().codemap().lookup_char_pos(call_info.span.lo);
     let filename = token::intern_and_get_ident(&loc.file.name);
@@ -399,6 +438,10 @@ pub fn trans_fail_bounds_check<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     let ccx = bcx.ccx();
     let _icx = push_ctxt("trans_fail_bounds_check");
 
+    if bcx.unreachable.get() {
+        return bcx;
+    }
+
     // Extract the file/line from the span
     let loc = bcx.sess().codemap().lookup_char_pos(call_info.span.lo);
     let filename = token::intern_and_get_ident(&loc.file.name);
index 309848d6cedc9b400e00b9ba55b43cfc543a27c8..63536b1383475be0889ea6b93bb21a572f6ccb74 100644 (file)
@@ -26,6 +26,22 @@ fn after_return() {
         (a, ref b) => {}
     }
     for a in &[111i32] {}
+    let test = if some_predicate() { 1 } else { 2 };
+    while some_predicate() {
+        let abc = !some_predicate();
+    }
+    loop {
+        let abc = !some_predicate();
+        break;
+    }
+    // nested block
+    {
+        let abc = !some_predicate();
+
+        {
+            let def = !some_predicate();
+        }
+    }
 }
 
 fn after_panic() {
@@ -36,6 +52,22 @@ fn after_panic() {
         (a, ref b) => {}
     }
     for a in &[111i32] {}
+    let test = if some_predicate() { 1 } else { 2 };
+    while some_predicate() {
+        let abc = !some_predicate();
+    }
+    loop {
+        let abc = !some_predicate();
+        break;
+    }
+    // nested block
+    {
+        let abc = !some_predicate();
+
+        {
+            let def = !some_predicate();
+        }
+    }
 }
 
 fn after_diverging_function() {
@@ -46,6 +78,22 @@ fn after_diverging_function() {
         (a, ref b) => {}
     }
     for a in &[111i32] {}
+    let test = if some_predicate() { 1 } else { 2 };
+    while some_predicate() {
+        let abc = !some_predicate();
+    }
+    loop {
+        let abc = !some_predicate();
+        break;
+    }
+    // nested block
+    {
+        let abc = !some_predicate();
+
+        {
+            let def = !some_predicate();
+        }
+    }
 }
 
 fn after_break() {
@@ -57,18 +105,50 @@ fn after_break() {
             (a, ref b) => {}
         }
         for a in &[111i32] {}
+        let test = if some_predicate() { 1 } else { 2 };
+        while some_predicate() {
+            let abc = !some_predicate();
+        }
+        loop {
+            let abc = !some_predicate();
+            break;
+        }
+        // nested block
+        {
+            let abc = !some_predicate();
+
+            {
+                let def = !some_predicate();
+            }
+        }
     }
 }
 
 fn after_continue() {
     for _ in 0..10i32 {
-        break;
+        continue;
         let x = "0";
         let (ref y,z) = (1i32, 2u32);
         match (20i32, 'c') {
             (a, ref b) => {}
         }
         for a in &[111i32] {}
+        let test = if some_predicate() { 1 } else { 2 };
+        while some_predicate() {
+            let abc = !some_predicate();
+        }
+        loop {
+            let abc = !some_predicate();
+            break;
+        }
+        // nested block
+        {
+            let abc = !some_predicate();
+
+            {
+                let def = !some_predicate();
+            }
+        }
     }
 }
 
@@ -83,3 +163,6 @@ fn main() {
 fn diverge() -> ! {
     panic!();
 }
+
+fn some_predicate() -> bool { true || false }
+