This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [C++ PATCH] Fix cp_parser_enum_specifier (PR c++/38021)


On Wed, Nov 05, 2008 at 07:46:08AM -0800, Mark Mitchell wrote:
> But, when we see the colon, or the C++0x class/struct keyword, we can
> commit.  "enum struct X" is only part of a C++0x enum-specifier, and so
> is "enum X : ".
> 
> So, I think the function should be reworked in that way.

Like this?

Note that we can't commit if we see enum class or enum struct, both
are valid for elaborated type specifier.

2008-11-06  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.

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

--- gcc/cp/parser.c.jj	2008-10-29 18:49:05.000000000 +0100
+++ gcc/cp/parser.c	2008-11-06 11:08:14.000000000 +0100
@@ -11780,6 +11780,7 @@ cp_parser_enum_specifier (cp_parser* par
   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* par
 
       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* par
     {
       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* par
           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.  */
--- gcc/testsuite/g++.dg/cpp0x/enum1.C.jj	2008-11-05 15:30:23.000000000 +0100
+++ gcc/testsuite/g++.dg/cpp0x/enum1.C	2008-11-06 11:05:51.000000000 +0100
@@ -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" }

	Jakub


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]