https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70988
Bug ID: 70988 Summary: missing buffer overflow warning on chained strcat calls Product: gcc Version: 7.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: middle-end Assignee: unassigned at gcc dot gnu.org Reporter: msebor at gcc dot gnu.org Target Milestone: --- In the program below, all of f1 through f4 clearly write past the end of the destination buffer. However, only f1 and f2 cause a warning about the overflow. f3 and f4 do not. Since chaining calls to strcat (or strcpy followed by strcat) is not an uncommon idiom, it might be worth checking for and diagnosing buffer overflow in it at compile time. I suspect that doing so would also improve the generated code since in the absence of overflow chained calls like 'strcat (strcat (a, "abc"), "def")' would be merged into a single call to __builtin_memcpy. $ cat t.c && /build/gcc-6.1.0/gcc/xgcc -B/build/gcc-6.1.0/gcc -D_FORTIFY_SOURCE=1 -O2 -Wall -Wextra -Wpedantic t.c #include <string.h> #define NOINLINE __attribute__ ((noclone, noinline)) void NOINLINE f0 (char *s) { __builtin_puts (s); } void NOINLINE f1 (void) { char a [4]; strcat (a, "abcdef"); f0 (a); } void NOINLINE f2 (void) { char a [4] = ""; strcat (a, "abcdef"); f0 (a); } void NOINLINE f3 (void) { char a [4]; strcat (strcat (a, "abc"), "def"); f0 (a); } void NOINLINE f4 (void) { char a [4] = ""; strcat (strcat (a, "abc"), "def"); f0 (a); } int main () { f1 (); f2 (); f3 (); f4 (); } In file included from /usr/include/string.h:638:0, from t.c:1: In function ‘strcat’, inlined from ‘f1’ at t.c:10:3: /usr/include/bits/string3.h:142:10: warning: call to __builtin___strcat_chk will always overflow destination buffer return __builtin___strcat_chk (__dest, __src, __bos (__dest)); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In function ‘strcat’, inlined from ‘f2’ at t.c:17:3: /usr/include/bits/string3.h:142:10: warning: call to __builtin___memcpy_chk will always overflow destination buffer return __builtin___strcat_chk (__dest, __src, __bos (__dest)); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~