diff options
author | Mark Mitchell <mark@codesourcery.com> | 2006-10-17 22:43:37 +0000 |
---|---|---|
committer | Mark Mitchell <mmitchel@gcc.gnu.org> | 2006-10-17 22:43:37 +0000 |
commit | d19b84e94b3a0b93c02128f4a9f34281a70ebf41 (patch) | |
tree | d259806834b4f4ee036d1af0e724187d570c357b | |
parent | c7b0e0273ea01ccc3a8b8065944f89b6d619e787 (diff) | |
download | gcc-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/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/cp/parser.c | 75 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/parse/enum3.C | 5 |
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" } |