Hi,

On 11/19/25 7:01 PM, Martin Jambor wrote:
Hello,

On Sat, Oct 18 2025, Josef Melcr wrote:
The inclusion of this early return statement has been discussed before,
it was ultimately left out of the original patch, but it turns out to be
necessary.

When a callback edge is being created, it is first created by
symbol_table::create_edge, which is where it is added to the call site
hash.  However, its callback flag is not set at that point, so the early
return for callback edges doesn't affect it.  This causes the wrong edge
to be hashed, ultimately leading to segfaults and ICEs. This happens
many times in the testsuite, the one I noticed first was
libgomp.fortran/simd7.f90.

gcc/ChangeLog:

        * cgraph.cc (cgraph_add_edge_to_call_site_hash): Add an early
        return when the hashed edge is a callback-carrying edge.
This is OK.  Sorry that it took so long, I wanted to have a look myself
what was going on.

May just suggest that...

Signed-off-by: Josef Melcr <[email protected]>
---
  gcc/cgraph.cc | 7 ++++---
  1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/gcc/cgraph.cc b/gcc/cgraph.cc
index d1b2e2a162c..782c4d87b63 100644
--- a/gcc/cgraph.cc
+++ b/gcc/cgraph.cc
@@ -885,9 +885,10 @@ cgraph_add_edge_to_call_site_hash (cgraph_edge *e)
        gcc_assert (edge->speculative || edge->has_callback);
        if (edge->has_callback)
        /* If the slot is already occupied, then the hashed edge is the
-          callback-carrying edge, which is desired behavior, so we can safely
-          return.  */
-       gcc_checking_assert (edge == e);
+          callback-carrying edge, which is desired behavior.  If we don't
+          return now, the slot could be overwritten during callback edge
+          creation, because the flags are not initialized at that point.  */
... the comment simply says "In some cases the callback flag of e is not
set yet and so the early exit above is not taken."

I think that is sufficient and cleaner.

Thanks and sorry again.

Committed with the comment change, thank you.


Martin
Josef


+       return;
        if (e->callee && (!e->prev_callee
                        || !e->prev_callee->speculative
                        || e->prev_callee->call_stmt != e->call_stmt))
--
2.51.1.dirty

Reply via email to