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 debug/29202


Hi,

 the attached patch fixes PR debug/29202. We are crashing on code
looking like this

template <class charT> struct s
{
    charT imp() const;
};
template <class charT> charT s<charT>::imp() const
{
    static const int masks = 0;
}
__extension__ extern template char  s<char>::imp() const;
int regcompA(void)
{
  s<char> t;
  t.imp();
}

with compile flags "-g2 -feliminate-dwarf2-dups -finline-functions".

 There is problem with pruning dwarf info for extern inline candidates
with static variables. Extern template functions marked as inline are
marked as candidate for instantiation (cgraph node is builded). When
we are building cgraph we are putting function static variables into
varpool (even static variables from extern functions). When we want
dwarf info, we create it for all variables in varpool. In our case
static variables from extern function are added to pubnames (even if
function is not inlined anywhere). When extern function is not inlined
anywhere (not used in actual compilation unit) all dwarf info is
pruned out (even info about static variables). When we are checking
(flushing pubnames), if dwarf info is still valid after pruning
(die_mark is set), it fails.

 Fix prohibits adding static variables from extern non-inlinable
function into varpool.

 I am not completely sure if fact that extern function has static
variable prohibits it from inlining (if yes call of
tree_inlinable_function_p is not neccesary).

Bootstrapped and tested on x86_64-unknown-linux-gnu.


Greetings
Tomas

Changelog:

2008-02-20 Tomas Bily <tbily@suse.cz>

	PR debug/29202
	* cgraphbuild.c(build_cgraph_edges): prohibit adding static
          variables from extern non-inlinable function into varpool

	* g++.dg/debug/pr29202.C: New testcase.
Index: gcc/cgraphbuild.c
===================================================================
--- gcc/cgraphbuild.c	(revision 132315)
+++ gcc/cgraphbuild.c	(working copy)
@@ -30,6 +30,7 @@ along with GCC; see the file COPYING3.  
 #include "intl.h"
 #include "tree-gimple.h"
 #include "tree-pass.h"
+#include "tree-inline.h"
 
 /* Walk tree and record all calls and references to functions/variables.
    Called via walk_tree: TP is pointer to tree to be examined.  */
@@ -158,8 +159,11 @@ build_cgraph_edges (void)
     {
       tree decl = TREE_VALUE (step);
       if (TREE_CODE (decl) == VAR_DECL
-	  && (TREE_STATIC (decl) && !DECL_EXTERNAL (decl))
-	  && flag_unit_at_a_time)
+	  && (TREE_STATIC (decl)  
+	      && !(DECL_EXTERNAL (decl) 
+		   || (DECL_EXTERNAL (cfun->decl) 
+		       && !tree_inlinable_function_p (cfun->decl)))
+	      && flag_unit_at_a_time))
 	varpool_finalize_decl (decl);
       else if (TREE_CODE (decl) == VAR_DECL && DECL_INITIAL (decl))
 	walk_tree (&DECL_INITIAL (decl), record_reference, node, visited_nodes);
Index: gcc/testsuite/g++.dg/debug/pr29202.C
===================================================================
--- gcc/testsuite/g++.dg/debug/pr29202.C	(revision 0)
+++ gcc/testsuite/g++.dg/debug/pr29202.C	(revision 0)
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-g2 -feliminate-dwarf2-dups -finline-functions" } */
+
+template <class charT> struct s
+{
+    charT imp() const;
+};
+template <class charT> charT s<charT>::imp() const
+{
+    static const int masks = 0;
+    return (charT)masks;
+}
+__extension__ extern template char  s<char>::imp() const;
+int regcompA(void)
+{
+  s<char> t;
+  return (int) t.imp();
+}
+
+

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