[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 msebor at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89561

--- Comment #7 from Martin Sebor  ---
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.

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).

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.

[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 compile-time configuration

2019-03-04 Thread rguenth at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89561

Richard Biener  changed:

   What|Removed |Added

 Status|NEW |RESOLVED
 Resolution|--- |WONTFIX

--- Comment #5 from Richard Biener  ---
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.  The difficult thing is to detect what you want (from
inside generic analysis infrastructure).

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.

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).

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

2019-03-02 Thread egallager at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89561

Eric Gallager  changed:

   What|Removed |Added

 CC||egallager at gcc dot gnu.org

--- Comment #4 from Eric Gallager  ---
(In reply to bugsthecode from comment #0)
> 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.

More ideas: https://blog.regehr.org/archives/759 
(I still want to bring back the "play nethack on undefined behavior" option in
particular)

> 
> 
> 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 compile-time configuration

2019-03-02 Thread msebor at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89561

Martin Sebor  changed:

   What|Removed |Added

 Status|UNCONFIRMED |NEW
   Last reconfirmed||2019-03-02
 CC||msebor at gcc dot gnu.org
 Ever confirmed|0   |1
   Severity|normal  |enhancement

--- Comment #3 from Martin Sebor  ---
There have been suggestions along these lines in the past, partly to deal with
classes of false positives (by eliminating the errorneous code or replacing it
with __builtin_trap) and partly to avoid emitting code that could be
potentially dangerous and even exploitable.  Alexander Monakov gave a talk on
this topic at Cauldron 2018: https://www.youtube.com/watch?v=inDduOFEyew. 
There was strong support for some solution along these lines during the
discussion there, so I think it's fair to acknowledge this enhancement request.