> On 9 Sep 2025, at 15:57, Jakub Jelinek <ja...@redhat.com> wrote:
>
> On Tue, Sep 09, 2025 at 03:30:07PM +0200, Michael Matz wrote:
>> But it would also be an invalid transformation of the compiler. So I
>> can't quite see the worry. The second check ("*p > 5") is conditional on
>> the first one:
>>
>> if (!p)
>> fail()
>> if (*p > 5)
>> fail2()
>>
>> The *p access would only be unconditional if fail() can fall-through.
>>
>> Two cases:
>> (a) the spec of contracts says that later contracts may depend on earlier
>> contracts to have succeeded (dependend contracts): the fail() must not
>> fall through, that would be an invalid implementation of contracts,
>> and the compiler removing the first !p check would be buggy
>> (b) the spec of contracts say that all of them are independend: then
>> fail() can fall through and the compiler may indeed remove the !p
>> check (if fail() itself doesn't have any interesting side-effects).
>> But then the author who wrote those two contracts independendly, where
>> in reality one depends on the other, was wrong.
>>
>> In both cases I don't see how an observably_checkpoint facility would
>> help.
>>
>> So, again, a precise spec of the supposed semantics of the builtin are
>> required. Up to now it seems fairly fuzzy and all cases I've seen in this
>> thread are trying to work around clear compiler or user bugs.
Unlike most of what we deal with - in this case we exactly concerned with
what happens under those the conditions that the program is wrong and
that suitable recovery, termination or even logging can be done then.
>>
>> So, what is or isn't guaranteed by the builtin?
>
> I think some pedantic readings of the standards suggest that if a program
> invokes UB, it is invalid as whole and can do anything even before the point
> of the UB. Which I think is true, but the compiler can't assume code
> invokes UB if it calls something it doesn't know anything about (because
> it could loop forever or exit or throw or setjmp out of the UB invoking
> function etc. and so never actually invoke the UB) before the UB is
> encountered.
> So any movement of UB across such points is a compiler bug, while moving it
> across some statements which certainly won't result in the later UB not
> being invoked should be fine.
This description matches my understanding of the paper [1]
I would say that if the paper is not clear, then it would be useful for me to
ask the author to weigh in with any additional clarifications.
Iain
[1] https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2025/p1494r5.html
>
> Jakub
>