This is the mail archive of the 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]

C++ PATCH: PR 17695

This patch fixes an ice-on-valid with -g on DWARF2 systems.

The problem here is an ordering issue.

When we see A<C>, we instantiate it, and call gen_type_die for A<C>.
That causes us to generate DIEs for all members of A<C>, including
A<C>::t.  The type of A<C>::t is C, so we now go to generate a DIE for
C.  C is not presently marked as DECL_ABSTRACT, so we do not enter it
in the decl->DIE table.  Later, we realize that B::B() is an abstract
instance, so we go ahead and mark C as DECL_ABSTRACT -- but it's too
late, we've already dealt with its DIE.  Then, we process one of the
clones of B::B(), encounter a copy of the typedef, go back to the
abstract origin of the typedef, and try to look it up -- but it's not
in the table.

In GCC 3.4, this worked because we did not actually copy the typedef
into the clone.  Therefore, there was never a second typedef pointing
back at the original typedef.  However, remap_decl has been changed to
make a copy of all declarations, even static variables and
typedefs. So, now we have a problem.

The fix is to mark the original typedef DECL_ABSTRACT so that the
DWARF 2 back end knows that other things may later point back to it.

Tested on i686-pc-linux-gnu, applied on the mainline.

Mark Mitchell
CodeSourcery, LLC

2004-10-29  Mark Mitchell  <>

	PR c++/17695
	* decl.c (grokdeclarator): Mark TYPE_DECLs as abstract when they
	appear in a constructor/destructor that will be cloned.

2004-10-29  Mark Mitchell  <>

	PR c++/17695
	* g++.dg/debug/typedef2.C: New test.

Index: cp/decl.c
RCS file: /cvs/gcc/gcc/gcc/cp/decl.c,v
retrieving revision 1.1319
diff -c -5 -p -r1.1319 decl.c
*** cp/decl.c	27 Oct 2004 02:23:10 -0000	1.1319
--- cp/decl.c	29 Oct 2004 07:12:35 -0000
*************** grokdeclarator (const cp_declarator *dec
*** 7617,7626 ****
--- 7617,7634 ----
  	  decl = build_decl (TYPE_DECL, unqualified_id, type);
  	  if (in_namespace || ctype)
  	    error ("%Jtypedef name may not be a nested-name-specifier", decl);
  	  if (!current_function_decl)
  	    DECL_CONTEXT (decl) = FROB_CONTEXT (current_namespace);
+ 	  else if (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (current_function_decl)
+ 		       (current_function_decl)))
+ 	    /* The TYPE_DECL is "abstract" because there will be
+ 	       clones of this constructor/destructor, and there will
+ 	       be copies of this TYPE_DECL generated in those
+ 	       clones.  */
+ 	    DECL_ABSTRACT (decl) = 1;
        /* If the user declares "typedef struct {...} foo" then the
  	 struct will have an anonymous name.  Fill that name in now.
  	 Nothing can refer to it, so nothing needs know about the name
Index: testsuite/g++.dg/debug/typedef2.C
RCS file: testsuite/g++.dg/debug/typedef2.C
diff -N testsuite/g++.dg/debug/typedef2.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/debug/typedef2.C	29 Oct 2004 07:12:35 -0000
*** 0 ****
--- 1,12 ----
+ // PR c++/17695
+ template<typename T> struct A
+ {
+   T t;
+   A();
+ };
+ struct B
+ {
+   B() { typedef int C; A<C> a; }
+ } b;

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