https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105346
--- Comment #15 from Richard Biener <rguenth at gcc dot gnu.org> --- (In reply to Aldy Hernandez from comment #14) > (In reply to Richard Biener from comment #13) > > (In reply to Andrew Macleod from comment #11) > > > (In reply to Richard Biener from comment #6) > > > > > > > > > > > <bb 2> : > > > > bufp_2 = &buf; > > > > if (&buf != bufp_2) > > > > goto <bb 3>; [INV] > > > > else > > > > goto <bb 4>; [INV] > > > > > > > > <bb 3> : > > > > __builtin_free (bufp_2); > > > > > > > > and for the stmt __builtin_free (bufp_2) I'd like to ask if we know > > > > that bufp_2 is != &buf (I'd expect a 'true' answer). I think the > > > > relation oracle should be able to answer this but I can't find the > > > > appropriate API to use for this? > > > > > > - The relation oracle currently only works with ssa-names. > > > - Ranger also doesn't currently track that sort of symbolic equivalence > > > with > > > irange. > > > - the VRP passes have a pointer tracking mechanism as part of the dom > > > walk, > > > and the call to rvrp_folder::value_of_expr (bufp_2) would give us &buf. I > > > also think we also would fold the stmt in VRP. This could in theory be > > > extended to any pass doing a dom walk. however: > > > - I believe the upcoming prange extension for pointer ranges in stage 1 > > > will > > > make this happen naturally with rangers query system. range_of_stmt ( if > > > <..>) would then produce bool [0, 0]. I would also expect that prange > > > will > > > have an easy way to ask what its base/equivalence(s) are. > > > > OK, I was hoping I can so sth like > > > > range_simplify_expr (NE_EXPR, bufp_2, &buf, at_free_stmt); > > > > and then by means of the dominating if condition get a 'true'. Note the > > diagnostic pass is not within a DOM walk so all I can use is an ad-hoc > > query. I'm not looking to simplify the conditional itself as that won't > > help me with the current pass structure. > > Hmmm, I suppose we could track inequality as well as equality in prange. In > which case, we'd have: > > =========== BB 2 ============ > Imports: bufp_2 > Exports: bufp_2 > <bb 2> : > bufp_2 = &buf; > if (&buf != bufp_2) > goto <bb 3>; [INV] > else > goto <bb 4>; [INV] > > bufp_2 : [prange] char[20] * [1B, +INF] [PT &buf] > 2->3 (T) bufp_2 : [prange] char[20] * [1B, +INF] [PT !&buf] > 2->4 (F) bufp_2 : [prange] char[20] * [1B, +INF] [PT &buf] > > =========== BB 3 ============ > bufp_2 [prange] char[20] * [1B, +INF] [PT !&buf] > <bb 3> : > free (bufp_2); > > Notice that the range of bufp_2 at free() is: > > bufp_2 [prange] char[20] * [1B, +INF] [PT !&buf] > > Whereas range_of_expr of &buf (anywhere) would be: > > [prange] char[20] * [1B, +INF] [PT &buf] > > The intersection of both is the empty set / UNDEFINED, and should be able to > get that without dominance info. > > Would that help? > > Right now we're tracking equality, but it should be trivial to track > non-equality by adjusting the op1_range range-op entries. If it isn't possible to use ranger at the moment to resolve this at the point of the free() call I wouldn't bother. I think the correct solution is indeed to see the code is unreachable even at -O0 (similar as to what we now to for uninit analysis - run VN in analysis mode). I hope somebody will have the time to refactor all the various diagnostic passes to run from a single driver / CFG walk making it possible to do this. Alternatively use some function-local -Wanalyzer for the new fancy diagnostics or at least share code with it. If we think this case is important to fix I'd resort to pattern matching the conditional.