[gcc(refs/vendors/ARM/heads/arm-perf-staging)] c++: Fix tentative parsing of enum-specifier [PR96077]

Tamar Christina tnfchris@gcc.gnu.org
Fri Jul 17 15:40:43 GMT 2020


https://gcc.gnu.org/g:30529e2faa482bc749c65a490763dbc2ccaf63ac

commit 30529e2faa482bc749c65a490763dbc2ccaf63ac
Author: Marek Polacek <polacek@redhat.com>
Date:   Thu Jul 9 20:44:05 2020 -0400

    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:
---
 gcc/cp/parser.c                     | 7 ++++++-
 gcc/testsuite/g++.dg/parse/enum14.C | 7 +++++++
 2 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 45ad2c05288..6337f0d240a 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 00000000000..be09cca5211
--- /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" }
+}


More information about the Gcc-cvs mailing list