From: Marek Polacek Date: Fri, 10 Jul 2020 00:44:05 +0000 (-0400) Subject: c++: Fix tentative parsing of enum-specifier [PR96077] X-Git-Tag: releases/gcc-10.2.0~44 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=30529e2faa482bc749c65a490763dbc2ccaf63ac;p=thirdparty%2Fgcc.git c++: Fix tentative parsing of enum-specifier [PR96077] Here's an interesting issue: in this code a ) is missing: enum { E = (2 } e; but we compile the code anyway, and E is set to 0 in build_enumerator, which is sneaky. The problem is that cp_parser_enum_specifier parses tentatively, because when we see the enum keyword, we don't know yet if we'll find an enum-specifier, opaque-enum-declaration, or elaborated-enum-specifier. In this test when we call cp_parser_enumerator_list we're still parsing tentatively, and as a consequence, parens.require_close (parser) in cp_parser_primary_expression doesn't report any errors. But we only go on to parse the enumerator-list after we've seen a {, at which point we might as well commit -- we know we're dealing with an enum-specifier. gcc/cp/ChangeLog: PR c++/96077 * parser.c (cp_parser_enum_specifier): Commit to tentative parse after we've seen an opening brace. gcc/testsuite/ChangeLog: PR c++/96077 * g++.dg/parse/enum14.C: New test. (cherry picked from commit 4fd124a23664c712f1bb1a7e91fa23fe83d72c0b) --- diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 45ad2c05288d..6337f0d240a8 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -19355,7 +19355,12 @@ cp_parser_enum_specifier (cp_parser* parser) "ISO C++ forbids empty unnamed enum"); } else - cp_parser_enumerator_list (parser, type); + { + /* We've seen a '{' so we know we're in an enum-specifier. + Commit to any tentative parse to get syntax errors. */ + cp_parser_commit_to_tentative_parse (parser); + cp_parser_enumerator_list (parser, type); + } /* Consume the final '}'. */ braces.require_close (parser); diff --git a/gcc/testsuite/g++.dg/parse/enum14.C b/gcc/testsuite/g++.dg/parse/enum14.C new file mode 100644 index 000000000000..be09cca5211e --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/enum14.C @@ -0,0 +1,7 @@ +// PR c++/96077 + +int main () +{ + enum { E = (2 } e; // { dg-error "expected" } + enum { F = true ? 2 : (3 /* missing ")" here */ } f; // { dg-error "expected" } +}