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.
&& !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.
&& !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. */
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. */
--- /dev/null
+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;
+}