> On 8 Sep 2025, at 15:05, Jakub Jelinek <ja...@redhat.com> wrote:
> 
> On Mon, Sep 08, 2025 at 02:54:18PM +0100, Iain Sandoe wrote:
>> (for pre-conditions) they  lower to a series of statements like
>> if (some check fails)
>>   handle the contract violation
>> if (some other check fails)
>>   handle the contract violation
>> …
>> 
>>> The only "example" is for in(p) in (*p > 5) where the contract
>>> *p > 5 would "elide" the 'p' one.  Whatever "eliding" means here.
>> 
>> So, IIRC, the argument was
>> 
>> *p > 5 would be UB for p == nullptr
>> 
>> therefore an earlier  check for p == nulptr can be removed, because
>> that case cannot happen in a well-formed program.
>> 
>> However, that prevents the contract check from doing its job (diagnosing
>> the bad case).
>> 
>> I cannot say that GCC would make that optimisation - it was, in general,
>> quite hard to find cases that time-traveled.
> 
> If handle the contract violation is just __builtin_unreachable () or
> it isn't evaluated at all and handled more like [[assume ()]] for the ignore
> semantics, then I don't see a problem with that kind of time travel.
> If handle the contract violation is a function call which gcc knows nothing
> about (including calling ::handle_contract_violation), I don't see how gcc
> could optimize that (unless it is buggy), exactly because it needs to count
> with the function exiting or looping forever or doing thread synchronization
> and other threads observe the state etc.

The contract violation handling depends on the chosen contract semantic
 it can:

  * terminate (in an implementation-defined way - so could trap or abort 
equally).
  * do some diagnostic output or logging and then terminate (etc).
  * do some diagnostic output or logging and then continue.

I completely agree with Richi that, in the given case, continuation means
that the program will segv.  I guess the question is whether the violation
handler logging a cause before that is considered a useful functionality.

Iain
 
> 
>       Jakub
> 

Reply via email to