diff options
author | Giovanni Bajo <giovannibajo@gcc.gnu.org> | 2005-02-03 10:26:22 +0000 |
---|---|---|
committer | Giovanni Bajo <giovannibajo@gcc.gnu.org> | 2005-02-03 10:26:22 +0000 |
commit | 515e6a84cd464581711a5aa5fe51342a57ff2095 (patch) | |
tree | 983d0094d83cbea096c2fd0c40e4d3de7dd54f48 /gcc | |
parent | aa2d0bc31c2dac0ecde72d92d7d419be5a8f21b3 (diff) | |
download | gcc-515e6a84cd464581711a5aa5fe51342a57ff2095.zip gcc-515e6a84cd464581711a5aa5fe51342a57ff2095.tar.gz gcc-515e6a84cd464581711a5aa5fe51342a57ff2095.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/cp/decl2.c | 57 | ||||
-rw-r--r-- | gcc/cp/parser.c | 17 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/parse/error25.C | 16 |
5 files changed, 46 insertions, 58 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 230e710..32e6645 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -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 diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 012ec59..0a74ed7 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -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) diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index e89fd85..82d665e 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -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; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 3820b90..d983553 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -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. diff --git a/gcc/testsuite/g++.dg/parse/error25.C b/gcc/testsuite/g++.dg/parse/error25.C new file mode 100644 index 0000000..a726a17 --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/error25.C @@ -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" } +}; + + |