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
This commit is contained in:
Mark Mitchell 2006-10-17 22:43:37 +00:00 committed by Mark Mitchell
parent c7b0e0273e
commit d19b84e94b
4 changed files with 81 additions and 14 deletions

View 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

View 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;

View 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

View File

@ -0,0 +1,5 @@
// PR c++/28261
struct A {}; // { dg-error "A" }
A::A (enum { e }) {} // { dg-error "defined|match" }