Hi,
this is the fourth version of this patch (v3:
https://gcc.gnu.org/pipermail/gcc-patches/2025-December/702732.html).
I changed the call to referred_to_p to a check for address_taken, as it
wasn't the right predicate to use, as Martin pointed out.  I also
changed its use in redirect_callee to just check for references, as that
usage suffered from the same problem.

Bootstrapped and regtested on x86_64-linux with
RUNTESTFLAGS="--target_board='unix{,-m32}'" with no issues.

OK for master?

Thanks,
Josef

        PR ipa/122798

gcc/ChangeLog:

        * cgraph.cc (cgraph_edge::redirect_callee): Use
        iterate_referring instead of referred_to_p.
        * cgraphclones.cc (set_new_clone_decl_and_node_flags): Set local
        to true iff the node does not have its address taken.

Signed-off-by: Josef Melcr <[email protected]>
---
 gcc/cgraph.cc       | 6 +++++-
 gcc/cgraphclones.cc | 4 +++-
 2 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/gcc/cgraph.cc b/gcc/cgraph.cc
index 3c21e174943..1a7d49922e0 100644
--- a/gcc/cgraph.cc
+++ b/gcc/cgraph.cc
@@ -1696,8 +1696,12 @@ cgraph_edge::redirect_callee (cgraph_node *n)
       old_ref->remove_reference ();
       ipa_ref *new_ref = caller->create_reference (n, IPA_REF_ADDR, call_stmt);
       new_ref->lto_stmt_uid = lto_stmt_uid;
-      if (!old_callee->referred_to_p ())
+      /* If the last reference to OLD_CALLEE has been redirected, unset
+        address_taken.  old_ref is only used as a placeholder when looking for
+        a different reference.  */
+      if (!old_callee->iterate_referring (0, old_ref))
        old_callee->address_taken = 0;
+      n->mark_address_taken ();
     }
 
   if (!inline_failed)
diff --git a/gcc/cgraphclones.cc b/gcc/cgraphclones.cc
index 49f0e58fa1e..816fc53c28a 100644
--- a/gcc/cgraphclones.cc
+++ b/gcc/cgraphclones.cc
@@ -176,7 +176,9 @@ set_new_clone_decl_and_node_flags (cgraph_node *new_node)
   DECL_IS_REPLACEABLE_OPERATOR (new_node->decl) = 0;
 
   new_node->externally_visible = 0;
-  new_node->local = 1;
+  /* Clones of callbacks might have their address taken, and thus cannot be
+     local.  */
+  new_node->local = !new_node->address_taken;
   new_node->lowered = true;
   new_node->semantic_interposition = 0;
 }
-- 
2.52.0

Reply via email to