diff mbox

[C/C++] Fix bogus warning with -Wswitch-unreachable (PR c/71249)

Message ID 20160524114115.GV1611@redhat.com
State New
Headers show

Commit Message

Marek Polacek May 24, 2016, 11:41 a.m. UTC
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.


	Marek

Comments

Jason Merrill May 24, 2016, 3:50 p.m. UTC | #1
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 mbox

Patch

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;
+}