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

            Bug ID: 87028
           Summary: false positive -Wstringop-truncation strncpy with
                    global variable source string
           Product: gcc
           Version: 9.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: anon63 at protonmail dot com
  Target Milestone: ---

Hi, 

Just builded latest gcc (GCC) 9.0.0 20180820 (experimental) commit 316828699
on Debian Linux 4.17.0-1-amd64 with gcc (Debian 8.2.0-3) 8.2.0 and ldd (Debian
GLIBC 2.27-5) 2.27

I know there are already several -Wstringop-truncation false positive related
threads but I'm not sure if this particular behaviour : emit warning when
source string is global variable and does not emit warning when source string
is local variable, has already been addressed. 

////////////////////////////////////////////////////////
////////////////////////////////////////////////////////

GLOBAL VARIABLE SOURCE STRING => WARNING

$ cat a.c && gcc -O2 -Wall -Wextra -S a.c
char *strncpy (char *, const char *, __SIZE_TYPE__);

struct S {
    char dest[5];
};

const char src[] = "1234567890";
void function(struct S *s)
{
    strncpy(s->dest,src,sizeof(s->dest)-1);
    s->dest[sizeof(s->dest)-1]='\0';
}
////////////////////////////////////////////////////////
a.c: In function ‘function’:
a.c:12:5: warning: ‘strncpy’ output truncated copying 4 bytes from a string of
length 10 [-Wstringop-truncation]
     strncpy(s->dest,src,sizeof(s->dest)-1);
     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


////////////////////////////////////////////////////////
////////////////////////////////////////////////////////

LOCAL VARIABLE SOURCE STRING => NO WARNING

$ cat a.c && gcc -O2 -Wall -Wextra -S a.c
char *strncpy (char *, const char *, __SIZE_TYPE__);

struct S {
    char dest[5];
};

void function(struct S *s)
{
    const char src[] = "1234567890";
    strncpy(s->dest,src,sizeof(s->dest)-1);
    s->dest[sizeof(s->dest)-1]='\0';
}

////////////////////////////////////////////////////////
////////////////////////////////////////////////////////

CONSTANT SOURCE STRING => WARNING

$ cat a.c && gcc -O2 -Wall -Wextra -S a.c
////////////////////////////////////////////////////////
char *strncpy (char *, const char *, __SIZE_TYPE__);

struct S {
    char dest[5];
};

void function(struct S *s)
{
    strncpy(s->dest,"1234567890",sizeof(s->dest)-1);
    s->dest[sizeof(s->dest)-1]='\0';
}
////////////////////////////////////////////////////////
a.c: In function ‘function’:
a.c:11:5: warning: ‘strncpy’ output truncated copying 4 bytes from a string of
length 10 [-Wstringop-truncation]
11 |     strncpy(s->dest,"1234567890",sizeof(s->dest)-1);


////////////////////////////////////////////////////////
////////////////////////////////////////////////////////

This last case, constant source string, seems to be duplicate
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84474 but I would like to know if
there are any news/recommendations about this problem.

Lots of codebases can't be compiled with -Werror flag now.

I see lots of people, mechanically changing strncpy for memcpy. Other people do
the transformation strncpy of size n => strncpy of size n-1 + '\0' at index
n-1.  Without success for me in the "global variable" case.
What would be the recommended way with the examples above ?

Cheers, 

A.

Reply via email to