]> git.lizzy.rs Git - rust.git/commitdiff
Rollup merge of #22527 - dotdash:if-loop, r=huonw
authorManish Goregaokar <manishsmail@gmail.com>
Sat, 21 Feb 2015 20:17:28 +0000 (01:47 +0530)
committerManish Goregaokar <manishsmail@gmail.com>
Sat, 21 Feb 2015 20:17:28 +0000 (01:47 +0530)
 In `if loop {} {}`, the `if` is actually unreachable, but we didn't
handle that correctly and when trying to translate the `if` we tried to
branch on the \"return value\" of the loop expression, which is not an
`i1` and therefore triggered an LLVM assertion.

src/librustc_trans/trans/controlflow.rs
src/test/compile-fail/if-loop.rs [new file with mode: 0644]

index 26e12a1af403dac45981d8bd2e4751c9f60fec69..600201a97c948e251bc2dc1225ad48b4f74f5dd9 100644 (file)
@@ -12,6 +12,7 @@
 use middle::def;
 use middle::lang_items::{PanicFnLangItem, PanicBoundsCheckFnLangItem};
 use trans::base::*;
+use trans::basic_block::BasicBlock;
 use trans::build::*;
 use trans::callee;
 use trans::cleanup::CleanupMethods;
@@ -280,6 +281,12 @@ pub fn trans_loop<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
 
     fcx.pop_loop_cleanup_scope(loop_expr.id);
 
+    // If there are no predecessors for the next block, we just translated an endless loop and the
+    // next block is unreachable
+    if BasicBlock(next_bcx_in.llbb).pred_iter().next().is_none() {
+        Unreachable(next_bcx_in);
+    }
+
     return next_bcx_in;
 }
 
diff --git a/src/test/compile-fail/if-loop.rs b/src/test/compile-fail/if-loop.rs
new file mode 100644 (file)
index 0000000..15f04df
--- /dev/null
@@ -0,0 +1,20 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(rustc_attrs)]
+#![allow(warnings)]
+
+// This used to ICE because the "if" being unreachable was not handled correctly
+fn err() {
+    if loop {} {}
+}
+
+#[rustc_error]
+fn main() {} //~ ERROR compilation successful