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

            Bug ID: 86764
           Summary: missing -Wstringop-truncation writing to the last
                    array member
           Product: gcc
           Version: 9.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: msebor at gcc dot gnu.org
  Target Milestone: ---

As reported in https://lkml.org/lkml/2018/7/30/605, GCC fails to issue
-Wstringop-truncation in the last call to strncpy, yet it issues a
-Wstringop-overflow for the same call when the size is increased by one.  Both
warnings should be issued consistently.

$ cat c.c && gcc -O2 -S -Wall c.c
#include <string.h>

struct logical_input {
    union {
        struct {    /* valid when type == INPUT_TYPE_KBD */
            /* strings can be non null-terminated */
            char press_str[sizeof(void *) + sizeof(int)] /*
__attribute__((nonstring)) to tell gcc this is alright */;
            char repeat_str[sizeof(void *) + sizeof(int)];
            char release_str[sizeof(void *) + sizeof(int)];
        } kbd;
    } u;
};

void panel_bind_key(struct logical_input *key, const char *press,
                     const char *repeat,
                     const char *release)
{
    strncpy(key->u.kbd.press_str, press, sizeof(key->u.kbd.press_str));
    strncpy(key->u.kbd.repeat_str, repeat, sizeof(key->u.kbd.repeat_str));
    strncpy(key->u.kbd.release_str, release, sizeof(key->u.kbd.release_str));
}

void foo (struct logical_input *key, const char *press,
          const char *repeat,
          const char *release)
{
    strncpy(key->u.kbd.press_str, press, sizeof(key->u.kbd.press_str) + 1);
    strncpy(key->u.kbd.repeat_str, repeat, sizeof(key->u.kbd.repeat_str) + 1);
    strncpy(key->u.kbd.release_str, release, sizeof(key->u.kbd.release_str) +
1);
}

In file included from /usr/include/string.h:630,
                 from c.c:1:
c.c: In function ‘panel_bind_key’:
c.c:19:5: warning: ‘__builtin_strncpy’ specified bound 12 equals destination
size [-Wstringop-truncation]
     strncpy(key->u.kbd.press_str, press, sizeof(key->u.kbd.press_str));
     ^~~~~~~
c.c:20:5: warning: ‘__builtin_strncpy’ specified bound 12 equals destination
size [-Wstringop-truncation]
     strncpy(key->u.kbd.repeat_str, repeat, sizeof(key->u.kbd.repeat_str));
     ^~~~~~~
c.c: In function ‘foo’:
c.c:28:5: warning: ‘__builtin_strncpy’ writing 13 bytes into a region of size
12 overflows the destination [-Wstringop-overflow=]
     strncpy(key->u.kbd.press_str, press, sizeof(key->u.kbd.press_str) + 1);
     ^~~~~~~
c.c:29:5: warning: ‘__builtin_strncpy’ writing 13 bytes into a region of size
12 overflows the destination [-Wstringop-overflow=]
     strncpy(key->u.kbd.repeat_str, repeat, sizeof(key->u.kbd.repeat_str) + 1);
     ^~~~~~~
c.c:30:5: warning: ‘__builtin_strncpy’ writing 13 bytes into a region of size
12 overflows the destination [-Wstringop-overflow=]
     strncpy(key->u.kbd.release_str, release, sizeof(key->u.kbd.release_str) +
1);
     ^~~~~~~

Reply via email to