On 7/3/25 9:46 AM, Jakub Jelinek wrote:
On Thu, Jul 03, 2025 at 09:35:49AM -0400, Jason Merrill wrote:
On 7/2/25 7:58 PM, Patrick Palka wrote:
Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK
for trunk?

-- >8 --

Here the flag -fno-delete-null-pointer-checks causes the trivial address
comparison in

    inline int a, b;
    static_assert(&a != &b);

to be rejected as non-constant because with the flag we can't assume
such weak symbols are non-NULL, which causes symtab/fold-const.cc to
punt on such comparisons.  Note this also affects -fsanitize=undefined
since it implies -fno-delete-null-pointer-checks.

Right, the underlying problem is that we use the one flag to mean two
things:

1) a static storage duration decl can live at address 0
2) do more careful checking for null pointers/lvalues (i.e. in
gimple_call_nonnull_result_p)

Both cases are related to checking for null, but they are different
situations and really shouldn't depend on the same flag.

Your patch seems wrong for #1 targets; on such a target 'a' might end up
allocated at address 0, so "&a != nullptr" is not decidable at compile time.

OTOH such targets are a small minority, and I suspect they already have
other C++ issues with e.g. a conversion to base not adjusting a null
pointer.

Jakub, what do you think?  It's been 9 years since you proposed a better fix
in the PR, but that hasn't happened yet.

I don't know what is best.

One possibility is only treat the implicitly set
-fno-delete-null-pointer-checks because of the sanitizers as if it wasn't
changed during constexpr evaluation.  Either always or perhaps just in
manifestly constant evaluation?
That will help most users where just -fsanitize=undefined breaks constexpr
stuff, but we still know that no variables actually will be at address 0.

Another case are targets with implicit -fno-delete-null-pointer-checks or
when users use that explicitly.  In that case one variable or function can
actually end up being at address 0, so am not sure if it is correct to
pretend at constant evaluation time something that is not true at runtime.
Though on the other side, pointers with NULL value in the standard mean that
there is no object at that location, so any kind of placing variables or
functions at that location will cause problems everywhere anyway.

A simple thing might be to adjust Patrick's patch to only set the flag

  if (!targetm.addr_space.zero_address_valid (ADDR_SPACE_GENERIC))

Jason

Reply via email to