https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104215
--- Comment #6 from rguenther at suse dot de <rguenther at suse dot de> --- On Tue, 25 Jan 2022, msebor at gcc dot gnu.org wrote: > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104215 > > --- Comment #5 from Martin Sebor <msebor at gcc dot gnu.org> --- > To "use" means to evaluate. The strict C semantics are that the realloc() > argument becomes indeterminate after the function has returned non-null, > whether or not the returned pointer is the same as the argument. The argument > is only safe to use after realloc() has returned null. In other words, > strictly conforming programs must treat every successful call to realloc() as > if it freed the original object. > > The warning is based on these strict semantics. It handles the realloc > failure > case, and it tries to accommodate the use case of detecting whether realloc() > has moved the block to a different address by only warning on equality > expressions involving the original argument at level 3. > > The warning cannot very well avoid triggering on this case if we want it to > continue to work as designed (I of course do). The solution I'd like to see > is > the forwprop pass checking for the uses of the pointers in the propagated > condition in deallocation calls and suppressing the warning for the propagated > condition statement by calling suppress_warning(). This could be made > reliable > by having forwprop and the warning share the same code (a common function to > do > the same analysis to determine whether to suppress the warning in forwprop or > whether to trigger in gimple-ssa-warn-access). Note it's not only forwprop but any pass that eventually uses fold_stmt or moves code (sink for example) thereby honoring dataflow which does not represent that realloc() "clobbers" its first argument (on the !NULL return path). So I don't think it's feasible to fix this which means I don't think this warning will do any good to people. For example I see in a kernel build [ 59s] In file included from help.c:12: [ 59s] In function 'xrealloc', [ 59s] inlined from 'add_cmdname' at help.c:24:2: [ 59s] subcmd-util.h:56:23: error: pointer may be used after 'realloc' [-Werror=use-after-free] [ 59s] 56 | ret = realloc(ptr, size); [ 59s] | ^~~~~~~~~~~~~~~~~~ [ 59s] subcmd-util.h:52:21: note: call to 'realloc' here [ 59s] 52 | void *ret = realloc(ptr, size); [ 59s] | ^~~~~~~~~~~~~~~~~~ [ 59s] subcmd-util.h:58:31: error: pointer may be used after 'realloc' [-Werror=use-after-free] [ 59s] 58 | ret = realloc(ptr, 1); [ 59s] | ^~~~~~~~~~~~~~~ [ 59s] subcmd-util.h:52:21: note: call to 'realloc' here [ 59s] 52 | void *ret = realloc(ptr, size); [ 59s] | ^~~~~~~~~~~~~~~~~~ which eventually looks like static inline void *xrealloc(void *ptr, size_t size) { void *ret = realloc(ptr, size); if (!ret && !size) ret = realloc(ptr, 1); if (!ret) { ret = realloc(ptr, size); if (!ret && !size) ret = realloc(ptr, 1); if (!ret) die("Out of memory, realloc failed"); } return ret; } so it seems there'll be false positives even with the strict reading of the standard.