The following fixes a thinko in the handling of interposed weak
definitions which confused the interposition check in
get_availability by setting DECL_EXTERNAL too early.

Bootstrap and regtest running on x86_64-unknown-linux-gnu, will push
if that succeeds.

        PR lto/91299
gcc/lto/
        * lto-symtab.cc (lto_symtab_merge_symbols): Set DECL_EXTERNAL
        only after calling get_availability.

        * gcc.dg/lto/pr91299_0.c: New testcase.
        * gcc.dg/lto/pr91299_1.c: Likewise.
---
 gcc/lto/lto-symtab.cc                |  2 +-
 gcc/testsuite/gcc.dg/lto/pr91299_0.c | 16 ++++++++++++++++
 gcc/testsuite/gcc.dg/lto/pr91299_1.c |  6 ++++++
 3 files changed, 23 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.dg/lto/pr91299_0.c
 create mode 100644 gcc/testsuite/gcc.dg/lto/pr91299_1.c

diff --git a/gcc/lto/lto-symtab.cc b/gcc/lto/lto-symtab.cc
index bc3c144e444..66674a4415f 100644
--- a/gcc/lto/lto-symtab.cc
+++ b/gcc/lto/lto-symtab.cc
@@ -1016,7 +1016,6 @@ lto_symtab_merge_symbols (void)
                  || node->resolution == LDPR_RESOLVED_EXEC
                  || node->resolution == LDPR_RESOLVED_DYN))
            {
-             DECL_EXTERNAL (node->decl) = 1;
              /* If alias to local symbol was preempted by external definition,
                 we know it is not pointing to the local symbol.  Remove it.  */
              if (node->alias
@@ -1042,6 +1041,7 @@ lto_symtab_merge_symbols (void)
                      node->remove_all_references ();
                    }
                }
+             DECL_EXTERNAL (node->decl) = 1;
            }
 
          if (!(cnode = dyn_cast <cgraph_node *> (node))
diff --git a/gcc/testsuite/gcc.dg/lto/pr91299_0.c 
b/gcc/testsuite/gcc.dg/lto/pr91299_0.c
new file mode 100644
index 00000000000..d9a8b21d6b8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/lto/pr91299_0.c
@@ -0,0 +1,16 @@
+/* { dg-lto-do run } */
+/* { dg-lto-options { { -O2 -flto } } } */
+
+__attribute__((weak)) int get_t(void)
+{
+  return 0;
+}
+
+int a;
+int main(void)
+{
+  a = get_t();
+  if (a != 1)
+    __builtin_abort ();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/lto/pr91299_1.c 
b/gcc/testsuite/gcc.dg/lto/pr91299_1.c
new file mode 100644
index 00000000000..29a28520f7b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/lto/pr91299_1.c
@@ -0,0 +1,6 @@
+/* { dg-options "-fno-lto" } */
+
+int get_t(void)
+{
+    return 1;
+}
-- 
2.43.0

Reply via email to