diff mbox

PR ipa/60150

Message ID 20140302222349.GA19250@kam.mff.cuni.cz
State New
Headers show

Commit Message

Jan Hubicka March 2, 2014, 10:23 p.m. UTC
Hi,
this patch fixes simple ordering issue in function_and_variable_visibility.

Bootstrapped/regtested x86_64-linux, comitted.
	PR ipa/60150
	* ipa.c (function_and_variable_visibility): When dissolving comdat
	group, also set all symbols to local.
	* g++.dg/lto/pr60150.H: New testcase.
	* g++.dg/lto/pr60150_0.C: New testcase.
	* g++.dg/lto/pr60150_1.C: New testcase.
diff mbox

Patch

Index: ipa.c
===================================================================
--- ipa.c	(revision 208247)
+++ ipa.c	(working copy)
@@ -970,15 +970,32 @@  function_and_variable_visibility (bool w
 	  gcc_assert (whole_program || in_lto_p
 		      || !TREE_PUBLIC (node->decl));
 	  node->unique_name = ((node->resolution == LDPR_PREVAILING_DEF_IRONLY
-				      || node->resolution == LDPR_PREVAILING_DEF_IRONLY_EXP)
-				      && TREE_PUBLIC (node->decl));
+				|| node->unique_name
+				|| node->resolution == LDPR_PREVAILING_DEF_IRONLY_EXP)
+				&& TREE_PUBLIC (node->decl));
 	  node->resolution = LDPR_PREVAILING_DEF_IRONLY;
 	  if (node->same_comdat_group && TREE_PUBLIC (node->decl))
-	    /* cgraph_externally_visible_p has already checked all other nodes
-	       in the group and they will all be made local.  We need to
-	       dissolve the group at once so that the predicate does not
-	       segfault though. */
-	    symtab_dissolve_same_comdat_group_list (node);
+	    {
+	      symtab_node *next = node;
+
+	      /* Set all members of comdat group local.  */
+	      if (node->same_comdat_group)
+		for (next = node->same_comdat_group;
+		     next != node;
+		     next = next->same_comdat_group)
+		{
+		  symtab_make_decl_local (next->decl);
+		  next->unique_name = ((next->resolution == LDPR_PREVAILING_DEF_IRONLY
+					|| next->unique_name
+					|| next->resolution == LDPR_PREVAILING_DEF_IRONLY_EXP)
+					&& TREE_PUBLIC (next->decl));
+		}
+	      /* cgraph_externally_visible_p has already checked all other nodes
+	         in the group and they will all be made local.  We need to
+	         dissolve the group at once so that the predicate does not
+	         segfault though. */
+	      symtab_dissolve_same_comdat_group_list (node);
+	    }
 	  symtab_make_decl_local (node->decl);
 	}
 
Index: testsuite/g++.dg/lto/pr60150.H
===================================================================
--- testsuite/g++.dg/lto/pr60150.H	(revision 0)
+++ testsuite/g++.dg/lto/pr60150.H	(revision 0)
@@ -0,0 +1,20 @@ 
+struct Base {
+  virtual void f() = 0;
+};
+
+struct X : public Base { };
+struct Y : public Base { };
+struct Z : public Base { };
+struct T : public Base { };
+
+struct S : public X, public Y, public Z
+#ifdef XXX
+, public T
+#endif
+{
+  void f()
+#ifdef XXX
+  { }
+#endif
+  ;
+};
Index: testsuite/g++.dg/lto/pr60150_0.C
===================================================================
--- testsuite/g++.dg/lto/pr60150_0.C	(revision 0)
+++ testsuite/g++.dg/lto/pr60150_0.C	(revision 0)
@@ -0,0 +1,8 @@ 
+// { dg-lto-do run }
+#include "pr60150.H"
+
+int main()
+{
+  S s;
+  return 0;
+}
Index: testsuite/g++.dg/lto/pr60150_1.C
===================================================================
--- testsuite/g++.dg/lto/pr60150_1.C	(revision 0)
+++ testsuite/g++.dg/lto/pr60150_1.C	(revision 0)
@@ -0,0 +1,4 @@ 
+// { dg-options "-fno-lto" }
+#include "pr60150.H"
+
+void S::f() { }