aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorGiovanni Bajo <giovannibajo@gcc.gnu.org>2005-02-03 10:26:22 +0000
committerGiovanni Bajo <giovannibajo@gcc.gnu.org>2005-02-03 10:26:22 +0000
commit515e6a84cd464581711a5aa5fe51342a57ff2095 (patch)
tree983d0094d83cbea096c2fd0c40e4d3de7dd54f48 /gcc
parentaa2d0bc31c2dac0ecde72d92d7d419be5a8f21b3 (diff)
downloadgcc-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/ChangeLog9
-rw-r--r--gcc/cp/decl2.c57
-rw-r--r--gcc/cp/parser.c17
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/parse/error25.C16
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" }
+};
+
+