Message ID | 20160524114115.GV1611@redhat.com |
---|---|
State | New |
Headers | show |
OK. Jason On Tue, May 24, 2016 at 7:41 AM, Marek Polacek <polacek@redhat.com> wrote: > Martin S. noticed that cc1plus bogusly warns on the following test. That's > because I didn't realize that GIMPLE_BINDs might be nested in C++ so we need to > look through them, and only then get the first statement in the seq. > > Bootstrapped/regtested on x86_64-linux, ok for trunk? > > 2016-05-24 Marek Polacek <polacek@redhat.com> > > PR c/71249 > * gimplify.c (gimplify_switch_expr): Look into the innermost lexical > scope. > > * c-c++-common/Wswitch-unreachable-2.c: New test. > > diff --git gcc/gimplify.c gcc/gimplify.c > index 6473544..5c5e9d6 100644 > --- gcc/gimplify.c > +++ gcc/gimplify.c > @@ -1605,8 +1605,9 @@ gimplify_switch_expr (tree *expr_p, gimple_seq *pre_p) > && switch_body_seq != NULL) > { > gimple_seq seq = switch_body_seq; > - if (gimple_code (switch_body_seq) == GIMPLE_BIND) > - seq = gimple_bind_body (as_a <gbind *> (switch_body_seq)); > + /* Look into the innermost lexical scope. */ > + while (gimple_code (seq) == GIMPLE_BIND) > + seq = gimple_bind_body (as_a <gbind *> (seq)); > gimple *stmt = gimple_seq_first_stmt (seq); > enum gimple_code code = gimple_code (stmt); > if (code != GIMPLE_LABEL && code != GIMPLE_TRY) > diff --git gcc/testsuite/c-c++-common/Wswitch-unreachable-2.c gcc/testsuite/c-c++-common/Wswitch-unreachable-2.c > index e69de29..8f57392 100644 > --- gcc/testsuite/c-c++-common/Wswitch-unreachable-2.c > +++ gcc/testsuite/c-c++-common/Wswitch-unreachable-2.c > @@ -0,0 +1,18 @@ > +/* PR c/71249 */ > +/* { dg-do compile } */ > + > +int > +f (int i) > +{ > + switch (i) > + { > + { > + int j; > + foo: > + return i; /* { dg-bogus "statement will never be executed" } */ > + }; > + case 3: > + goto foo; > + } > + return i; > +} > > Marek
diff --git gcc/gimplify.c gcc/gimplify.c index 6473544..5c5e9d6 100644 --- gcc/gimplify.c +++ gcc/gimplify.c @@ -1605,8 +1605,9 @@ gimplify_switch_expr (tree *expr_p, gimple_seq *pre_p) && switch_body_seq != NULL) { gimple_seq seq = switch_body_seq; - if (gimple_code (switch_body_seq) == GIMPLE_BIND) - seq = gimple_bind_body (as_a <gbind *> (switch_body_seq)); + /* Look into the innermost lexical scope. */ + while (gimple_code (seq) == GIMPLE_BIND) + seq = gimple_bind_body (as_a <gbind *> (seq)); gimple *stmt = gimple_seq_first_stmt (seq); enum gimple_code code = gimple_code (stmt); if (code != GIMPLE_LABEL && code != GIMPLE_TRY) diff --git gcc/testsuite/c-c++-common/Wswitch-unreachable-2.c gcc/testsuite/c-c++-common/Wswitch-unreachable-2.c index e69de29..8f57392 100644 --- gcc/testsuite/c-c++-common/Wswitch-unreachable-2.c +++ gcc/testsuite/c-c++-common/Wswitch-unreachable-2.c @@ -0,0 +1,18 @@ +/* PR c/71249 */ +/* { dg-do compile } */ + +int +f (int i) +{ + switch (i) + { + { + int j; + foo: + return i; /* { dg-bogus "statement will never be executed" } */ + }; + case 3: + goto foo; + } + return i; +}