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++/18416


This patch fixes a crash that occurred on IA64 GNU/Linux, but not IA32
GNU/Linux.  

The proximate cause of the difference in behavior is that IA64 defines
ASM_OUTPUT_EXTERNAL.  At some point in the compilation, we call
assemble_external on a variable, which causes is it to get DECL_RTL on
IA64, but not IA32.

The real problem, however, is that rest_of_decl_compilation was
looking at DECL_RTL_SET_P to decide whether to pass a variable to the
cgraph machinery or directly to assemble_variable.  That breaks
assumptions in the C++ front end, which knows that in unit-at-a-time
mode all variables will go through cgraph.  The C++ front end is
correct; rest_of_decl_compilation is bogus.  

The alleged justification for this behavior is that
check_global_declarations will clear out DECL_RTL for certain
variables.  However, that code is also bogus, on at least two fronts.
First, DECL_RTL is cleared only for undefined TREE_STATIC variables.
Perhaps the intended predicate was "!TREE_PUBLIC".  All variables in
check_global_declarations will be TREE_STATIC, so the current code
does not make sense.  Second, the reason for clearing the RTL was to
avoid the debug generators mentioning the variable.  That doesn't make
sense either, but if we do want to do that we should be using
DECL_IGNORED, not clearing DECL_RTL.

Bootstrapped and tested on i686-pc-linux-gnu, the affected test case
was also tested with an ia64-none-linux-gnu cross compiler.  Applied
on the mainline. 

--
Mark Mitchell
CodeSourcery, LLC
mark@codesourcery.com

2004-11-12  Mark Mitchell  <mark@codesourcery.com>

	PR c++/18416
	* passes.c (rest_of_decl_compilation): Do not look at DECL_RTL
	when deciding whether to pass a variable to
	cgraph_varpool_finalize_decl or assemble_variable.
	* toplev.c (check_global_declarations): Do not clear DECL_RTL. 

2004-11-12  Mark Mitchell  <mark@codesourcery.com>

	PR c++/18416
	* g++.dg/init/global1.C: New test.

Index: passes.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/passes.c,v
retrieving revision 2.54
diff -c -5 -p -r2.54 passes.c
*** passes.c	9 Nov 2004 01:04:56 -0000	2.54
--- passes.c	12 Nov 2004 16:29:41 -0000
*************** rest_of_decl_compilation (tree decl,
*** 227,244 ****
  	   || !DECL_DEFER_OUTPUT (decl)
  	   || (flag_unit_at_a_time && DECL_INITIAL (decl)))
  	  && !DECL_EXTERNAL (decl))
  	{
  	  if (flag_unit_at_a_time && !cgraph_global_info_ready
! 	      && TREE_CODE (decl) != FUNCTION_DECL && top_level
! 	      /* If we defer processing of decls that have had their
! 		 DECL_RTL set above (say, in make_decl_rtl),
! 		 check_global_declarations() will clear it before
! 		 assemble_variable has a chance to act on it.  This
! 		 would remove all traces of the register name in a
! 		 global register variable, for example.  */
! 	      && !DECL_RTL_SET_P (decl))
  	    cgraph_varpool_finalize_decl (decl);
  	  else
  	    assemble_variable (decl, top_level, at_end, 0);
  	}
  
--- 227,237 ----
  	   || !DECL_DEFER_OUTPUT (decl)
  	   || (flag_unit_at_a_time && DECL_INITIAL (decl)))
  	  && !DECL_EXTERNAL (decl))
  	{
  	  if (flag_unit_at_a_time && !cgraph_global_info_ready
! 	      && TREE_CODE (decl) != FUNCTION_DECL && top_level)
  	    cgraph_varpool_finalize_decl (decl);
  	  else
  	    assemble_variable (decl, top_level, at_end, 0);
  	}
  
Index: toplev.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/toplev.c,v
retrieving revision 1.930
diff -c -5 -p -r1.930 toplev.c
*** toplev.c	2 Nov 2004 02:41:36 -0000	1.930
--- toplev.c	12 Nov 2004 16:29:41 -0000
*************** check_global_declarations (tree *vec, in
*** 811,827 ****
  
    for (i = 0; i < len; i++)
      {
        decl = vec[i];
  
-       if (TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl)
- 	  && ! TREE_ASM_WRITTEN (decl))
- 	/* Cancel the RTL for this decl so that, if debugging info
- 	   output for global variables is still to come,
- 	   this one will be omitted.  */
- 	SET_DECL_RTL (decl, NULL_RTX);
- 
        /* Warn about any function
  	 declared static but not defined.
  	 We don't warn about variables,
  	 because many programs have static variables
  	 that exist only to get some text into the object file.  */
--- 811,820 ----
Index: testsuite/g++.dg/init/global1.C
===================================================================
RCS file: testsuite/g++.dg/init/global1.C
diff -N testsuite/g++.dg/init/global1.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/init/global1.C	12 Nov 2004 16:35:35 -0000
***************
*** 0 ****
--- 1,16 ----
+ // PR c++/18416
+ 
+ class errarg { 
+   enum { EMPTY } type; 
+ public: 
+   errarg(); 
+ }; 
+ extern errarg empty_errarg; 
+ extern void errprint(const char *, 
+ 		     const errarg &arg1 = empty_errarg, 
+ 		     const errarg &arg2 = empty_errarg, 
+ 		     const errarg &arg3 = empty_errarg); 
+ errarg::errarg() : type(EMPTY) 
+ { 
+ } 
+ errarg empty_errarg; 


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