From 515e6a84cd464581711a5aa5fe51342a57ff2095 Mon Sep 17 00:00:00 2001 From: Giovanni Bajo Date: Thu, 3 Feb 2005 10:26:22 +0000 Subject: [PATCH] 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 --- gcc/cp/ChangeLog | 9 +++++ gcc/cp/decl2.c | 57 +++------------------------- gcc/cp/parser.c | 17 ++++++--- gcc/testsuite/ChangeLog | 5 +++ gcc/testsuite/g++.dg/parse/error25.C | 16 ++++++++ 5 files changed, 46 insertions(+), 58 deletions(-) create mode 100644 gcc/testsuite/g++.dg/parse/error25.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 230e710f591..32e664533d5 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,12 @@ +2005-02-03 Giovanni Bajo + + 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 PR c++/19628 diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 012ec59185e..0a74ed7f2a6 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 e89fd85c034..82d665ed810 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 3820b90d186..d983553ec5b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2005-02-03 Giovanni Bajo + + PR c++/17401 + * g++.dg/parse/error25.C: New test. + 2005-02-03 Alexandre Oliva * 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 00000000000..a726a174bb4 --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/error25.C @@ -0,0 +1,16 @@ +// { dg-do compile } +// Origin: Steven Bosscher +// 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" } +}; + + -- 2.30.2