https://gcc.gnu.org/bugzilla/show_bug.cgi?id=19831
--- Comment #20 from Richard Biener <rguenth at gcc dot gnu.org> ---
The original cases are all fixed but what remains is us failing to elide
void f ()
{
void *p = __builtin_malloc (1);
if (!p)
__builtin_abort ();
__builtin_free (p);
}
if that's even desirable. Note that we mark the abort() call as necessary
since it has side-effects which is contrary to this expectation. If you
think of, say,
extern int alloc_fails;
extern int alloc_success;
void f ()
{
void *p = __builtin_malloc (1);
if (!p)
alloc_fails++;
else
alloc_success++;
__builtin_free (p);
}
then the question is really whether we may assume that malloc does not
return NULL. We can then avoid marking 'p' necessary on NULL checks
on malloc returned pointers and upon DCEing the malloc/free pair
replace the def of 'p' with a non-zero constant.
Related would be to play similar things with realloc - replace
void *p = realloc (q, n);
free (p);
with
free (q);
and
void *p = realloc (q, n);
if (p == q)
not_copied++;
free (p);
with
void *p = q;
if (p == q)
not_copied++;
free(q);
so here we'd not only have to deal with != NULL but other pointer equality
checks.