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

--- Comment #18 from Andrew Macleod <amacleod at redhat dot com> ---
(In reply to rguent...@suse.de from comment #17)
> On Thu, 17 Nov 2022, amacleod at redhat dot com wrote:
> 
> > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78655
> > 
> > --- Comment #16 from Andrew Macleod <amacleod at redhat dot com> ---
> > (In reply to rguent...@suse.de from comment #15)
> > > On Wed, 16 Nov 2022, amacleod at redhat dot com wrote:
> > > 
> > > > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78655
> > > > 
> > > > Andrew Macleod <amacleod at redhat dot com> changed:
> > > > 
> > > >            What    |Removed                     |Added
> > > > ----------------------------------------------------------------------------
> > > >              Status|NEW                         |ASSIGNED
> > > >            Assignee|unassigned at gcc dot gnu.org      |amacleod at 
> > > > redhat dot com
> > > > 
> > > > --- Comment #14 from Andrew Macleod <amacleod at redhat dot com> ---
> > > > Created attachment 53910 [details]
> > > >   --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=53910&action=edit
> > > > patch to fix the problem
> > > > 
> > > > This patch fixes the PR, but exposes issues in other passes.  They 
> > > > introduce
> > > > undefined behaviour by hoisting POINTER_PLUS expressions into blocks in 
> > > > which
> > > > the operand is not known to be non-null.   (See PR 107709)
> > > > Until this can be audited fully, we put this patch on hold.
> > > 
> > > In fact the patch doesnt 'exploit the fact that the result of
> > > pointer addition can not be nullptr' but it exploits that if
> > > ptr + CST is performed then 'ptr' cannot be nullptr(?)
> > > 
> > 
> > GCC already exploits the title of the PR, when the code represents it with 
> > that
> > situation. 
> > The only case we don't get is if the code is reordered slightly as the 
> > testcase
> > in comment 4:
> > 
> > bool f(int* a)
> > {
> >   bool x = a == nullptr;
> >   a += 10;
> >   return x;
> > }
> > 
> > That testcase requires this patch.  
> > 
> > 
> > > That is, it assumes that there is a zero sized object at nullptr and
> > > thus the pointer increment to outside (but not one after it) invokes UB.
> > > 
> > > That's much more aggressive than optimizing
> > > 
> > >   ptr + 4 != nullptr
> > > 
> > > to true and I'm not sure the reasoning follows.  I think at 'nullptr'
> > > there is _no_ object and thus the restriction to pointer addition
> > > doesn't apply at all - if a pointer does not refer to an object then
> > > the rule that increment to outside of the object invokes UB doesn't 
> > > apply.
> > 
> > It implements comment 11, and comment 12 confirmed that 11 was accurate.
> > 
> > (1)
> > >> X + Y would be non-null if either X or Y is known to be non-null.
> > so if Y is non-zero, X + Y is non-zero.
> > (2)
> > >> If we know that X + Y is non-null via some mechanism (for example the 
> > >> result was dereferenced), then we know that X and Y are non-null.
> > X + Y is non-null based on (2)
> 
> But (2) is IMHO false for 'nullptr + 4', we know from (1) that the result
> is not nullptr but we don't know that _both_ are not null.  I don't see
> how computing 'nullptr + 4' invokes UB.  Hmm, one might read that
> into C17/6.5.6/8 "If both the pointer operand and the result point to
> elements of the same array object, or one past the last element of an 
> array object, the evaluation shall not produce an overflow; otherwise,
> the behavior is undefined" - here nullptr and nullptr + 4 do not
> point to elements of the same array object (nullptr doesn't point to
> any object), so 'otherwise' applies and the behavior is undefined?

FWIW, that would be my take...  NULL + anything would be UB.  Assuming of
course 0 is not an addressable value.

Reply via email to