aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMartin Jambor <mjambor@suse.cz>2024-09-06 14:12:53 +0200
committerMartin Jambor <jamborm@gcc.gnu.org>2024-09-06 14:15:43 +0200
commite98ad6a049c96c21cf641954584c2f5b7df0ce93 (patch)
treefee2fe7aca6977c19e39f4c99cb00bff4b0cea97 /gcc
parentea9d4bf45ef906b990abdb101297e34366059f1c (diff)
downloadgcc-e98ad6a049c96c21cf641954584c2f5b7df0ce93.zip
gcc-e98ad6a049c96c21cf641954584c2f5b7df0ce93.tar.gz
gcc-e98ad6a049c96c21cf641954584c2f5b7df0ce93.tar.bz2
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. gcc/ChangeLog: 2024-07-25 Martin Jambor <mjambor@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 <mjambor@suse.cz> PR ipa/115815 * gcc.dg/lto/pr115815_0.c: New test.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cgraph.cc4
-rw-r--r--gcc/ipa-visibility.cc5
-rw-r--r--gcc/testsuite/gcc.dg/lto/pr115815_0.c18
3 files changed, 24 insertions, 3 deletions
diff --git a/gcc/cgraph.cc b/gcc/cgraph.cc
index 473d841..39a3adb 100644
--- a/gcc/cgraph.cc
+++ b/gcc/cgraph.cc
@@ -2434,7 +2434,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 501d3c3..21f0c47 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 0000000..d938ae4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/lto/pr115815_0.c
@@ -0,0 +1,18 @@
+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;
+}