Re: RFC: (Unconditionally) enable -fno-strict-overflow for kernel builds

From: Konstantin Belousov <kostikbel_at_gmail.com>
Date: Sun, 1 Dec 2013 09:59:14 +0200
On Sat, Nov 30, 2013 at 04:33:17PM -0800, Adrian Chadd wrote:
> On 30 November 2013 15:25, Dimitry Andric <dim_at_freebsd.org> wrote:
> > On 30 Nov 2013, at 14:56, Konstantin Belousov <kostikbel_at_gmail.com> wrote:
> >> I propose to unconditionally add the switch  -fno-strict-overflow to the
> >> kernel compilation.  See the patch at the end of message for exact change
> >> proposed.
> >>
> >> What does it do. It disallows useless and counter-intuitive behaviour of
> >> the compiler(s) for the signed overflow. Basically, the issue is that
> >> the C standard left signed overflow as undefined to allow for different
> >> hardware implementation of signess to be used for signed arithmetic.
> >> De-facto, all architectures where FreeBSD works or have a chance to be
> >> ported, use two-complement signed integer representation, and developers
> >> intuition is right about it.
> >
> > I think this is quite a misrepresentation.  Any C compiler is free to do
> > whatever it wants whenever it encounters undefined behavior.  Some
> > behavior is undefined in the C standards, so compilers can do a better
> > job at optimization.
Sure. And we are free to call such compiler useless and moronic. E.g.
the standard explicitely marks any code implementing malloc-like
allocator and VM 'forbidden', since it cannot be done without calling
undefined behaviour. Should we stop writing the kernel or libc ?

> >
> > If the optimized code fails to do what the programmer thinks it does, it
> > is almost always the programmer's fault, excluding actual compiler bugs
> > (which are unavoidable, as all software has bugs).
> >
> > Basically, if you rely on undefined behavior, you are inventing your own
> > de facto language, which is *not* C.  That is fine with me, but let's
> > not pretend the FreeBSD kernel is written in C then. :-)
It is written in C, but no useful program can be written in the pure
standard C.  We must rely on the assumptions about underlying architecture,
and compiler must provide sane access to the features of the underlying
architecture to be useful.

Just to list a few,
- ILP32 or LP64;
- ABI;
- flat address space with arbitrary arithmetic on the data pointers;
- code as data, in the same address space (yes, we patch code at
  runtime);
- non-regular memory, both with additional side-effects when accessed,
  like register mappings (this cannot be modelled with volatile, think
  about e.g. address space switch caused by register access);
  and side-effect free memory with non-WC semantic.
This can be continued infinitely.

Why _sane_ implementation of signed arithmetic for 2-complement machine,
which is just one item in the list above, is tolerated to be crippled ?
Esp. since it causes (god forbids) *security* problems systematically ?

> 
> Are you able to have clang/llvm/gcc tell us where/when code is relying
> on undefined behaviour? So we can, like, fix them?
No, it is impossible. This is similar to the -fno-strict-aliasing.
Compiler is sometimes able to note that it cheat on you by applying
the undefined behaviour card, but this is not coded in the compiler
systematically. And, the biggest problem, routine changes in the
optimizer cause different places to become the victim. So the fact that
your code is not flagged today does not assure that it would be not
crippled tomorrow.

> 
> If there was a way to lint this stuff then yes, please lint it.
> 
> Otherwise we don't have the tools to know whether we're doing sane
> things or not.
> 
> (Same with things like strict aliasing..)
We do not have the tools, and indeed, same as with strict aliasing.


Received on Sun Dec 01 2013 - 06:59:25 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:40:44 UTC