Re: Gcc 8.1, -O2 optimisation build failure

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

 



On Mon, Jul 30, 2018 at 09:08:31AM +0100, Wei Liu wrote:
> 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;

Sorry for not mentioning this earlier, length_req(len) is bound within
[0, 65535] here. I deleted the bound check because it didn't affect how
the error is triggered.

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