[Bug c++/89561] feature request: undefined behaviour compile-time configuration

2019-03-04 Thread bugsthecode at mail dot ru
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  }
> 
> 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.

[Bug c++/89561] feature request: undefined behaviour compile-time configuration

2019-03-04 Thread bugsthecode at mail dot ru
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 *) = 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 configuration

2019-03-02 Thread bugsthecode at mail dot ru
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] New: feature request: undefined behaviour configuration

2019-03-02 Thread bugsthecode at mail dot ru
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.