We are crashing with a label as a value without accompanying goto.
The problem is that TREE_SIDE_EFFECTS and FORCED_LABEL use the same
->base.side_effects_flag, so gimplify_expr is confused.  We don't
ICE with 'goto *&&L;' becase then we take this path:
11406         case GOTO_EXPR:
11407           /* If the target is not LABEL, then it is a computed jump
11408              and the target needs to be gimplified.  */
11409           if (TREE_CODE (GOTO_DESTINATION (*expr_p)) != LABEL_DECL)
11410             {
11411               ret = gimplify_expr (&GOTO_DESTINATION (*expr_p), pre_p,
11412                                    NULL, is_gimple_val, fb_rvalue);
and because of that fb_rvalue we won't go to the switch where the ICE
occured.  Because '*&&L;' on its own is useless, I think we can simply
discard it, which is what the following does.

Bootstrapped/regtested on x86_64-linux, ok for trunk and 6?

2017-02-17  Marek Polacek  <pola...@redhat.com>

        PR middle-end/79537
        * gimplify.c (gimplify_expr): Handle unused *&&L;.

        * gcc.dg/comp-goto-4.c: New.

diff --git gcc/gimplify.c gcc/gimplify.c
index 1b9c8d2..5524357 100644
--- gcc/gimplify.c
+++ gcc/gimplify.c
@@ -12003,6 +12003,11 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, 
gimple_seq *post_p,
                             gimple_test_f, fallback);
              break;
 
+           case LABEL_DECL:
+             /* We can get here with code such as "*&&L;", where L is
+                a LABEL_DECL that is marked as FORCED_LABEL.  Skip it.  */
+             break;
+
            default:
               /* Anything else with side-effects must be converted to
                  a valid statement before we get here.  */
diff --git gcc/testsuite/gcc.dg/comp-goto-4.c gcc/testsuite/gcc.dg/comp-goto-4.c
index e69de29..51a6a86 100644
--- gcc/testsuite/gcc.dg/comp-goto-4.c
+++ gcc/testsuite/gcc.dg/comp-goto-4.c
@@ -0,0 +1,21 @@
+/* PR middle-end/79537 */
+/* { dg-do compile } */
+/* { dg-options "" } */
+/* { dg-require-effective-target indirect_jumps } */
+/* { dg-require-effective-target label_values } */
+
+void
+f (void)
+{
+L:
+  *&&L;
+}
+
+void
+f2 (void)
+{
+   void *p;
+L:
+   p = &&L;
+   *p; /* { dg-warning "dereferencing 'void \\*' pointer" } */
+}

        Marek

Reply via email to