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]

[lto][patch] Fix linking error


The attached patch fixes the include testcase. The problem was that
cc1plus was writing function decls to disk that were only reachable
via the DECL_INITIAL of a vtable. It was doing so even if the vtable
had a home in another file and the vtable VAR_DECL was DECL_EXTERNAL.
Since the function decl was not really used, there was no cgraph node
for it.

In wpa we assume that if a decl has a node, then the prevailing decl
also has. This was false if the file described  above (with a decl but
no cgraph node for it) was linked with a file that actually used the
function and therefore had both a function decl and a node.

One option would be to make wpa handle that case, but it is much
easier to just ovoid writing decls that are not used.

Bootstrapped and regression tested.

2009-03-11  Rafael Avila de Espindola  <espindola@google.com>

	* g++.dg/lto/20090311_0.C: New.
	* g++.dg/lto/20090311_1.C: New.

2009-03-11  Rafael Avila de Espindola  <espindola@google.com>

	* tree.c (free_lang_data_in_decl): Free DECL_INITIAL of DECL_EXTERNAL
	VAR_DECLs.

Cheers,
-- 
Rafael Avila de Espindola

Google | Gordon House | Barrow Street | Dublin 4 | Ireland
Registered in Dublin, Ireland | Registration Number: 368047
diff --git a/gcc/testsuite/g++.dg/lto/20090311_0.C b/gcc/testsuite/g++.dg/lto/20090311_0.C
new file mode 100644
index 0000000..6c6e197
--- /dev/null
+++ b/gcc/testsuite/g++.dg/lto/20090311_0.C
@@ -0,0 +1,12 @@
+class C1 {
+public:     virtual ~C1() {
+}
+};
+class C2 : public C1 {
+public:
+  C2(void *q);
+  virtual void A();
+};
+int main(int argc, char **argv) {
+  C2 h(0);
+}
diff --git a/gcc/testsuite/g++.dg/lto/20090311_1.C b/gcc/testsuite/g++.dg/lto/20090311_1.C
new file mode 100644
index 0000000..e78da72
--- /dev/null
+++ b/gcc/testsuite/g++.dg/lto/20090311_1.C
@@ -0,0 +1,13 @@
+class C1 {
+public:    virtual ~C1() {
+}
+};
+class C2 : public C1 {
+  C2(void *q);
+  virtual void A();
+};
+void C2::A() {
+}
+C2::C2(void *q)
+{
+}
diff --git a/gcc/tree.c b/gcc/tree.c
index 8e94d0c..fee59cd 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -4034,6 +4034,9 @@ free_lang_data_in_decl (tree decl)
 	  && TREE_CODE (expr) == VAR_DECL
 	  && !TREE_STATIC (expr) && !DECL_EXTERNAL (expr))
 	SET_DECL_DEBUG_EXPR (decl, NULL_TREE);
+
+      if (DECL_EXTERNAL (decl))
+	DECL_INITIAL (decl) = NULL_TREE;
     }
   else if (TREE_CODE (decl) == TYPE_DECL)
     {

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