[Bug c/87028] New: false positive -Wstringop-truncation strncpy with global variable source string
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.
[Bug c/87028] false positive -Wstringop-truncation strncpy with global variable source string
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87028 --- Comment #3 from anon63 --- Dear Martin, Thank you for the explanations. Do you have any advice of what we should do before this eventual deferring of the strncpy -> memcpy folding in a future gcc release ? In particular, can you elaborate just a bit on what you said in https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84474 : "strncpy is being misused and strcpy (or other string functions if strcpy is not acceptable) would be more appropriate" I am searching for a strategic way of dealing with these false positive when lots of codebases are going to be compiled by default with gcc-8. (as you know, gcc 8 is the default on debian sid since end of July 2018 but people are coming back from holidays now :) ) For example, here https://lkml.org/lkml/2018/2/17/198, a guy suggests to use -Wno-stringop-truncation until gcc deals true/false positive correctly or here https://stackoverflow.com/questions/50198319/gcc-8-wstringop-truncation-what-is-the-good-practice the pragma diagnostic solution, the manual strncmp->memcmp solution... Best,
[Bug c/87028] false positive -Wstringop-truncation strncpy with global variable source string
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87028 --- Comment #6 from anon63 --- Dear Martin, Thank you for all these details. Well, re-reading what I wrote in Comment 0, I think I should explain what I meant by "Lots of codebases can't be compiled with -Werror flag now.". Since the gcc-7 -> gcc-8 transition on my laptop, I see a lot of these warnings (and a Google search on -Wstringop-truncation gives lots of results for 2018) but I'm working on a project where security matters (IoT OS) and we use -Werror on Travis-CI but that does not reflect accurately the common case. My assumption "Lots of codebases can't be compiled with -Werror flag now." was not "I have seen lots of codebases where the build fails" but rather "It will not be easy for those projects to use more strict CFLAGS in a next future". I am not a distribution packages maintainer so I am probably not the right person for an informed point of view. Anyway, thanks a lot for your time. As I was more interested by the global/local variable case than by the constant case, I think I will go for something strange like this : char *strncpy (char *, const char *, __SIZE_TYPE__); struct S { char dest[5]; }; const char src[] = "1234567890"; void function(struct S *s) { const char *src2=src;// this indirection avoids a gcc >= 8 strncpy(s->dest,src2,sizeof(s->dest)-1); // false positive stringop-truncation warning s->dest[sizeof(s->dest)-1]='\0'; } and the indirection doesn't change the assembly : gcc -O2 -Wall -Wextra -c a.c && objdump -d a.o a.o: file format elf64-x86-64 Disassembly of section .text: : 0: c7 07 31 32 33 34 movl $0x34333231,(%rdi) 6: c6 47 04 00 movb $0x0,0x4(%rdi) a: c3 retq Best,