https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79221
Bug ID: 79221 Summary: missing -Wstringop-overflow= on a strcat overflow 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: --- Similar to bug 79220, the -Wstringop-overflow option diagnoses the buffer overflow in the call to strcat in f() in the program below but fails to do the same for the strcat() overflow in g(). As in the referenced bug, GCC transforms the second strcat() to an assignment followed by a call to memcpy, defeating the overflow detection. GCC should avoid this transformation when the destination isn't big enough for the copy. I expect this bug will be resolved by a comprehensive fix for bug 79220 but it seems that keeping track of each of these troublesome -- even though not invalid -- transformations separately might help assure that the fix does, in fact, resolve all these related problems. (Both cases of overflow are diagnosed when _FORTIFY_SOURCE is defined.) $ cat t.c && gcc -O2 -S -Wall -Wextra -Wpedantic -fdump-tree-optimized=/dev/stdout t.c #include <string.h> char d[3]; void f (int i) { const char *s = i < 0 ? "01234567" : "89abcd"; strcat (d, s); } void gf (int i) { const char *s = i < 0 ? "12345678" : "87654321"; strcat (d, s); } ;; Function f (f, funcdef_no=14, decl_uid=2196, cgraph_uid=14, symbol_order=15) Removing basic block 3 f (int i) { const char * iftmp.0_1; <bb 2> [100.00%]: if (i_2(D) < 0) goto <bb 4>; [32.39%] else goto <bb 3>; [67.61%] <bb 3> [67.61%]: <bb 4> [100.00%]: # iftmp.0_1 = PHI <"01234567"(2), "89abcd"(3)> strcat (&d, iftmp.0_1); [tail call] return; } t.c: In function ‘f’: t.c:8:3: warning: ‘strcat’ writing 7 bytes into a region of size 3 overflows the destination [-Wstringop-overflow=] strcat (d, s); ^~~~~~~~~~~~~ ;; Function gf (gf, funcdef_no=15, decl_uid=2200, cgraph_uid=15, symbol_order=16) Removing basic block 3 gf (int i) { char[9] * iftmp.1_1; long unsigned int _5; char[3] * _6; <bb 2> [100.00%]: if (i_2(D) < 0) goto <bb 4>; [32.39%] else goto <bb 3>; [67.61%] <bb 3> [67.61%]: <bb 4> [100.00%]: # iftmp.1_1 = PHI <"12345678"(2), "87654321"(3)> _5 = __builtin_strlen (&d); _6 = &d + _5; __builtin_memcpy (_6, iftmp.1_1, 9); [tail call] return; }