re PR c++/17401 (ICE with invalid pure specifier)

PR c++/17401
	* parser.c (cp_parser_pure_specifier): Emit a specific error
	message with an invalid pure specifier.
	* decl2.c (grok_function_init): Remove.
	(grokfield): An initializer for a method is a always a pure
	specifier.

	PR c++/17401
	* g++.dg/parse/error25.C: New test.

From-SVN: r94656
This commit is contained in:
Giovanni Bajo 2005-02-03 10:26:22 +00:00
parent aa2d0bc31c
commit 515e6a84cd
5 changed files with 46 additions and 58 deletions

View File

@ -1,3 +1,12 @@
2005-02-03 Giovanni Bajo <giovannibajo@gcc.gnu.org>
PR c++/17401
* parser.c (cp_parser_pure_specifier): Emit a specific error
message with an invalid pure specifier.
* decl2.c (grok_function_init): Remove.
(grokfield): An initializer for a method is a always a pure
specifier.
2005-02-02 Matt Austern <austern@apple.com>
PR c++/19628

View File

@ -64,7 +64,6 @@ typedef struct priority_info_s {
} *priority_info;
static void mark_vtable_entries (tree);
static void grok_function_init (tree, tree);
static bool maybe_emit_vtables (tree);
static tree build_anon_union_vars (tree);
static bool acceptable_java_type (tree);
@ -897,8 +896,11 @@ grokfield (const cp_declarator *declarator,
{
if (TREE_CODE (value) == FUNCTION_DECL)
{
grok_function_init (value, init);
init = NULL_TREE;
/* Initializers for functions are rejected early in the parser.
If we get here, it must be a pure specifier for a method. */
gcc_assert (TREE_CODE (TREE_TYPE (value)) == METHOD_TYPE);
gcc_assert (error_operand_p (init) || integer_zerop (init));
DECL_PURE_VIRTUAL_P (value) = 1;
}
else if (pedantic && TREE_CODE (value) != VAR_DECL)
/* Already complained in grokdeclarator. */
@ -1045,55 +1047,6 @@ grokbitfield (const cp_declarator *declarator,
return value;
}
/* When a function is declared with an initializer,
do the right thing. Currently, there are two possibilities:
class B
{
public:
// initialization possibility #1.
virtual void f () = 0;
int g ();
};
class D1 : B
{
public:
int d1;
// error, no f ();
};
class D2 : B
{
public:
int d2;
void f ();
};
class D3 : B
{
public:
int d3;
// initialization possibility #2
void f () = B::f;
};
*/
static void
grok_function_init (tree decl, tree init)
{
/* An initializer for a function tells how this function should
be inherited. */
tree type = TREE_TYPE (decl);
if (TREE_CODE (type) == FUNCTION_TYPE)
error ("initializer specified for non-member function %qD", decl);
else if (integer_zerop (init))
DECL_PURE_VIRTUAL_P (decl) = 1;
else
error ("invalid initializer for virtual method %qD", decl);
}
void
cplus_decl_attributes (tree *decl, tree attributes, int flags)

View File

@ -13332,13 +13332,18 @@ cp_parser_pure_specifier (cp_parser* parser)
if (!cp_parser_require (parser, CPP_EQ, "`='"))
return error_mark_node;
/* Look for the `0' token. */
token = cp_parser_require (parser, CPP_NUMBER, "`0'");
/* Unfortunately, this will accept `0L' and `0x00' as well. We need
to get information from the lexer about how the number was
spelled in order to fix this problem. */
if (!token || !integer_zerop (token->value))
return error_mark_node;
token = cp_lexer_consume_token (parser->lexer);
if (token->type != CPP_NUMBER || !integer_zerop (token->value))
{
cp_parser_error (parser,
"invalid pure specifier (only `= 0' is allowed)");
cp_parser_skip_to_end_of_statement (parser);
return error_mark_node;
}
/* FIXME: Unfortunately, this will accept `0L' and `0x00' as well.
We need to get information from the lexer about how the number
was spelled in order to fix this problem. */
return integer_zero_node;
}

View File

@ -1,3 +1,8 @@
2005-02-03 Giovanni Bajo <giovannibajo@gcc.gnu.org>
PR c++/17401
* g++.dg/parse/error25.C: New test.
2005-02-03 Alexandre Oliva <aoliva@redhat.com>
* gcc.c-torture/execute/20050203-1.c: New.

View File

@ -0,0 +1,16 @@
// { dg-do compile }
// Origin: Steven Bosscher <steven at gcc dot gnu dot org>
// PR c++/17401: ICE with invalid pure specifier
// NOTE: This also tests QoI of diagnostic for invalid pure specifiers.
// Please do *not* relax the dg-error tests.
class foo
{
virtual void bar1 () = 0;
virtual void bar2 () = __null; // { dg-error "invalid pure specifier" }
virtual void bar3 () = 4; // { dg-error "invalid pure specifier" }
virtual void bar4 () = A::f; // { dg-error "invalid pure specifier" }
};