re PR c++/38021 (C++ hang for new keywords)
authorJakub Jelinek <jakub@redhat.com>
Mon, 10 Nov 2008 13:41:37 +0000 (14:41 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Mon, 10 Nov 2008 13:41:37 +0000 (14:41 +0100)
PR c++/38021
* parser.c (cp_parser_enum_specifier): After parsing :,
parse definitely.  Don't return early if type specifier
is erroneous.

* g++.dg/cpp0x/enum1.C: New test.

From-SVN: r141739

gcc/cp/ChangeLog
gcc/cp/parser.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp0x/enum1.C [new file with mode: 0644]

index ec7a1aa..81941e2 100644 (file)
@@ -1,3 +1,10 @@
+2008-11-10  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c++/38021
+       * parser.c (cp_parser_enum_specifier): After parsing :,
+       parse definitely.  Don't return early if type specifier
+       is erroneous.
+
 2008-11-06  David Edelsohn  <edelsohn@gnu.org>
 
        PR target/26397
index 40f2a3a..c819082 100644 (file)
@@ -11780,6 +11780,7 @@ cp_parser_enum_specifier (cp_parser* parser)
   tree type;
   tree attributes;
   bool scoped_enum_p = false;
+  bool has_underlying_type = false;
   tree underlying_type = NULL_TREE;
 
   /* Parse tentatively so that we can back up if we don't find a
@@ -11805,7 +11806,7 @@ cp_parser_enum_specifier (cp_parser* parser)
 
       scoped_enum_p = true;
     }
-      
+
   attributes = cp_parser_attributes_opt (parser);
 
   if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
@@ -11818,18 +11819,22 @@ cp_parser_enum_specifier (cp_parser* parser)
     {
       cp_decl_specifier_seq type_specifiers;
 
+      /* At this point this is surely not elaborated type specifier.  */
+      if (!cp_parser_parse_definitely (parser))
+       return NULL_TREE;
+
       if (cxx_dialect == cxx98)
         maybe_warn_cpp0x ("scoped enums");
 
       /* Consume the `:'.  */
       cp_lexer_consume_token (parser->lexer);
 
+      has_underlying_type = true;
+
       /* Parse the type-specifier-seq.  */
       cp_parser_type_specifier_seq (parser, /*is_condition=*/false,
                                     &type_specifiers);
-      if (type_specifiers.type == error_mark_node)
-        return error_mark_node;
-     
+
       /* If that didn't work, stop.  */
       if (type_specifiers.type != error_mark_node)
         {
@@ -11838,15 +11843,17 @@ cp_parser_enum_specifier (cp_parser* parser)
           if (underlying_type == error_mark_node)
             underlying_type = NULL_TREE;
         }
-      else
-        cp_parser_error (parser, "expected underlying type of enumeration");
     }
 
   /* Look for the `{' but don't consume it yet.  */
   if (!cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
-    cp_parser_simulate_error (parser);
+    {
+      cp_parser_error (parser, "expected %<{%>");
+      if (has_underlying_type)
+       return NULL_TREE;
+    }
 
-  if (!cp_parser_parse_definitely (parser))
+  if (!has_underlying_type && !cp_parser_parse_definitely (parser))
     return NULL_TREE;
 
   /* Issue an error message if type-definitions are forbidden here.  */
index b341ead..412c77a 100644 (file)
@@ -1,3 +1,8 @@
+2008-11-10  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c++/38021
+       * g++.dg/cpp0x/enum1.C: New test.
+
 2008-11-02  Ralph Loader  <suckfish@ihug.co.nz>
 
        PR middle-end/37807
diff --git a/gcc/testsuite/g++.dg/cpp0x/enum1.C b/gcc/testsuite/g++.dg/cpp0x/enum1.C
new file mode 100644 (file)
index 0000000..af691f0
--- /dev/null
@@ -0,0 +1,6 @@
+// PR c++/38021
+// { dg-do compile }
+// { dg-options "-std=gnu++0x" }
+
+enum : { };    // { dg-error "expected type-specifier" }
+enum : 3 { };  // { dg-error "expected" }