On Fri, Feb 17, 2017 at 2:53 PM, Marek Polacek <pola...@redhat.com> wrote: > 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?
I think I prefer Index: gcc/gimplify.c =================================================================== --- gcc/gimplify.c (revision 245594) +++ gcc/gimplify.c (working copy) @@ -11977,7 +11977,8 @@ gimplify_expr (tree *expr_p, gimple_seq { /* We aren't looking for a value, and we don't have a valid statement. If it doesn't have side-effects, throw it away. */ - if (!TREE_SIDE_EFFECTS (*expr_p)) + if (TREE_CODE (*expr_p) == LABEL_DECL + || !TREE_SIDE_EFFECTS (*expr_p)) *expr_p = NULL; else if (!TREE_THIS_VOLATILE (*expr_p)) { (with a comment). Ideally we'd have TREE_NOT_CHECK (NON_TYPE_CHEC (NODE), LABEL_DECL) on TREE_SIDE_EFFECTS but that may have unwanted fallout at this point. Ok with the above change. Thanks, RIchard. > 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