> It seems that the whole m_item array should probably be replaced by
> summary. I think only reason it is written this way is since the code
> predates summaries.
>
> This seems like a symtom of a bug where m_item is not correctly updated
> with the result of symbol merging which may end up with mixing up
> sem_item from one body and apply it to another...
>
> Honza
Merging seems to behave correctly. We correctly remove body of weak
symbol, we just never marked it with body_removed.
---
During LTO symbol merging, weak symbols may be resolved to external
definition.
We reset the symbol, so the body might be released in unreachability
pass. But we didn't mark the symbol with body_removed, so ICF assumed
the body was still there causing SegFault.
gcc/lto/ChangeLog:
* lto-symtab.cc (lto_symtab_merge_symbols): Set body_removed
for symbols resolved outside of IR.
gcc/testsuite/ChangeLog:
* gcc.dg/lto/attr-weakref-2_0.c: New test.
* gcc.dg/lto/attr-weakref-2_1.c: New test.
---
gcc/lto/lto-symtab.cc | 1 +
gcc/testsuite/gcc.dg/lto/attr-weakref-2_0.c | 11 +++++++++++
gcc/testsuite/gcc.dg/lto/attr-weakref-2_1.c | 3 +++
3 files changed, 15 insertions(+)
create mode 100644 gcc/testsuite/gcc.dg/lto/attr-weakref-2_0.c
create mode 100644 gcc/testsuite/gcc.dg/lto/attr-weakref-2_1.c
diff --git a/gcc/lto/lto-symtab.cc b/gcc/lto/lto-symtab.cc
index acc750c125d..9805cbd1722 100644
--- a/gcc/lto/lto-symtab.cc
+++ b/gcc/lto/lto-symtab.cc
@@ -1043,6 +1043,7 @@ lto_symtab_merge_symbols (void)
node->analyzed = node->definition = false;
node->remove_all_references ();
}
+ node->body_removed = true;
}
DECL_EXTERNAL (node->decl) = 1;
}
diff --git a/gcc/testsuite/gcc.dg/lto/attr-weakref-2_0.c
b/gcc/testsuite/gcc.dg/lto/attr-weakref-2_0.c
new file mode 100644
index 00000000000..a55ef28bd13
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/lto/attr-weakref-2_0.c
@@ -0,0 +1,11 @@
+/* { dg-lto-do link } */
+/* { dg-lto-options {{-O2 -flto}} } */
+
+#define __weak __attribute__((__weak__))
+void __weak other() {}
+void __weak fn() {}
+
+int main() {
+ fn();
+ other();
+}
diff --git a/gcc/testsuite/gcc.dg/lto/attr-weakref-2_1.c
b/gcc/testsuite/gcc.dg/lto/attr-weakref-2_1.c
new file mode 100644
index 00000000000..639093fba46
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/lto/attr-weakref-2_1.c
@@ -0,0 +1,3 @@
+/* { dg-options {{-fno-lto}} } */
+
+void fn() {}
--
2.52.0