bitfields: one more hack and a "-Wgcc-compat" switch
commitd242706f3b739bcb00de1d970a01a319db6ad77d
authorgrischka <grischka>
Tue, 9 May 2017 16:10:02 +0000 (9 18:10 +0200)
committergrischka <grischka>
Tue, 9 May 2017 16:10:02 +0000 (9 18:10 +0200)
tree1de0c3a07502e60fde9a8c63814e3662e5e062dc
parent3f5fd305afbe63c6bc4af5e06b315f4fce60b694
bitfields: one more hack and a "-Wgcc-compat" switch

    bit_pos + bit_size > type_size * 8

must NEVER happen because the code generator can read/write
only the basic integral types.

Warn if tcc has to break GCC compatibility for that reason
and if -Wgcc-compat is given.

Example:
    struct __attribute__((packed)) _s
    {
        unsigned int x  : 12;
        unsigned char y :  7;
        unsigned int z  : 28;
    };

Expected (GCC) layout (sizeof struct = 6)
.xxxxxxxx.xxxxyyyy.yyyzzzzz.zzzzzzzz.zzzzzzzz.zzzzzzz0.

But we cannot read/write 'char y'from 2 bytes in memory.
So we have to adjust:
.xxxxxxxx.xxxx0000.yyyyyyyz.zzzzzzzz.zzzzzzzz.zzzzzzzz.zzz00000

Now 'int z' cannot be accessed from 5 bytes.  So we arrive
at this (sizeof struct = 7):
.xxxxxxxx.xxxx0000.yyyyyyy0.zzzzzzzz.zzzzzzzz.zzzzzzzz.zzzz0000

Otherwise the bitfield load/store generator needs to be
changed to allow byte-wise accesses.

Also we may touch memory past the struct in some cases
currently.  The patch adds a warning for that too.

   0: 55                    push   %ebp
   1: 89 e5                 mov    %esp,%ebp
   3: 81 ec 04 00 00 00     sub    $0x4,%esp
   9: 90                    nop

    struct __attribute__((packed)) { unsigned x : 5; } b = {0} ;

   a: 8b 45 ff              mov    -0x1(%ebp),%eax
   d: 83 e0 e0              and    $0xffffffe0,%eax
  10: 89 45 ff              mov    %eax,-0x1(%ebp)

This touches -0x1 ... +0x3(%ebp), hence 3 bytes beyond
stack space.  Since the data is not changed, nothing
else happens here.
libtcc.c
tcc.h
tccgen.c