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 <pola...@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