This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[patch] Fix PR c++/20499: ICE on duplicate class definition
- From: Volker Reichelt <reichelt at igpm dot rwth-aachen dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Wed, 16 Mar 2005 18:25:43 +0100 (CET)
- Subject: [patch] Fix PR c++/20499: ICE on duplicate class definition
The following invalid code snippet causes an ICE on the 4.0 branch and
mainline:
==================
struct A
{
struct B {};
};
struct A::B {};
==================
The error message is:
bug.cc:6: error: redefinition of 'struct A::B'
bug.cc:3: error: previous definition of 'struct A::B'
bug.cc:6: internal compiler error: tree check: expected class 'type', have 'exceptional' (error_mark) in cp_parser_class_specifier, at cp/parser.c:12407
Please submit a full bug report, [etc.]
(Btw, this is the same problem as g++.dg/parse/error16.C.
Why the testsuite doesn't trigger is discussed in
http://gcc.gnu.org/ml/gcc/2005-02/msg00953.html )
The regression was probably caused by Mark's patch for PR c++/20152:
2005-02-22 Mark Mitchell <mark@codesourcery.com>
PR c++/20152
* parser.c (cp_parser_class_head): Check for redefintions here.
* semantics.c (begin_class_definition): Not here.
The problem is the interaction between cp_parser_class_head and its
only caller cp_parser_class_specifier. The comment above c_p_c_h says:
Returns error_mark_node if this is not a class-head.
Returns NULL_TREE if the class-head is syntactically valid, but
semantically invalid in a way that means we should skip the entire
body of the class.
The calling function c_p_c_s only checks whether NULL_TREE was returned.
For the redefinition in the code above, c_p_c_h returns error_mark_node
(in contrast to the comment above), which leads to hiccups in c_p_c_h
later.
The IMHO right fix is to return a NULL_TREE instead (conforming to the
comment) which is implemented in the following patch. The additional
jump is required to bypass xref_basetypes which crashes with a NULL_TREE
as first argument.
The patch also modifies g++.dg/parse/error16.C so that it cannot fall
through the cracks again (until a better solution for the testsuite is
implemented).
Bootstrapped and regtested.
Ok for 4.0 branch and mainline?
A question remains, though: What about the other code paths where c_p_c_h
returns an error_mark_node? Will they cause ICEs, too? Or are they safe
(or just never taken)?
Regards,
Volker
2005-03-16 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
* parser.c (cp_parser_class_head): Return NULL_TREE when
encountering a redefinition.
===================================================================
--- gcc/gcc/cp/parser.c 24 Feb 2005 21:55:15 -0000 1.319
+++ gcc/gcc/cp/parser.c 10 Mar 2005 01:40:38 -0000
@@ -12848,7 +12848,8 @@ cp_parser_class_head (cp_parser* parser,
{
error ("redefinition of %q#T", type);
cp_error_at ("previous definition of %q#T", type);
- type = error_mark_node;
+ type = NULL_TREE;
+ goto done;
}
/* We will have entered the scope containing the class; the names of
===================================================================
2005-03-16 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
* g++.dg/parse/error16.C: Tweak error markers.
===================================================================
--- gcc/gcc/testsuite/g++.dg/parse/error16.C 11 Aug 2004 22:13:32 -0000 1.1
+++ gcc/gcc/testsuite/g++.dg/parse/error16.C 10 Mar 2005 01:44:29 -0000
@@ -2,7 +2,7 @@
struct A
{
- struct B {}; // { dg-error "" }
+ struct B {}; // { dg-error "previous" }
};
-struct A::B{}; // { dg-error "" }
+struct A::B{}; // { dg-error "redefinition" }
===================================================================