https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86276

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |alias, missed-optimization
             Status|UNCONFIRMED                 |NEW
   Last reconfirmed|                            |2018-06-22
                 CC|                            |rguenth at gcc dot gnu.org
     Ever confirmed|0                           |1

--- Comment #1 from Richard Biener <rguenth at gcc dot gnu.org> ---
  <bb 2> [local count: 1073741825]:
  MEM[(struct _Vector_impl *)something_3(D)]._M_start = 0B;
  MEM[(struct _Vector_impl *)something_3(D)]._M_finish = 0B;
  MEM[(struct _Vector_impl *)something_3(D)]._M_end_of_storage = 0B;
  _26 = operator new (22);

  <bb 3> [local count: 354334802]:
  _23 = something_3(D)->D.15703._M_impl._M_start;
  if (_23 != 0B)


Confirmed.  So the reason we do not elide the NULL check is that GCC
thinks that the call to operator new may clobber the return slot
(well, generally clobber global memory).

For malloc() we assume it cannot but IIRC operator new () may be
overridden by the user and we could have (parts of) its implementation visible
to GCC which means we do have to assume it reads/clobbers global memory.

Note that we know that something_3(D) points to "local" memory but as you
say we see the pointer is returned and thus since points-to analysis is
flow-insensitive we have to assume it is already escaped at the call to
operator new.

I suppose we could handle returns specially but we have to beware of recursion
here and cannot handle it specially for IPA points-to.

So ... better points-to analysis to the rescue... (or somehow special-casing
operator new similar to malloc)

Reply via email to