https://gcc.gnu.org/g:975fd1ef9f70779cce6fa756372869f0a17b32dc
commit r17-5630-g975fd1ef9f70779cce6fa756372869f0a17b32dc Author: Josef Melcr <[email protected]> Date: Wed Sep 16 11:26:20 2026 +0200 cgraph: Adjust callback edge sanity checks Callback edges without a carrying edge weren't permitted, but that changed with internal callback edges. This patch changes the code checking that a carrying edge exists to account for this. The patch also moves the code to a different loop, where it can be checked also in WPA. gcc/ChangeLog: * cgraph.cc (cgraph_node::verify_node): Adjust checks for internal callback edges, allow the checks to run in WPA. Signed-off-by: Josef Melcr <[email protected]> Diff: --- gcc/cgraph.cc | 118 ++++++++++++++++++++++++++++++---------------------------- 1 file changed, 61 insertions(+), 57 deletions(-) diff --git a/gcc/cgraph.cc b/gcc/cgraph.cc index f86b14762df6..0aa89d657bbb 100644 --- a/gcc/cgraph.cc +++ b/gcc/cgraph.cc @@ -4204,6 +4204,67 @@ cgraph_node::verify_node (void) && verify_speculative_call (e->caller, e->call_stmt, e->lto_stmt_uid, NULL)) error_found = true; + if (e->callback && e->has_callback) + { + error ("edge has both callback and has_callback set"); + error_found = true; + } + if (e->callback) + { + cgraph_edge *carrying = e->get_callback_carrying_edge (); + if (!carrying && !e->callee->assume_function) + { + error ("callback edge %s->%s has no callback-carrying edge", + identifier_to_locale (e->caller->dump_name ()), + identifier_to_locale (e->callee->dump_name ())); + error_found = true; + } + else if (carrying && e->callee->assume_function) + { + error ("internal callback edge %s->%s should not have a " + "callback-carrying edge", + identifier_to_locale (e->caller->dump_name ()), + identifier_to_locale (e->callee->dump_name ())); + error_found = true; + } + } + if (e->has_callback + && !callback_is_special_cased (e->callee->decl, e->call_stmt) + && !fndecl_built_in_p (e->callee->decl, BUILT_IN_UNREACHABLE)) + { + int ncallbacks = 0; + int nfound_edges = 0; + for (tree cb = lookup_attribute ("callback_only", + DECL_ATTRIBUTES (e->callee->decl)); + cb; cb = lookup_attribute ("callback_only", TREE_CHAIN (cb)), + ncallbacks++) + ; + for (cgraph_edge *cbe = callees; cbe; cbe = cbe->next_callee) + { + if (cbe->callback && cbe->call_stmt == e->call_stmt + && cbe->lto_stmt_uid == e->lto_stmt_uid) + { + nfound_edges++; + } + } + if (ncallbacks < nfound_edges) + { + error ("callback edge %s->%s callback edge count mismatch, " + "expected at most %d, found %d", + identifier_to_locale (e->caller->name ()), + identifier_to_locale (e->callee->name ()), ncallbacks, + nfound_edges); + } + } + if (e->has_callback + && fndecl_built_in_p (e->callee->decl, BUILT_IN_UNREACHABLE)) + for (cgraph_edge *cbe = e->first_callback_edge (); cbe; + cbe = cbe->next_callback_edge ()) + if (!fndecl_built_in_p (cbe->callee->decl, BUILT_IN_UNREACHABLE)) + error ("callback-carrying edge is pointing towards " + "__builtin_unreachable, but its callback edge %s -> %s " + "is not", + cbe->caller->name (), cbe->callee->name ()); } for (e = indirect_calls; e; e = e->next_callee) { @@ -4429,63 +4490,6 @@ cgraph_node::verify_node (void) for (e = callees; e; e = e->next_callee) { - if (e->callback && e->has_callback) - { - error ("edge has both callback and has_callback set"); - error_found = true; - } - - if (e->callback) - { - if (!e->get_callback_carrying_edge ()) - { - error ("callback edge %s->%s has no callback-carrying", - identifier_to_locale (e->caller->name ()), - identifier_to_locale (e->callee->name ())); - error_found = true; - } - } - - if (e->has_callback - && !callback_is_special_cased (e->callee->decl, e->call_stmt) - && !fndecl_built_in_p (e->callee->decl, BUILT_IN_UNREACHABLE)) - { - int ncallbacks = 0; - int nfound_edges = 0; - for (tree cb - = lookup_attribute ("callback_only", - DECL_ATTRIBUTES (e->callee->decl)); - cb; cb = lookup_attribute ("callback_only", TREE_CHAIN (cb)), - ncallbacks++) - ; - for (cgraph_edge *cbe = callees; cbe; cbe = cbe->next_callee) - { - if (cbe->callback && cbe->call_stmt == e->call_stmt - && cbe->lto_stmt_uid == e->lto_stmt_uid) - { - nfound_edges++; - } - } - if (ncallbacks < nfound_edges) - { - error ("callback edge %s->%s callback edge count mismatch, " - "expected at most %d, found %d", - identifier_to_locale (e->caller->name ()), - identifier_to_locale (e->callee->name ()), ncallbacks, - nfound_edges); - } - } - - if (e->has_callback - && fndecl_built_in_p (e->callee->decl, BUILT_IN_UNREACHABLE)) - for (cgraph_edge *cbe = e->first_callback_edge (); cbe; - cbe = cbe->next_callback_edge ()) - if (!fndecl_built_in_p (cbe->callee->decl, BUILT_IN_UNREACHABLE)) - error ("callback-carrying edge is pointing towards " - "__builtin_unreachable, but its callback edge %s -> %s " - "is not", - cbe->caller->name (), cbe->callee->name ()); - if (!e->aux && !e->speculative && !e->callback && !e->has_callback) { error ("edge %s->%s has no corresponding call_stmt",
