https://gcc.gnu.org/g:005ce1c1826777f33d5011723827d17f1fcd55c1
commit r13-9143-g005ce1c1826777f33d5011723827d17f1fcd55c1 Author: Martin Jambor <mjam...@suse.cz> Date: Fri Oct 18 21:32:16 2024 +0200 ipa: Treat static constructors and destructors as non-local (PR 115815) In PR 115815, IPA-SRA thought it had control over all invocations of a (recursive) static destructor but it did not see the implied invocation which led to the original being left behind and the clean-up code encountering uses of SSAs that definitely should have been dead. Fixed by teaching cgraph_node::can_be_local_p about static constructors and destructors. Similar test is missing in cgraph_node::local_p so I added the check there as well. In addition to the commit with the fix, this backport also contains squashed commit 1a458bdeb223ffa501bac8e76182115681967094 which fixes dejagnu directives in the testcase. gcc/ChangeLog: 2024-07-25 Martin Jambor <mjam...@suse.cz> PR ipa/115815 * cgraph.cc (cgraph_node_cannot_be_local_p_1): Also check DECL_STATIC_CONSTRUCTOR and DECL_STATIC_DESTRUCTOR. * ipa-visibility.cc (non_local_p): Likewise. (cgraph_node::local_p): Delete extraneous line of tabs. gcc/testsuite/ChangeLog: 2024-07-25 Martin Jambor <mjam...@suse.cz> PR ipa/115815 * gcc.dg/lto/pr115815_0.c: New test. (cherry picked from commit e98ad6a049c96c21cf641954584c2f5b7df0ce93) Diff: --- gcc/cgraph.cc | 4 +++- gcc/ipa-visibility.cc | 5 +++-- gcc/testsuite/gcc.dg/lto/pr115815_0.c | 22 ++++++++++++++++++++++ 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/gcc/cgraph.cc b/gcc/cgraph.cc index 7a14c00b60a0..ad71cf82823c 100644 --- a/gcc/cgraph.cc +++ b/gcc/cgraph.cc @@ -2433,7 +2433,9 @@ cgraph_node_cannot_be_local_p_1 (cgraph_node *node, void *) && !node->forced_by_abi && !node->used_from_object_file_p () && !node->same_comdat_group) - || !node->externally_visible)); + || !node->externally_visible) + && !DECL_STATIC_CONSTRUCTOR (node->decl) + && !DECL_STATIC_DESTRUCTOR (node->decl)); } /* Return true if cgraph_node can be made local for API change. diff --git a/gcc/ipa-visibility.cc b/gcc/ipa-visibility.cc index 8ec82bb333e2..9ca0e39df950 100644 --- a/gcc/ipa-visibility.cc +++ b/gcc/ipa-visibility.cc @@ -102,7 +102,9 @@ non_local_p (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED) && !node->externally_visible && !node->used_from_other_partition && !node->in_other_partition - && node->get_availability () >= AVAIL_AVAILABLE); + && node->get_availability () >= AVAIL_AVAILABLE + && !DECL_STATIC_CONSTRUCTOR (node->decl) + && !DECL_STATIC_DESTRUCTOR (node->decl)); } /* Return true when function can be marked local. */ @@ -116,7 +118,6 @@ cgraph_node::local_p (void) return n->callees->callee->local_p (); return !n->call_for_symbol_thunks_and_aliases (non_local_p, NULL, true); - } /* A helper for comdat_can_be_unshared_p. */ diff --git a/gcc/testsuite/gcc.dg/lto/pr115815_0.c b/gcc/testsuite/gcc.dg/lto/pr115815_0.c new file mode 100644 index 000000000000..ade91def55b0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/lto/pr115815_0.c @@ -0,0 +1,22 @@ +/* { dg-lto-options {{-O2 -flto}} } */ +/* { dg-lto-do link } */ +/* { dg-require-effective-target global_constructor } */ + +int a; +volatile int v; +volatile int w; + +int __attribute__((destructor)) +b() { + if (v) + return a + b(); + v = 5; + return 0; +} + +int +main (int argc, char **argv) +{ + w = 1; + return 0; +}