On Mon, Sep 08, 2025 at 01:22:17PM +0100, Iain Sandoe wrote:
> For the testcase attached to the patch.
> 
> Do we consider that the addition to x is considered observable?

I don't think so, it isn't any kind of barrier for moving statements
around in either direction.
I think a non-const/pure call (with the exception of some builtins
where we know what they are doing) where we don't know what the body
does is (or should be, anything else would be a bug).
Because such a call can exit or say throw (unless marked nothrow and if
it doesn't need to run anything on throw locally, there wouldn't be
an edge for it) or loop forever and in all those cases, valid program
with UB after that point shouldn't observe the UB earlier.
So I think std::observable_checkpoint() needs to be handled as a barrier
for such movements.
const/pure calls (except for looping ones?) can be CSEd or removed entirely,
so don't act as such barriers.

> we can also have things like
> 
>  char *p = something;
> if (p == nullptr)
>   {
>      __builtin_printf (“bad pointer\n”);
>      __builtin_abort ();
>   }
> 
> ….
>   some UB….
> 
> which gets reduced to an unconditional print and abort.
> (I agree that this is allowed, but it is unexpected to many users)
> that kind of check can also be guarded.

I don't think we do such optimizations.
We do optimize
char *p = something;
*p = 1; // or read from it
if (p == nullptr) // into if (false)
or I think even
char *p = something;
int a = 0;
if (p == nullptr) // into if (false)
  a++;
*p = 1;
but shouldn't be doing it exactly if there is some call that could not
return or loop forever that would make the change observable.

        Jakub

Reply via email to