https://gcc.gnu.org/bugzilla/show_bug.cgi?id=54202
Martin Sebor <msebor at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |msebor at gcc dot gnu.org Component|c |middle-end --- Comment #7 from Martin Sebor <msebor at gcc dot gnu.org> --- All late warnings are susceptible to the same problem. The only way to tell from the IL that the free call isn't unconditional is from the CFG. While that could be used to issue either a "maybe" kind of a warning or a definitive one per function, it would just turn most instances of these warnings into the "maybe" kind. Which is how all warnings need to be viewed regardless. What might help more than rewording every warning to say "this may be undefined" is printing the chain of conditions that need to be satisfied in order for the warning to trigger. The infrastructure to do this is all there, it's just a matter of taking advantage of it: when a warning is issued, walk the shortest path from the entry to the basic block with the problem statement and print each conditional along the way. With that, we should end up with output very close to that of the analyzer: pr54202.c:17:9: warning: ‘free’ of ‘&shared_null’ which points to memory not on the heap [CWE-590] [-Wanalyzer-free-of-non-heap] 17 | free(d); | ^~~~~~~ ‘f’: events 1-3 | | 16 | if (d->refcount == 0) | | ^ | | | | | (1) following ‘true’ branch... | 17 | free(d); | | ~~~~~~~ | | | | | (2) ...to here | | (3) call to ‘free’ here | Removing basic block 5 f () { int _2; <bb 2> [local count: 1073741824]: _2 = shared_null.refcount; if (_2 == 0) <<< condition goto <bb 3>; [33.00%] else goto <bb 4>; [67.00%] <bb 3> [local count: 354334800]: free (&shared_null); [tail call] <<< conditional invalid call <bb 4> [local count: 1073741824]: return; }