mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-01-10 16:55:21 +08:00
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:
parent
aa2d0bc31c
commit
515e6a84cd
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
|
16
gcc/testsuite/g++.dg/parse/error25.C
Normal file
16
gcc/testsuite/g++.dg/parse/error25.C
Normal 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" }
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user