Actually, it is very much aligned with what I want in C. In general I want to have pragma-based compilation modes for memory safety:
https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3211.pdf (Bjarne Stroustrup has a proposal for profiles in C++ which goes in similar direction I think) >From an implementation point of view, if we annotated all operations with UB in the front ends with a new __builtin_undefined() that - depending on configuration and/or mode - does: 0) nothing 1) expands to __builtin_unreachable() 2) expands to __builtin_trap() 3) expands to a __builtin_warning (as suggested before by Martin Sebor) that causes the backend to emit an error in a very late pass when the __builtin_warning has not been removed during optimization. Then this would solve all my problems related to UB. Martin Am Sonntag, dem 30.06.2024 um 08:33 +0200 schrieb Martin Uecker via Gcc: > Am Sonntag, dem 30.06.2024 um 05:03 +0200 schrieb Matthias Kretz: > > On Saturday, 29 June 2024 16:20:55 GMT+2 Martin Uecker wrote: > > > Am Samstag, dem 29.06.2024 um 08:50 -0500 schrieb Matthias Kretz via Gcc: > > > > I.e. once UB becomes IFNDR, the dreaded time-travel optimizations can't > > > > happen anymore. Instead precondition checks bubble up because otherwise > > > > the program is ill-formed. > > > > > > It is not clear to mean what you mean by this? > > > > It would help if you could point out what is unclear to you. I assume you > > know > > IFNDR? And I gave an example for the "bubbling up" of precondition checks > > directly above your quoted paragraph. > > I think I understood it now: You want to make UB be IFNDR so > that the compiler is allowed to diagnose it at translation > time in certain cases (although this would not generally be > required for IFNDR). > > > > > > Note that in C time-travel optimizations are already not allowed. > > > > Then, calling __builtin_unreachable is non-conforming for C? ... at least > > in > > the English sense of "this code is impossible to reach", which implies that > > the condition leading up to it must be 'false', allowing time-travel > > optimization. Or how would C define 'unreachable'? > > __builtin_uneachable is an extension, it can do whatever it wants. > > But note that compilers do not seem to eliminate the control flow path > leading to it: > > > https://godbolt.org/z/coq9Yra1j > > So even if it is defined in terms of C's UB, these implementations > would still be conforming to C. > > > > > > But I am not sure how this is relevant here as this affects only > > > observable behavior and the only case where GCC does not seem to > > > already conform to this is volatile. > > > > Now you lost me. > > Consider the following example: > > int f(int x) > { > int r = 0; > if (x < 10) > r = 1; > if (x < 10) > __builtin_unreachable(); > return r; > } > > But removing the store to 'r' here as GCC does: > > https://godbolt.org/z/h7qqrGsbz > > can simply be justified by the "as if" principle as > any other optimization, it does not need to rely on a weird > intepretation that the UB from __builin_unreachable() travels > back in time. > > > > > > Of course, C++ may be different but I suspect that some of the > > > discussion is confusing compiler bugs with time-travel: > > > > "some of the discussion" is referring to what? > > To discussions inside WG21 that seems to believe that it > is important that compilers can do time-travel optimizations, > when this is actually not the case. > > > > > > > Again, I don't believe this would be conforming to the C++ standard. > > > > But I > > > > believe it's a very interesting mode to add as a compiler flag. > > > > > > > > -fharden=0 (default) > > > > -fharden=1 (make UB ill-formed or unreachable) > > > > -fharden=2 (make UB ill-formed or trap) > > > > > > > > If there's interest I'd be willing to look into a patch to libstdc++, > > > > building upon the above sketch as a starting point. Ultimately, if this > > > > becomes a viable build mode, I'd like to have a replacement for the > > > > [[gnu::error("")]] hack with a dedicated builtin. > > > > > > -fharden should never turn this into unreachable. > > > > Well, if the default is 'unreachable' and the next step is 'ill-formed or > > unreachable' it's a step up. But I'm all for a better name. > > I think it is a good idea. The compiler can optionally treat UB as > a translation time error. We discussed similar ideas in the past > in WG14. But this will only work for very specific instances of UB > under certain conditions. > > > > > > IMHO the FEs should insert the conditional traps when requested to > > > and the middle end could then treat it as UB and more freely > > > decide what to do. > > > > Right I was thinking of turning my library-solution hack into a builtin (if > > it > > shows potential). The behavior of which then depends on a compiler flag. > > Then > > both library and language UB could invoke that builtin. E.g. > > 'operator+(int, > > int)' would add '__check_precondition(not __builtin_add_overflow_p(a, b, > > a));' > > With my proposed '-fharden=1 -O2' you'd then get a compilation error on > > '0x7fff'ffff + 1', but no code size increase for all other additions. With > > '-fharden=2 -O2' the 'lea' would turn into an actual 'add' instruction with > > subsequent 'jo' to 'ud2' (on x86). > > Yes, I fully agree with this. > > > > > Also IMHO this should be split up from > > > UBsan which has specific semantics and upstream dependencies > > > which are are not always ideal. (But UBSan could share the > > > same infrastructure) > > > > I'm not sure what you're thinking of here. UBsan detects UB at runtime > > whereas > > my '-fharden=1' proposal is about flagging UB as ill-formed on > > compile-time. > > So UBsan is a more verbose '-fharden=2' then? > > Yes, I was talking about the -fharden=2 case. In principle UBSan > with traps instead of diagnostics would do this. In practice, > I think we need something which is not tied to UBSan. > > Martin > > > > > > - Matthias > > >