Re: Gcc 8.1, -O2 optimisation build failure

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



...
    if (/* offset > sizeof ctrl.c32 || */ offset + len > sizeof ctrl.c32)
    {
        len = 0;
        printf("A: s->addr=%zu off=%zu len=0\n", s->addr, (size_t) offset);
    }
    else
    {
        const uint8_t* p = ((uint8_t *)&ctrl.c32) + offset;
printf("B: s->addr=%zu off=%zu poff=%ld\n", s->addr, (size_t) offset, p - ((uint8_t *)&ctrl.c32));
        memcpy(buf, p, len);
    }
}

int main()
{
  kdd_state s;
  s.buf[0]     = 0;
  s.length_req = 84;
  for (int i = 0; i <= 1000; i += 10)
    {
      s.addr = i;
      func(&s);
    }

  return 0;
}

Just compiling and executing normal 64bit:

$ gcc -Wall -Wextra -std=gnu99 -O2 t.c
$ ./a.out
A: s->addr=0 off=4294967092 len=0
A: s->addr=10 off=4294967102 len=0
A: s->addr=20 off=4294967112 len=0
A: s->addr=30 off=4294967122 len=0
A: s->addr=40 off=4294967132 len=0
A: s->addr=50 off=4294967142 len=0
A: s->addr=60 off=4294967152 len=0
A: s->addr=70 off=4294967162 len=0
A: s->addr=80 off=4294967172 len=0
A: s->addr=90 off=4294967182 len=0
A: s->addr=100 off=4294967192 len=0
A: s->addr=110 off=4294967202 len=0
B: s->addr=120 off=4294967212 poff=4294967212
Segmentation fault

IMO, the code is buggy as hell.


U.Mutlu wrote on 07/30/2018 02:59 PM:
I think there's a mismatch with decimal and hexadecimal values.

Write/simulate testcases for some border cases of offset, for example 0, 128,
256, 512, 768.


Wei Liu wrote on 07/30/2018 10:08 AM:
Hello,

We have a program which fails to build with gcc 8.1 -m32 -O2 (version
Debian 8.1.0-12). We couldn't figure out how the optimiser came up with
the idea that array bounds could become negative. Any help would be
appreciated. The attached code has been simplified from the original to
reproduce the issue.

The same code snippet builds find with 8.1 debug build and older
versions of gcc.

$ gcc  -m32 -march=i686 -std=gnu99 -Wall -O2   -Werror   -c -o t.o t.c
t.c: In function 'func':
t.c:41:9: error: 'memcpy' offset [-204, -717] is out of the bounds [0, 216]
of object 'ctrl' with type 'struct kdd_ctrl' [-Werror=array-bounds]
          memcpy(buf, ((uint8_t *)&ctrl.c32) + offset, len);
          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
t.c:27:21: note: 'ctrl' declared here
      struct kdd_ctrl ctrl;

<code>
#include <stdint.h>
#include <string.h>

struct kdd_ctrl_32 {
     uint8_t _[84];
};

struct kdd_ctrl_64 {
     uint8_t _[216];
};

struct kdd_ctrl {
     union {
         struct kdd_ctrl_32 c32;
         struct kdd_ctrl_64 c64;
     };
};

typedef struct {
     uint8_t buf[17 + 65536];
     uint32_t length_req;
     uint64_t addr;
} kdd_state;

void func(kdd_state *s)
{
     struct kdd_ctrl ctrl;
     uint8_t *buf = s->buf + 17 + 57;
     uint32_t len = s->length_req;
     uint64_t addr = s->addr;

     uint32_t offset = addr;

     /* 32-bit control-register space starts at 0x[2]cc, for 84 bytes */
     if (offset > 0x200)
         offset -= 0x200;
     offset -= 0xcc;
     if (offset > sizeof ctrl.c32 || offset + len > sizeof ctrl.c32) {
         len = 0;
     } else {
         memcpy(buf, ((uint8_t *)&ctrl.c32) + offset, len);
     }
}
</code>

Regards,
Wei.







[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux