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.