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:
parent
c7b0e0273e
commit
d19b84e94b
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
// PR c++/28261
|
||||
|
||||
struct A {}; // { dg-error "A" }
|
||||
|
||||
A::A (enum { e }) {} // { dg-error "defined|match" }
|
Loading…
Reference in New Issue