Skip to content

Commit

Permalink
Rollup merge of rust-lang#23066 - michaelwoerister:unreachable-if, r=…
Browse files Browse the repository at this point in the history
…pnkfelix

This PR solves rust-lang#21559 by making sure that unreachable if-expressions are not further translated.

Could someone who knows their way around `trans` take a look at the changes in `controlflow.rs`? I'm not sure if any other code relies on any side-effects of translating unreachable things.

cc @nikomatsakis @nrc @eddyb
  • Loading branch information
Manishearth committed Apr 1, 2015
2 parents d528aa9 + e05c2f8 commit 02b38a2
Show file tree
Hide file tree
Showing 2 changed files with 128 additions and 2 deletions.
45 changes: 44 additions & 1 deletion src/librustc_trans/trans/controlflow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()));
}
Expand Down Expand Up @@ -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
Expand All @@ -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;

Expand Down Expand Up @@ -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());
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -296,12 +325,13 @@ pub fn trans_break_cont<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
exit: usize)
-> 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(),
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down
85 changes: 84 additions & 1 deletion src/test/debuginfo/unreachable-locals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand All @@ -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() {
Expand All @@ -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() {
Expand All @@ -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();
}
}
}
}

Expand All @@ -83,3 +163,6 @@ fn main() {
fn diverge() -> ! {
panic!();
}

fn some_predicate() -> bool { true || false }

0 comments on commit 02b38a2

Please sign in to comment.