This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: Removal of useless null pointer checks


>>>>> "Jeffrey" == Jeffrey A Law <law@cygnus.com> writes:

    Jeffrey> But on the bad side, it may also be legitimate to have a
    Jeffrey> signal handler catch the dereference, do something
    Jeffrey> reasonable, then return.  I had not originally thought of
    Jeffrey> that case and I'll need to do some reading of the
    Jeffrey> standards to find out if what we're doing is kosher given
    Jeffrey> that scenario.  [ My gut tells me the catch, handle and
    Jeffrey> return is a valid thing to do, which would mean we can
    Jeffrey> not enable this opt by default...  Sigh...]

BTW, NULL is even more special in C++, than in C.  In C++, pointer
conversions sometimes change the value of the pointer in the presence
of multiple inheritance.  But, converting the NULL pointer also gives
you the NULL pointer.  So, trying to put an object using multiple
inheritance at address zero in an embedded system is just not going to
work out nicely.

But, as for your questions about standards, this is exactly the same
sort of situation as with -fstrict-aliasing.  The C9x draft (which is
the first I grabbed) clearly says that dereferencing NULL is
undefined, so your optimization is valid.  However, some users on some
systems may have done their own VM management via dereferencing NULL
pointers, or some such; that code could break with your change.  My
guess is that this invalid code is even less common that the invalid
aliasing code.

A similar situation arises with code like:

  void f(int *y)
  {
    int x = *y;
  }

Here, we can say that the value loaded is never used.  Therefore, we
can eliminate the load.  This is an important optimization, and one we
should definitely do by default.  (We already do it, in fact.)  In
C++, espcially, optimizations like this are essential to getting
high-performance out of template code.

But, like yours, this optimization would break programs trying to do
their own VM by depending on dereferencing invalid pointers.

My opinion is that such code is erroneous (i.e., yields undefined
behavior), and even more uncommon than code that violates the strict
aliasing rules.  So, I think your change should be on by default.

I guess it would be nice if we could switch it off, but any such
switch should really switch off the dead-load elimination in the
example given above, as well.

I believe the RMS-style proposal w.r.t. this optimization would be
something along the lines of: if you see `* ((int *) NULL) = 3' (in
other words, if you can tell that the dereferenced thing *is* in fact
NULL), then you should assume that the programmer meant that, and not
eliminate the dereference.  (I'm not suggesting that RMS would
actually advocate this propsoal; just providing what I think is the
analogue of the proposal made for alias analysis.)

--
Mark Mitchell                   mark@codesourcery.com
CodeSourcery, LLC               http://www.codesourcery.com


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]