C++ PATCH: Fix DWARF2 bootstrap failure

Mark Mitchell mark@codesourcery.com
Mon Apr 30 07:49:00 GMT 2001


Brad Lucier (and others) have reported seeing a crash on some DWARF2
platforms when compiling libstdc++.  I tracked this down to the
failure to set DECL_ABSTRACT_ORIGIN correctly on cloned versions of
the `this' parameter.

Tested on i686-pc-linux-gnu, with an alpha-unknown-linux-gnu cross,
and with a mips-sgi-irix6.5 native bootstrap.

Installed on the mainline and on the branch.

--
Mark Mitchell                   mark@codesourcery.com
CodeSourcery, LLC               http://www.codesourcery.com

2001-04-30  Mark Mitchell  <mark@codesourcery.com>

	* optimize.c (update_cloned_parm): New function.
	(maybe_clone_body): Use it.  Update the `this' parameter too.

Index: gcc/cp/optimize.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/optimize.c,v
retrieving revision 1.51.2.15
diff -c -p -r1.51.2.15 optimize.c
*** optimize.c	2001/04/27 12:45:26	1.51.2.15
--- optimize.c	2001/04/30 14:37:33
*************** static tree remap_decl PARAMS ((tree, in
*** 99,104 ****
--- 99,105 ----
  static void remap_block PARAMS ((tree, tree, inline_data *));
  static void copy_scope_stmt PARAMS ((tree *, int *, inline_data *));
  static tree calls_setjmp_r PARAMS ((tree *, int *, void *));
+ static void update_cloned_parm PARAMS ((tree, tree));
  
  /* The approximate number of instructions per statement.  This number
     need not be particularly accurate; it is used only to make
*************** calls_setjmp_p (fn)
*** 1009,1014 ****
--- 1010,1034 ----
  				       NULL) != NULL_TREE;
  }
  
+ /* CLONED_PARM is a copy of CLONE, generated for a cloned constructor
+    or destructor.  Update it to ensure that the source-position for
+    the cloned parameter matches that for the original, and that the
+    debugging generation code will be able to find the original PARM.  */
+ 
+ static void
+ update_cloned_parm (parm, cloned_parm)
+      tree parm;
+      tree cloned_parm;
+ {
+   DECL_ABSTRACT_ORIGIN (cloned_parm) = parm;
+   
+   /* The name may have changed from the declaration. */
+   DECL_NAME (cloned_parm) = DECL_NAME (parm);
+   DECL_SOURCE_FILE (cloned_parm) = DECL_SOURCE_FILE (parm);
+   DECL_SOURCE_LINE (cloned_parm) = DECL_SOURCE_LINE (parm);
+   
+ }
+ 
  /* FN is a function that has a complete body.  Clone the body as
     necessary.  Returns non-zero if there's no longer any need to
     process the main body.  */
*************** maybe_clone_body (fn)
*** 1057,1062 ****
--- 1077,1086 ----
        /* Adjust the parameter names and locations. */
        parm = DECL_ARGUMENTS (fn);
        clone_parm = DECL_ARGUMENTS (clone);
+       /* Update the `this' parameter, which is always first.
+ 	 Sometimes, we end update the `this' parameter twice because
+ 	 we process it again in the loop below.  That is harmless.  */
+       update_cloned_parm (parm, clone_parm);
        if (DECL_HAS_IN_CHARGE_PARM_P (fn))
  	parm = TREE_CHAIN (parm);
        if (DECL_HAS_VTT_PARM_P (fn))
*************** maybe_clone_body (fn)
*** 1066,1078 ****
        for (; parm;
  	   parm = TREE_CHAIN (parm), clone_parm = TREE_CHAIN (clone_parm))
  	{
! 	  DECL_ABSTRACT_ORIGIN (clone_parm) = parm;
! 
! 	  /* The name may have changed from the declaration. */
! 	  DECL_NAME (clone_parm) = DECL_NAME (parm);
! 	  DECL_SOURCE_FILE (clone_parm) = DECL_SOURCE_FILE (parm);
! 	  DECL_SOURCE_LINE (clone_parm) = DECL_SOURCE_LINE (parm);
!  
  	  /* We should only give unused information for one clone. */
  	  if (!first)
  	    TREE_USED (clone_parm) = 1;
--- 1090,1097 ----
        for (; parm;
  	   parm = TREE_CHAIN (parm), clone_parm = TREE_CHAIN (clone_parm))
  	{
! 	  /* Update this paramter.  */
! 	  update_cloned_parm (parm, clone_parm);
  	  /* We should only give unused information for one clone. */
  	  if (!first)
  	    TREE_USED (clone_parm) = 1;
Index: gcc/testsuite/gcc.dg/20000724-1.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.dg/20000724-1.c,v
retrieving revision 1.1.8.1
diff -c -p -r1.1.8.1 20000724-1.c
*** 20000724-1.c	2001/03/07 01:07:22	1.1.8.1
--- 20000724-1.c	2001/04/30 14:37:35
*************** NT	"ret"
*** 51,57 ****
  
  extern inline void do_asm(struct s * x)
  {
!   asm volatile("call ___checkme" : : "c" (x) : "memory");
  }
  
  int foo(void)
--- 51,57 ----
  
  extern inline void do_asm(struct s * x)
  {
!   asm volatile("call ___checkme" : : "c" (x) : "esp", "memory");
  }
  
  int foo(void)



More information about the Gcc-patches mailing list