Commit d19b84e9 by Mark Mitchell Committed by Mark Mitchell

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
parent c7b0e027
2006-10-17 Mark Mitchell <mark@codesourcery.com> 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 PR c++/29039
* typeck2.c (build_functional_cast): Don't zero-initialize * typeck2.c (build_functional_cast): Don't zero-initialize
non-PODs; instead, call their constructors. non-PODs; instead, call their constructors.
......
...@@ -505,6 +505,49 @@ cp_lexer_next_token_is_keyword (cp_lexer* lexer, enum rid keyword) ...@@ -505,6 +505,49 @@ cp_lexer_next_token_is_keyword (cp_lexer* lexer, enum rid keyword)
return cp_lexer_peek_token (lexer)->keyword == 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, /* 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 then this is precisely equivalent to cp_lexer_peek_token (except
that it is not inline). One would like to disallow that case, but that it is not inline). One would like to disallow that case, but
...@@ -1815,7 +1858,7 @@ static void cp_parser_name_lookup_error ...@@ -1815,7 +1858,7 @@ static void cp_parser_name_lookup_error
(cp_parser *, tree, tree, const char *); (cp_parser *, tree, tree, const char *);
static bool cp_parser_simulate_error static bool cp_parser_simulate_error
(cp_parser *); (cp_parser *);
static void cp_parser_check_type_definition static bool cp_parser_check_type_definition
(cp_parser *); (cp_parser *);
static void cp_parser_check_for_definition_in_return_type static void cp_parser_check_for_definition_in_return_type
(cp_declarator *, tree); (cp_declarator *, tree);
...@@ -2008,14 +2051,18 @@ cp_parser_check_decl_spec (cp_decl_specifier_seq *decl_specs) ...@@ -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 definitions are forbidden at this point, an error message is
issued. */ issued. */
static void static bool
cp_parser_check_type_definition (cp_parser* parser) cp_parser_check_type_definition (cp_parser* parser)
{ {
/* If types are forbidden here, issue a message. */ /* If types are forbidden here, issue a message. */
if (parser->type_definition_forbidden_message) if (parser->type_definition_forbidden_message)
{
/* Use `%s' to print the string in case there are any escape /* Use `%s' to print the string in case there are any escape
characters in the message. */ characters in the message. */
error ("%s", parser->type_definition_forbidden_message); error ("%s", parser->type_definition_forbidden_message);
return false;
}
return true;
} }
/* This function is called when the DECLARATOR is processed. The TYPE /* This function is called when the DECLARATOR is processed. The TYPE
...@@ -10335,11 +10382,12 @@ cp_parser_enum_specifier (cp_parser* parser) ...@@ -10335,11 +10382,12 @@ cp_parser_enum_specifier (cp_parser* parser)
return NULL_TREE; return NULL_TREE;
/* Issue an error message if type-definitions are forbidden here. */ /* Issue an error message if type-definitions are forbidden here. */
cp_parser_check_type_definition (parser); if (!cp_parser_check_type_definition (parser))
type = error_mark_node;
/* Create the new type. We do this before consuming the opening brace else
so the enum will be recorded as being on the line of its tag (or the /* Create the new type. We do this before consuming the opening
'enum' keyword, if there is no tag). */ 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); type = start_enum (identifier);
/* Consume the opening brace. */ /* Consume the opening brace. */
...@@ -15329,8 +15377,7 @@ cp_parser_constructor_declarator_p (cp_parser *parser, bool friend_p) ...@@ -15329,8 +15377,7 @@ cp_parser_constructor_declarator_p (cp_parser *parser, bool friend_p)
/* A parameter declaration begins with a decl-specifier, /* A parameter declaration begins with a decl-specifier,
which is either the "attribute" keyword, a storage class which is either the "attribute" keyword, a storage class
specifier, or (usually) a type-specifier. */ specifier, or (usually) a type-specifier. */
&& !cp_lexer_next_token_is_keyword (parser->lexer, RID_ATTRIBUTE) && !cp_lexer_next_token_is_decl_specifier_keyword (parser->lexer))
&& !cp_parser_storage_class_specifier_opt (parser))
{ {
tree type; tree type;
tree pushed_scope = NULL_TREE; tree pushed_scope = NULL_TREE;
......
2006-10-17 Mark Mitchell <mark@codesourcery.com> 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 PR c++/29039
* g++.dg/init/ctor8.C: New test. * g++.dg/init/ctor8.C: New test.
// PR c++/28261
struct A {}; // { dg-error "A" }
A::A (enum { e }) {} // { dg-error "defined|match" }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment