From 07c0faa4070b13f7b59134ecd23f5810852319af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Steinbrink?= Date: Thu, 19 Feb 2015 10:49:14 +0100 Subject: [PATCH] Fix an ICE when translating `if loop {} {}` 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 | 7 +++++++ src/test/compile-fail/if-loop.rs | 20 ++++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 src/test/compile-fail/if-loop.rs diff --git a/src/librustc_trans/trans/controlflow.rs b/src/librustc_trans/trans/controlflow.rs index e6cd44676ce..ea549889ffa 100644 --- a/src/librustc_trans/trans/controlflow.rs +++ b/src/librustc_trans/trans/controlflow.rs @@ -12,6 +12,7 @@ use llvm::ValueRef; 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 index 00000000000..15f04df6939 --- /dev/null +++ b/src/test/compile-fail/if-loop.rs @@ -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 or the MIT license +// , 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