From: Mark Mitchell Date: Tue, 17 Oct 2006 22:43:37 +0000 (+0000) Subject: re PR c++/28261 (ICE with enum in constructor definition) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=d19b84e94b3a0b93c02128f4a9f34281a70ebf41;p=gcc.git 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 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index b759ba42580..b8687ba0b17 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,13 @@ +2006-10-17 Mark Mitchell + + 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 PR c++/29039 diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index dfcbe733316..82f87f6a636 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 57ec350bd85..19f897b4a91 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2006-10-17 Mark Mitchell + + PR c++/28261 + * g++.dg/parse/enum3.C: New test. + 2006-10-17 Mark Mitchell 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 index 00000000000..11c532c6e91 --- /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" }