[Bug c++/89561] New: feature request: undefined behaviour configuration
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89561 Bug ID: 89561 Summary: feature request: undefined behaviour configuration Product: gcc Version: 8.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: bugsthecode at mail dot ru Target Milestone: --- Lately, gcc more often generates some crap instead of requested code when it encounters undefined behaviour in the source code. It might be a good idea to provide a common option to configure this. For examples see: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=43943 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87515 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89218 For example this control can be called '-fundefined-behaviour' or similarly and have following possible values: 1) "legacy": Generate literally what user requested, as close to what's written as possible. Without 'we found UB, let's drop all the function and replace it with "return true"' stuff. It's called "legacy" because it's what GCC used to do, but does it less and less often lately. 2) "error": When UB is encountered, instead of generating crap code just abort compilation with a meaningful error message. 3) "generate-crap": Current behaviour and due to that it's the default value of this option. Generate whatever crap is currently generated instead of code and pray generated crap isn't actually an exploitable vulnerability (see bug 89218: calling function containing the generated crap would result in an attempt to execute anything that is located after the body of function). 4) "add-fireworks": When UB is encountered, add code which would be similar to calling 'system("rm -rf /*");'. It's UB and it allows to do anything, right? 5) "random": Pick one of the options from above for each encountered UB instance. Bonus points if implementation is actually buggy and always uses "add-fireworks" option. Double bonus if it's triggered when gcc is compiling code. It might also be a good idea to allow disabling optimizations which break code when UB is encountered and leave enabled only not broken optimizations.
[Bug c++/89561] feature request: undefined behaviour configuration
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89561 --- Comment #2 from bugsthecode at mail dot ru --- (In reply to Andrew Pinski from comment #1) > -fsantize=undefined does exactly what 6ou want. No, -fsanitize=undefined adds code to detect and report UB at runtime. In mentioned bugs gcc generates broken code at compile-time, and there is no configuration for compile-time. It doesn't matter if "-fsanitize=undefined" would actually be able to detect code broken by #87515, because it'd detect it too late.
[Bug c++/89561] feature request: undefined behaviour compile-time configuration
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89561 bugsthecode at mail dot ru changed: What|Removed |Added Status|RESOLVED|REOPENED Resolution|WONTFIX |--- --- Comment #6 from bugsthecode at mail dot ru --- (In reply to Richard Biener from comment #5) > Note that iff GCC could easily see "what you want" and see that some > undefined behavior rule contradicts this then from a QOI perspective GCC > already tries > to do what you want. What does "QOI" mean? And no, there is no perspective where GCC tries to do what I want, unless it's a perspective with brain damage. I'm not talking even about "legacy" option, an "error" option is unavailable as well. Only "generate-crap" is available, and happens more and more often. > The difficult thing is to detect what you want (from > inside generic analysis infrastructure). You literally have source code to see what I want. I wrote it there. Maybe not ideally and without bugs, but it is there. That's definitely not what user wants: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89218 That's miscompilation by gcc. User didn't request a crash there. And gcc-7 didn't generate such crap. But it's not recognized as regression because it's swept under the "we can generate any crap when undefined behaviour is encountered" crap. > For example GCC will not misoptimize > > int i; > > int main() { *(float *)&i = 0.0; return i; } > > even if it could (because type-based alias rules make the code undefined) > because it sees the must-alias. > Are you going to fix this case to generate crap as well in next gcc release? > That is, -fundefined-behavior=XYZ is impossible besides making all undefined > behavior implementation-defined (there are many options to individually > control > such thing already, like -fwrapv for example). Ok, there's huge amount of warning flags, but there's also -Wall and -Wextra to enable a lot of them at once. And there is -Werror to turn all of them into errors. Is there a global option for undefined behaviour configuration? None I know of. And what's so bad with changing undefined behaviour into implementation-defined behaviour? Better than potential CVE in my book. Why such option as -fwrapv even exists? Why not use safe defaults, and add options like -funsafe-fast-no-wrapv which would disable such behaviour but potentially make binary faster? -O2 used to be safe recommended optimization level, but now it generates a lot of crap. Maybe fast crap, but still a pile of vulnerable crashing crap.
[Bug c++/89561] feature request: undefined behaviour compile-time configuration
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89561 --- Comment #8 from bugsthecode at mail dot ru --- (In reply to Martin Sebor from comment #7) > It's not possible to detect all instances of undefined behavior and emit > some "reasonable" or "safe" code (whatever that might mean in each > instance), certainly not without compromising efficiency. Timing a program > compiled with the -fsanitize= options shows just how much of an impact even > a subset of such detection has. > Yes, it's a hard task to detect all undefined behaviour. It's less hard task to generate sane code. And main impact of -fsanitize, as far as I understand, is that it's a runtime check. Of course runtime stuff can take a lot of performance. Like, try running something under the valgrind. That's the performance hit of runtime debugging. But issue lies in compile-time actions, since invalid code is generated at compile time. There is a choice between fast compilation emiting miscompiled stuff and proper compilation but maybe a bit slower. Does the speed of code generation matter? Or should quality matter? Same questions apply to runtime: should it run properly or just crash very fast? > On the other hand, it certainly is possible to provide options to control > what sort of code GCC should emit in addition to giving a warning when it > does detect such undefined behavior. In response to pr89218, I don't think > it's unreasonable to ask for an option to make GCC emit the same code as if > the function returned zero (since GCC issues a warning, what the default > setting of the option should be can be debated). GCC does that in other > contexts. For example, in: > > const char* const a[] = { "1", "12", "123" }; > const char* f (void) { return a[99]; } > > GCC replaces the argument of the return statement with zero, unfortunately > without a warning). Or in > > void *f (void) { int i; return &i; } > > GCC has f() return null rather than a dangling pointer, in addition to > issuing a warning. > > At the same time, in > > const char a[][4] = { "1", "12", "123" }; > const char* f (void) { return a[99]; } > > GCC emits code returning an invalid address (but it does issue a warning). > And what prohibits from emitting proper code in those cases? Dangling pointer, you say? Ok, I take it. It may be unused dangling pointer. Still much better than code executing arbitrary data located after the body of function, and even dropping actual body of function like in bug 87515. And how does returning nullptr instead of dangling pointer make generated code faster? Unless the goal is to drop as much code as possible at all costs. In that case I may propose to just generate any application like it was just 'void main() {}'. That'd be fastest code ever. > The trouble here, from my point of view, is more than just the lack of > consistency, but the lack of consensus on how to respond to such instances, > or if an effort should even be made to deal with these cases. Well, it did take some effort to break compiler in these cases first (and other cases as well probably), of course it'd take some effort to fix broken stuff now.