On 2026-02-19 08:59, Richard Biener wrote:
On Thu, Feb 19, 2026 at 2:50 PM Siddhesh Poyarekar <[email protected]> wrote:When checking for use of a dangling pointer, use_after_inval_p only checks to see if there's a direct path between the use and the exit block and that there's a clobber in the way. This is insufficient to prove dangling pointer access since the basic premise of the use being reachable from End Of Scope clobber is not tested. If there's a straight, potentially failing path from use to the exit block, add another test to make sure that the use block is actually reachable from the invalidating block before warning. gcc/ChangeLog: PR middle-end/110091 PR middle-end/124141 * gimple-ssa-warn-access.cc (can_reach_from): New function. (pass_waccess::use_after_inval_p): Use it. gcc/testsuite/ChangeLog: PR middle-end/110091 PR middle-end/124141 * c-c++-common/Wdangling-pointer-pr110091.c: New test. Signed-off-by: Siddhesh Poyarekar <[email protected]> --- Changes from v1: - Dropped stmt traversal since it's not needed for straight line code. - Added a post-dominator check in can_reach_from to shortcut traversal. Testing: - No new regressions in x86_64, i686 - Sqlite test case in BZ #124141 builds without spurious -Wdangling-pointers warnings - x86_64 bootstrap in progress. - This leaves only unresolved false negatives for -Wdangling-pointer. gcc/gimple-ssa-warn-access.cc | 53 +++++++++++++++++-- .../c-c++-common/Wdangling-pointer-pr110091.c | 40 ++++++++++++++ 2 files changed, 89 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/c-c++-common/Wdangling-pointer-pr110091.c diff --git a/gcc/gimple-ssa-warn-access.cc b/gcc/gimple-ssa-warn-access.cc index c8f10cae32f..c440c7761f9 100644 --- a/gcc/gimple-ssa-warn-access.cc +++ b/gcc/gimple-ssa-warn-access.cc @@ -3854,6 +3854,43 @@ pass_waccess::maybe_check_dealloc_call (gcall *call) } } +/* Return true if there is a path from FROM to TO. VISITED logs the basic + blocks that have been previously visited. */ + +static bool +can_reach_from (basic_block from, basic_block to, + hash_set<basic_block> &visited) +{ + edge_iterator ei; + edge e; + + /* Avoid walking through the CFG if we can. */ + if (dominated_by_p (CDI_POST_DOMINATORS, from, to)) + return true; + + /* Walk through each successor, focusing on unique, normal, forward + edges. */It's probably better to walk from 'to' to 'from' given there's at most one function entry but multiple "ends" of the CFG. The walk should stop at the common dominator of 'to' and 'from' then (there might not be a common post-dominator), which might of course be the function entry at worst. That is, when there is _no_ path from 'from' to 'to' then we want to avoid walking all paths to exit (or entry if you reverse) to prove that but prune it at a sensible point.
Ack, thanks, v3 coming up. Sid
