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

            Bug ID: 89644
           Summary: False-positive -Warray-bounds diagnostic on strncpy
           Product: gcc
           Version: 8.3.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: samuel at sholland dot org
  Target Milestone: ---

GCC 8.3.0 warns for some calls to strncpy where n == sizeof(dest). It appears
to only happen if src is anything more complex than a char*, such as an array
or structure member. The warning claims an access to the character at n+1,
which is past the limit given to strncpy, so cannot happen.

In this example, "foo" and "bar" warn, but "ok1" and "ok2" do not:

# cat test.c 
typedef __SIZE_TYPE__ size_t;
char *strncpy(char *restrict dest, const char *restrict src, size_t n);

struct simple {
    char *s;
};

char foo(char *input[])
{
    char buffer[6] __attribute__ ((nonstring)) = {' ',' ',' ',' ',' ',' '};
    if (input && input[0])
        strncpy(buffer, input[0], sizeof(buffer));
    return buffer[2];
}

char bar(struct simple *input)
{
    char buffer[6] __attribute__ ((nonstring)) = {' ',' ',' ',' ',' ',' '};
    if (input && input->s)
        strncpy(buffer, input->s, sizeof(buffer));
    return buffer[2];
}

char ok1(struct simple *input)
{
    char buffer[6] __attribute__ ((nonstring)) = {' ',' ',' ',' ',' ',' '};
    if (input) {
        char *local = input->s;
        if (local)
            strncpy(buffer, local, sizeof(buffer));
    }
    return buffer[2];
}

char ok2(char *input)
{
    char buffer[6] __attribute__ ((nonstring)) = {' ',' ',' ',' ',' ',' '};
    if (input)
        strncpy(buffer, input, sizeof(buffer));
    return buffer[2];
}
# gcc -c -O2 -Wall test.c
test.c: In function 'foo':
test.c:12:9: warning: 'strncpy' forming offset 7 is out of the bounds [0, 6] of
object 'buffer' with type 'char[6]' [-Warray-bounds]                            
         strncpy(buffer, input[0], sizeof(buffer));
         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
test.c:10:10: note: 'buffer' declared here
     char buffer[6] __attribute__ ((nonstring)) = {' ',' ',' ',' ',' ',' '};
          ^~~~~~
test.c: In function 'bar':
test.c:20:9: warning: 'strncpy' forming offset 7 is out of the bounds [0, 6] of
object 'buffer' with type 'char[6]' [-Warray-bounds]                            
         strncpy(buffer, input->s, sizeof(buffer));
         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
test.c:18:10: note: 'buffer' declared here
     char buffer[6] __attribute__ ((nonstring)) = {' ',' ',' ',' ',' ',' '};
          ^~~~~~

Reply via email to