This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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" }
===================================================================



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]