Rollup merge of #23066 - michaelwoerister:unreachable-if, r=pnkfelix
This PR solves #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
This commit is contained in:
commit
02b38a2497
@ -40,6 +40,10 @@ pub fn trans_stmt<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
|
|||||||
let fcx = cx.fcx;
|
let fcx = cx.fcx;
|
||||||
debug!("trans_stmt({})", s.repr(cx.tcx()));
|
debug!("trans_stmt({})", s.repr(cx.tcx()));
|
||||||
|
|
||||||
|
if cx.unreachable.get() {
|
||||||
|
return cx;
|
||||||
|
}
|
||||||
|
|
||||||
if cx.sess().asm_comments() {
|
if cx.sess().asm_comments() {
|
||||||
add_span_comment(cx, s.span, &s.repr(cx.tcx()));
|
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)
|
pub fn trans_stmt_semi<'blk, 'tcx>(cx: Block<'blk, 'tcx>, e: &ast::Expr)
|
||||||
-> Block<'blk, 'tcx> {
|
-> Block<'blk, 'tcx> {
|
||||||
let _icx = push_ctxt("trans_stmt_semi");
|
let _icx = push_ctxt("trans_stmt_semi");
|
||||||
|
|
||||||
|
if cx.unreachable.get() {
|
||||||
|
return cx;
|
||||||
|
}
|
||||||
|
|
||||||
let ty = expr_ty(cx, e);
|
let ty = expr_ty(cx, e);
|
||||||
if cx.fcx.type_needs_drop(ty) {
|
if cx.fcx.type_needs_drop(ty) {
|
||||||
expr::trans_to_lvalue(cx, e, "stmt").bcx
|
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)
|
mut dest: expr::Dest)
|
||||||
-> Block<'blk, 'tcx> {
|
-> Block<'blk, 'tcx> {
|
||||||
let _icx = push_ctxt("trans_block");
|
let _icx = push_ctxt("trans_block");
|
||||||
|
|
||||||
|
if bcx.unreachable.get() {
|
||||||
|
return bcx;
|
||||||
|
}
|
||||||
|
|
||||||
let fcx = bcx.fcx;
|
let fcx = bcx.fcx;
|
||||||
let mut bcx = bcx;
|
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,
|
bcx.to_str(), if_id, bcx.expr_to_string(cond), thn.id,
|
||||||
dest.to_string(bcx.ccx()));
|
dest.to_string(bcx.ccx()));
|
||||||
let _icx = push_ctxt("trans_if");
|
let _icx = push_ctxt("trans_if");
|
||||||
|
|
||||||
|
if bcx.unreachable.get() {
|
||||||
|
return bcx;
|
||||||
|
}
|
||||||
|
|
||||||
let mut bcx = bcx;
|
let mut bcx = bcx;
|
||||||
|
|
||||||
let cond_val = unpack_result!(bcx, expr::trans(bcx, cond).to_llbool());
|
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)
|
body: &ast::Block)
|
||||||
-> Block<'blk, 'tcx> {
|
-> Block<'blk, 'tcx> {
|
||||||
let _icx = push_ctxt("trans_while");
|
let _icx = push_ctxt("trans_while");
|
||||||
|
|
||||||
|
if bcx.unreachable.get() {
|
||||||
|
return bcx;
|
||||||
|
}
|
||||||
|
|
||||||
let fcx = bcx.fcx;
|
let fcx = bcx.fcx;
|
||||||
|
|
||||||
// bcx
|
// bcx
|
||||||
@ -257,6 +281,11 @@ pub fn trans_loop<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
|||||||
body: &ast::Block)
|
body: &ast::Block)
|
||||||
-> Block<'blk, 'tcx> {
|
-> Block<'blk, 'tcx> {
|
||||||
let _icx = push_ctxt("trans_loop");
|
let _icx = push_ctxt("trans_loop");
|
||||||
|
|
||||||
|
if bcx.unreachable.get() {
|
||||||
|
return bcx;
|
||||||
|
}
|
||||||
|
|
||||||
let fcx = bcx.fcx;
|
let fcx = bcx.fcx;
|
||||||
|
|
||||||
// bcx
|
// bcx
|
||||||
@ -296,12 +325,13 @@ pub fn trans_break_cont<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
|||||||
exit: usize)
|
exit: usize)
|
||||||
-> Block<'blk, 'tcx> {
|
-> Block<'blk, 'tcx> {
|
||||||
let _icx = push_ctxt("trans_break_cont");
|
let _icx = push_ctxt("trans_break_cont");
|
||||||
let fcx = bcx.fcx;
|
|
||||||
|
|
||||||
if bcx.unreachable.get() {
|
if bcx.unreachable.get() {
|
||||||
return bcx;
|
return bcx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let fcx = bcx.fcx;
|
||||||
|
|
||||||
// Locate loop that we will break to
|
// Locate loop that we will break to
|
||||||
let loop_id = match opt_label {
|
let loop_id = match opt_label {
|
||||||
None => fcx.top_loop_scope(),
|
None => fcx.top_loop_scope(),
|
||||||
@ -341,6 +371,11 @@ pub fn trans_ret<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
|||||||
retval_expr: Option<&ast::Expr>)
|
retval_expr: Option<&ast::Expr>)
|
||||||
-> Block<'blk, 'tcx> {
|
-> Block<'blk, 'tcx> {
|
||||||
let _icx = push_ctxt("trans_ret");
|
let _icx = push_ctxt("trans_ret");
|
||||||
|
|
||||||
|
if bcx.unreachable.get() {
|
||||||
|
return bcx;
|
||||||
|
}
|
||||||
|
|
||||||
let fcx = bcx.fcx;
|
let fcx = bcx.fcx;
|
||||||
let mut bcx = bcx;
|
let mut bcx = bcx;
|
||||||
let dest = match (fcx.llretslotptr.get(), retval_expr) {
|
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 ccx = bcx.ccx();
|
||||||
let _icx = push_ctxt("trans_fail_value");
|
let _icx = push_ctxt("trans_fail_value");
|
||||||
|
|
||||||
|
if bcx.unreachable.get() {
|
||||||
|
return bcx;
|
||||||
|
}
|
||||||
|
|
||||||
let v_str = C_str_slice(ccx, fail_str);
|
let v_str = C_str_slice(ccx, fail_str);
|
||||||
let loc = bcx.sess().codemap().lookup_char_pos(call_info.span.lo);
|
let loc = bcx.sess().codemap().lookup_char_pos(call_info.span.lo);
|
||||||
let filename = token::intern_and_get_ident(&loc.file.name);
|
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 ccx = bcx.ccx();
|
||||||
let _icx = push_ctxt("trans_fail_bounds_check");
|
let _icx = push_ctxt("trans_fail_bounds_check");
|
||||||
|
|
||||||
|
if bcx.unreachable.get() {
|
||||||
|
return bcx;
|
||||||
|
}
|
||||||
|
|
||||||
// Extract the file/line from the span
|
// Extract the file/line from the span
|
||||||
let loc = bcx.sess().codemap().lookup_char_pos(call_info.span.lo);
|
let loc = bcx.sess().codemap().lookup_char_pos(call_info.span.lo);
|
||||||
let filename = token::intern_and_get_ident(&loc.file.name);
|
let filename = token::intern_and_get_ident(&loc.file.name);
|
||||||
|
@ -26,6 +26,22 @@ fn after_return() {
|
|||||||
(a, ref b) => {}
|
(a, ref b) => {}
|
||||||
}
|
}
|
||||||
for a in &[111i32] {}
|
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() {
|
fn after_panic() {
|
||||||
@ -36,6 +52,22 @@ fn after_panic() {
|
|||||||
(a, ref b) => {}
|
(a, ref b) => {}
|
||||||
}
|
}
|
||||||
for a in &[111i32] {}
|
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() {
|
fn after_diverging_function() {
|
||||||
@ -46,6 +78,22 @@ fn after_diverging_function() {
|
|||||||
(a, ref b) => {}
|
(a, ref b) => {}
|
||||||
}
|
}
|
||||||
for a in &[111i32] {}
|
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() {
|
fn after_break() {
|
||||||
@ -57,18 +105,50 @@ fn after_break() {
|
|||||||
(a, ref b) => {}
|
(a, ref b) => {}
|
||||||
}
|
}
|
||||||
for a in &[111i32] {}
|
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() {
|
fn after_continue() {
|
||||||
for _ in 0..10i32 {
|
for _ in 0..10i32 {
|
||||||
break;
|
continue;
|
||||||
let x = "0";
|
let x = "0";
|
||||||
let (ref y,z) = (1i32, 2u32);
|
let (ref y,z) = (1i32, 2u32);
|
||||||
match (20i32, 'c') {
|
match (20i32, 'c') {
|
||||||
(a, ref b) => {}
|
(a, ref b) => {}
|
||||||
}
|
}
|
||||||
for a in &[111i32] {}
|
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() -> ! {
|
fn diverge() -> ! {
|
||||||
panic!();
|
panic!();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn some_predicate() -> bool { true || false }
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user