cgraph: Avoid creating multiple *.localalias aliases with the same name [PR93384]
authorJakub Jelinek <jakub@redhat.com>
Thu, 30 Jan 2020 20:32:36 +0000 (21:32 +0100)
committerJakub Jelinek <jakub@redhat.com>
Thu, 30 Jan 2020 20:32:36 +0000 (21:32 +0100)
The following testcase FAILs on powerpc64le-linux with assembler errors, as we
emit a call to bar.localalias, then .set bar.localalias, bar twice and then
another call to bar.localalias.  The problem is that bar.localalias can be created
at various stages and e.g. ipa-pure-const can slightly adjust the original decl,
so that the existing bar.localalias isn't considered usable (different
flags_from_decl_or_type).  In that case, we'd create another bar.localalias, which
clashes with the existing name.

Fixed by retrying with another name if it is already present.  The various localalias
aliases shouldn't be that many, from different partitions they would be lto_priv
suffixed and in most cases they would already have the same type/flags/attributes.

2020-01-30  Jakub Jelinek  <jakub@redhat.com>

PR lto/93384
* symtab.c (symtab_node::noninterposable_alias): If localalias
already exists, but is not usable, append numbers after it until
a unique name is found.  Formatting fix.

* gcc.dg/lto/pr93384_0.c: New test.
* gcc.dg/lto/pr93384_1.c: New file.

gcc/ChangeLog
gcc/symtab.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/lto/pr93384_0.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/lto/pr93384_1.c [new file with mode: 0644]

index f2cc0276600169c243225dd61e1667251cd2cb66..a45d0907e9d116b25970ab43be7932ea50deb28f 100644 (file)
@@ -1,5 +1,10 @@
 2020-01-30  Jakub Jelinek  <jakub@redhat.com>
 
+       PR lto/93384
+       * symtab.c (symtab_node::noninterposable_alias): If localalias
+       already exists, but is not usable, append numbers after it until
+       a unique name is found.  Formatting fix.
+
        PR middle-end/93505
        * combine.c (simplify_comparison) <case ROTATE>: Punt on out of range
        rotate counts.
index f141200a452159269cc35ce5af087e5a70f60280..eae891ab211ed7ffa4b4e0f813a5d7d143661c67 100644 (file)
@@ -1864,7 +1864,7 @@ symtab_node::noninterposable_alias (void)
   symtab_node *node = ultimate_alias_target ();
   gcc_assert (!node->alias && !node->weakref);
   node->call_for_symbol_and_aliases (symtab_node::noninterposable_alias,
-                                  (void *)&new_node, true);
+                                    (void *)&new_node, true);
   if (new_node)
     return new_node;
 
@@ -1875,7 +1875,17 @@ symtab_node::noninterposable_alias (void)
   /* Otherwise create a new one.  */
   new_decl = copy_node (node->decl);
   DECL_DLLIMPORT_P (new_decl) = 0;
-  DECL_NAME (new_decl) = clone_function_name (node->decl, "localalias");
+  tree name = clone_function_name (node->decl, "localalias");
+  if (!flag_wpa)
+    {
+      unsigned long num = 0;
+      /* In the rare case we already have a localalias, but the above
+        node->call_for_symbol_and_aliases call didn't find any suitable,
+        iterate until we find one not used yet.  */
+      while (symtab_node::get_for_asmname (name))
+       name = clone_function_name (node->decl, "localalias", num++);
+    }
+  DECL_NAME (new_decl) = name;
   if (TREE_CODE (new_decl) == FUNCTION_DECL)
     DECL_STRUCT_FUNCTION (new_decl) = NULL;
   DECL_INITIAL (new_decl) = NULL;
index ce53e2c8bf8eac103c9c429ede7b82d5c3502c3b..4503016a73e6555ed479e47b537ad5be9479aeab 100644 (file)
@@ -1,5 +1,9 @@
 2020-01-30  Jakub Jelinek  <jakub@redhat.com>
 
+       PR lto/93384
+       * gcc.dg/lto/pr93384_0.c: New test.
+       * gcc.dg/lto/pr93384_1.c: New file.
+
        PR middle-end/93505
        * gcc.c-torture/compile/pr93505.c: New test.
 
diff --git a/gcc/testsuite/gcc.dg/lto/pr93384_0.c b/gcc/testsuite/gcc.dg/lto/pr93384_0.c
new file mode 100644 (file)
index 0000000..fdcb9a2
--- /dev/null
@@ -0,0 +1,12 @@
+/* PR lto/93384 */
+/* { dg-lto-do link } */
+/* { dg-require-effective-target fpic } */
+/* { dg-require-effective-target shared } */
+/* { dg-lto-options { { -O2 -flto -ffat-lto-objects -fpic -fno-semantic-interposition } } } */
+/* { dg-extra-ld-options { -shared -flto-partition=none } } */
+
+void bar (void);
+__attribute__((noipa)) void quux (int x) { if (x == 5) bar (); }
+__attribute__((noipa, noreturn)) void foo (void) { while (1) ; }
+__attribute__((noinline)) void bar (void) { asm (""); quux (7); foo (); }
+void baz (int x) { if (x) bar (); }
diff --git a/gcc/testsuite/gcc.dg/lto/pr93384_1.c b/gcc/testsuite/gcc.dg/lto/pr93384_1.c
new file mode 100644 (file)
index 0000000..1b9d6af
--- /dev/null
@@ -0,0 +1,2 @@
+extern void bar (void);
+void qux (int x) { if (!x) bar (); }