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.

Reply via email to