On Tue, Nov 19, 2019 at 05:34:45PM -0500, Jason Merrill wrote:
> On 11/18/19 7:04 PM, Marek Polacek wrote:
> > The newly added diagnostic causes an ICE because the new grokdeclarator call
> > returned error_mark_node and DECL_SOURCE_LOCATION crashes on that.  So don't
> > attempt to print the new diagnostic if we've encountered something not
> > resembling a bit-field.
> > 
> > Bootstrapped/regtested on x86_64-linux, ok for trunk?
> > 
> > 2019-11-18  Marek Polacek  <pola...@redhat.com>
> > 
> >     PR c++/92450 - ICE with invalid nested name specifier.
> >     * parser.c (cp_parser_member_declaration): Bail out for invalid code.
> > 
> >     * g++.dg/parse/crash71.C: New test.
> > 
> > diff --git gcc/cp/parser.c gcc/cp/parser.c
> > index c473e7fd92f..caed6946977 100644
> > --- gcc/cp/parser.c
> > +++ gcc/cp/parser.c
> > @@ -25052,6 +25052,9 @@ cp_parser_member_declaration (cp_parser* parser)
> >               tree d = grokdeclarator (declarator, &decl_specifiers,
> >                                        BITFIELD, /*initialized=*/false,
> >                                        &attributes);
> > +             /* Hopelessly invalid code, give up.  */
> > +             if (error_operand_p (d))
> > +               goto out;
> >               error_at (DECL_SOURCE_LOCATION (d),
> >                         "bit-field %qD has non-integral type %qT",
> >                         d, TREE_TYPE (d));
> 
> Don't we still want the rest of the error-recovery code there, i.e. skipping
> to the end of the statement?

Sure, that works too, we just emit fewer diagnostics.  But maybe that's not
that interesting at this point, because we've already given an error.

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

2019-11-20  Marek Polacek  <pola...@redhat.com>

        PR c++/92450 - ICE with invalid nested name specifier.
        * parser.c (cp_parser_member_declaration): Don't attempt to print
        erroneous bit-field diagnostic if grokdeclarator returns
        error_mark_node.

        * g++.dg/parse/crash71.C: New test.

diff --git gcc/cp/parser.c gcc/cp/parser.c
index c473e7fd92f..ad35945f954 100644
--- gcc/cp/parser.c
+++ gcc/cp/parser.c
@@ -25052,9 +25052,10 @@ cp_parser_member_declaration (cp_parser* parser)
                  tree d = grokdeclarator (declarator, &decl_specifiers,
                                           BITFIELD, /*initialized=*/false,
                                           &attributes);
-                 error_at (DECL_SOURCE_LOCATION (d),
-                           "bit-field %qD has non-integral type %qT",
-                           d, TREE_TYPE (d));
+                 if (!error_operand_p (d))
+                   error_at (DECL_SOURCE_LOCATION (d),
+                             "bit-field %qD has non-integral type %qT",
+                             d, TREE_TYPE (d));
                  cp_parser_skip_to_end_of_statement (parser);
                  /* Avoid "extra ;" pedwarns.  */
                  if (cp_lexer_next_token_is (parser->lexer,
diff --git gcc/testsuite/g++.dg/parse/crash71.C 
gcc/testsuite/g++.dg/parse/crash71.C
new file mode 100644
index 00000000000..13f484801fe
--- /dev/null
+++ gcc/testsuite/g++.dg/parse/crash71.C
@@ -0,0 +1,11 @@
+// PR c++/92450 - ICE with invalid nested name specifier.
+
+typedef int C2;
+struct B1 {
+  struct B2 {
+  };
+};
+
+struct S6g {
+  C2 : B1:B2; // { dg-error "" }
+};

Reply via email to