Patchwork varpool PATCH for c++/51832 (multiply defined symbol with LTO plugin)

login
register
mail settings
Submitter Jason Merrill
Date Jan. 20, 2012, 7:59 p.m.
Message ID <4F19C788.8020909@redhat.com>
Download mbox | patch
Permalink /patch/137095/
State New
Headers show

Comments

Jason Merrill - Jan. 20, 2012, 7:59 p.m.
As a result of my recent mangling work, any code that uses variadic 
templates will use the forward-compatibility aliases because the 
mangling of argument packs has changed.  This exposed an issue that we 
weren't copying DECL_EXTERNAL from decl to alias along with other 
linkage flags in varpool_analyze_pending_decls.  Fixed thus.  It would 
be nice for the front end to fix up the linkage flags appropriately, but 
this small change seems preferable for 4.7.

Tested x86_64-pc-linux-gnu.  OK for trunk?
Richard Guenther - Jan. 22, 2012, 12:47 p.m.
On Fri, Jan 20, 2012 at 8:59 PM, Jason Merrill <jason@redhat.com> wrote:
> As a result of my recent mangling work, any code that uses variadic
> templates will use the forward-compatibility aliases because the mangling of
> argument packs has changed.  This exposed an issue that we weren't copying
> DECL_EXTERNAL from decl to alias along with other linkage flags in
> varpool_analyze_pending_decls.  Fixed thus.  It would be nice for the front
> end to fix up the linkage flags appropriately, but this small change seems
> preferable for 4.7.
>
> Tested x86_64-pc-linux-gnu.  OK for trunk?

Ok.

Thanks,
Richard.

Patch

commit ef67d3adcc8accbc75acb6b81a28f231aaddfc35
Author: Jason Merrill <jason@redhat.com>
Date:   Fri Jan 20 13:32:39 2012 -0500

    	PR c++/51832
    	* varpool.c (varpool_analyze_pending_decls): Copy DECL_EXTERNAL
    	for extra name aliases.

diff --git a/gcc/testsuite/g++.dg/lto/pr51832.h b/gcc/testsuite/g++.dg/lto/pr51832.h
new file mode 100644
index 0000000..fee3693
--- /dev/null
+++ b/gcc/testsuite/g++.dg/lto/pr51832.h
@@ -0,0 +1,6 @@ 
+template<class...T> struct A
+{
+  static int i;
+};
+
+inline void f() { A<int>::i = 0; }
diff --git a/gcc/testsuite/g++.dg/lto/pr51832_0.C b/gcc/testsuite/g++.dg/lto/pr51832_0.C
new file mode 100644
index 0000000..e99cea4
--- /dev/null
+++ b/gcc/testsuite/g++.dg/lto/pr51832_0.C
@@ -0,0 +1,8 @@ 
+// PR c++/51832
+// { dg-lto-do link }
+// { dg-lto-options { "-std=c++11 -flto -fabi-version=2" } }
+
+#include "pr51832.h"
+
+int main() { }
+
diff --git a/gcc/testsuite/g++.dg/lto/pr51832_1.C b/gcc/testsuite/g++.dg/lto/pr51832_1.C
new file mode 100644
index 0000000..6f0137b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/lto/pr51832_1.C
@@ -0,0 +1 @@ 
+#include "pr51832.h"
diff --git a/gcc/varpool.c b/gcc/varpool.c
index 74fc1ba..e01accb 100644
--- a/gcc/varpool.c
+++ b/gcc/varpool.c
@@ -484,6 +484,7 @@  varpool_analyze_pending_decls (void)
 	    {
 	      DECL_WEAK (node->decl) = DECL_WEAK (node->alias_of);
 	      TREE_PUBLIC (node->decl) = TREE_PUBLIC (node->alias_of);
+	      DECL_EXTERNAL (node->decl) = DECL_EXTERNAL (node->alias_of);
 	      DECL_VISIBILITY (node->decl) = DECL_VISIBILITY (node->alias_of);
 	      if (TREE_PUBLIC (node->decl))
 		{