aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>2006-10-17 22:43:37 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>2006-10-17 22:43:37 +0000
commitd19b84e94b3a0b93c02128f4a9f34281a70ebf41 (patch)
treed259806834b4f4ee036d1af0e724187d570c357b
parentc7b0e0273ea01ccc3a8b8065944f89b6d619e787 (diff)
downloadgcc-d19b84e94b3a0b93c02128f4a9f34281a70ebf41.zip
gcc-d19b84e94b3a0b93c02128f4a9f34281a70ebf41.tar.gz
gcc-d19b84e94b3a0b93c02128f4a9f34281a70ebf41.tar.bz2
re PR c++/28261 (ICE with enum in constructor definition)
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
-rw-r--r--gcc/cp/ChangeLog10
-rw-r--r--gcc/cp/parser.c75
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/parse/enum3.C5
4 files changed, 81 insertions, 14 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index b759ba4..b8687ba 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,15 @@
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
* typeck2.c (build_functional_cast): Don't zero-initialize
non-PODs; instead, call their constructors.
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index dfcbe73..82f87f6 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -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;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 57ec350..19f897b 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,10 @@
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
* g++.dg/init/ctor8.C: New test.
diff --git a/gcc/testsuite/g++.dg/parse/enum3.C b/gcc/testsuite/g++.dg/parse/enum3.C
new file mode 100644
index 0000000..11c532c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/enum3.C
@@ -0,0 +1,5 @@
+// PR c++/28261
+
+struct A {}; // { dg-error "A" }
+
+A::A (enum { e }) {} // { dg-error "defined|match" }