]> gcc.gnu.org Git - gcc.git/commitdiff
re PR c++/28261 (ICE with enum in constructor definition)
authorMark Mitchell <mark@codesourcery.com>
Tue, 17 Oct 2006 22:43:37 +0000 (22:43 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Tue, 17 Oct 2006 22:43:37 +0000 (22:43 +0000)
PR c++/28261
* parser.c (cp_lexer_next_token_is_decl_specifier_keyword): New
function.
(cp_parser_constructor_declarator_p): Use it.
(cp_parser_check_type_definition): Return a value indicating
whether or not the definition is valid.
(cp_parser_enum_specifier): Skip invalid enum definitions.
PR c++/28261
* g++.dg/parse/enum3.C: New test.

From-SVN: r117835

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

index b759ba42580f5acb402b4b6b6e848b11ee88fc1f..b8687ba0b17c5886bcd3bd580e340e10b3f55f5c 100644 (file)
@@ -1,3 +1,13 @@
+2006-10-17  Mark Mitchell  <mark@codesourcery.com>
+
+       PR c++/28261
+       * parser.c (cp_lexer_next_token_is_decl_specifier_keyword): New
+       function.
+       (cp_parser_constructor_declarator_p): Use it.
+       (cp_parser_check_type_definition): Return a value indicating
+       whether or not the definition is valid.
+       (cp_parser_enum_specifier): Skip invalid enum definitions.
+
 2006-10-17  Mark Mitchell  <mark@codesourcery.com>
 
        PR c++/29039
index dfcbe733316e8413821845b4e6f2b0ef339ce5da..82f87f6a636408e4a5272d7b6c8f523eeeb677e5 100644 (file)
@@ -505,6 +505,49 @@ cp_lexer_next_token_is_keyword (cp_lexer* lexer, enum rid keyword)
   return cp_lexer_peek_token (lexer)->keyword == keyword;
 }
 
+static bool
+cp_lexer_next_token_is_decl_specifier_keyword (cp_lexer *lexer)
+{
+  cp_token *token;
+
+  token = cp_lexer_peek_token (lexer);
+  switch (token->keyword) 
+    {
+      /* Storage classes.  */
+    case RID_AUTO:
+    case RID_REGISTER:
+    case RID_STATIC:
+    case RID_EXTERN:
+    case RID_MUTABLE:
+    case RID_THREAD:
+      /* Elaborated type specifiers.  */
+    case RID_ENUM:
+    case RID_CLASS:
+    case RID_STRUCT:
+    case RID_UNION:
+    case RID_TYPENAME:
+      /* Simple type specifiers.  */
+    case RID_CHAR:
+    case RID_WCHAR:
+    case RID_BOOL:
+    case RID_SHORT:
+    case RID_INT:
+    case RID_LONG:
+    case RID_SIGNED:
+    case RID_UNSIGNED:
+    case RID_FLOAT:
+    case RID_DOUBLE:
+    case RID_VOID:
+      /* GNU extensions.  */ 
+    case RID_ATTRIBUTE:
+    case RID_TYPEOF:
+      return true;
+
+    default:
+      return false;
+    }
+}
+
 /* Return a pointer to the Nth token in the token stream.  If N is 1,
    then this is precisely equivalent to cp_lexer_peek_token (except
    that it is not inline).  One would like to disallow that case, but
@@ -1815,7 +1858,7 @@ static void cp_parser_name_lookup_error
   (cp_parser *, tree, tree, const char *);
 static bool cp_parser_simulate_error
   (cp_parser *);
-static void cp_parser_check_type_definition
+static bool cp_parser_check_type_definition
   (cp_parser *);
 static void cp_parser_check_for_definition_in_return_type
   (cp_declarator *, tree);
@@ -2008,14 +2051,18 @@ cp_parser_check_decl_spec (cp_decl_specifier_seq *decl_specs)
    definitions are forbidden at this point, an error message is
    issued.  */
 
-static void
+static bool
 cp_parser_check_type_definition (cp_parser* parser)
 {
   /* If types are forbidden here, issue a message.  */
   if (parser->type_definition_forbidden_message)
-    /* Use `%s' to print the string in case there are any escape
-       characters in the message.  */
-    error ("%s", parser->type_definition_forbidden_message);
+    {
+      /* Use `%s' to print the string in case there are any escape
+        characters in the message.  */
+      error ("%s", parser->type_definition_forbidden_message);
+      return false;
+    }
+  return true;
 }
 
 /* This function is called when the DECLARATOR is processed.  The TYPE
@@ -10335,13 +10382,14 @@ cp_parser_enum_specifier (cp_parser* parser)
     return NULL_TREE;
 
   /* Issue an error message if type-definitions are forbidden here.  */
-  cp_parser_check_type_definition (parser);
-
-  /* Create the new type.  We do this before consuming the opening brace
-     so the enum will be recorded as being on the line of its tag (or the
-     'enum' keyword, if there is no tag).  */
-  type = start_enum (identifier);
-
+  if (!cp_parser_check_type_definition (parser))
+    type = error_mark_node;
+  else
+    /* Create the new type.  We do this before consuming the opening
+       brace so the enum will be recorded as being on the line of its
+       tag (or the 'enum' keyword, if there is no tag).  */
+    type = start_enum (identifier);
+  
   /* Consume the opening brace.  */
   cp_lexer_consume_token (parser->lexer);
 
@@ -15329,8 +15377,7 @@ cp_parser_constructor_declarator_p (cp_parser *parser, bool friend_p)
          /* A parameter declaration begins with a decl-specifier,
             which is either the "attribute" keyword, a storage class
             specifier, or (usually) a type-specifier.  */
-         && !cp_lexer_next_token_is_keyword (parser->lexer, RID_ATTRIBUTE)
-         && !cp_parser_storage_class_specifier_opt (parser))
+         && !cp_lexer_next_token_is_decl_specifier_keyword (parser->lexer))
        {
          tree type;
          tree pushed_scope = NULL_TREE;
index 57ec350bd8500dcec5575b78545db3099ed467a2..19f897b4a91d1df3dc076d2b053bf4f057800899 100644 (file)
@@ -1,3 +1,8 @@
+2006-10-17  Mark Mitchell  <mark@codesourcery.com>
+
+       PR c++/28261
+       * g++.dg/parse/enum3.C: New test.
+
 2006-10-17  Mark Mitchell  <mark@codesourcery.com>
 
        PR c++/29039
diff --git a/gcc/testsuite/g++.dg/parse/enum3.C b/gcc/testsuite/g++.dg/parse/enum3.C
new file mode 100644 (file)
index 0000000..11c532c
--- /dev/null
@@ -0,0 +1,5 @@
+// PR c++/28261
+
+struct A {}; // { dg-error "A" }
+
+A::A (enum { e }) {} // { dg-error "defined|match" }
This page took 0.085358 seconds and 5 git commands to generate.