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.

Reply via email to