https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86914

            Bug ID: 86914
           Summary: gcc 8.1 -O2 generates wrong code with strlen() of
                    pointers within one-element arrays of structures
           Product: gcc
           Version: unknown
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: even.rouault at spatialys dot com
  Target Milestone: ---

The following code
{{{
#include <string.h>

struct s
{
    int i;
    char c[1];
};

size_t foo(struct s* p)
{
    return strlen(p->c+1);
}
}}}

compiled with gcc 8.1 -O2 generates the following code
{{{
0000000000000000 <foo>:
   0:   31 c0                   xor    %eax,%eax
   2:   c3                      retq   
}}}

returning 0

Previous gcc versions generate the "correct" code
{{{
0000000000000000 <foo>:
   0:   48 83 c7 05             add    $0x5,%rdi
   4:   e9 00 00 00 00          jmpq   9 <foo+0x9>      5: R_X86_64_PC32       
strlen-0x4
}}}

According to https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html , """Although
using one-element arrays this way is discouraged, GCC handles accesses to
trailing one-element array members analogously to zero-length arrays. """

If modifying c[1] to be c[0], gcc 8.1 -O2 generates the correct code. If
changing strlen(p->c+1) to strlen(p->c), the correct code is although generated

So it looks to be a too agressive optimization.

Reply via email to