https://gcc.gnu.org/bugzilla/show_bug.cgi?id=54582
Martin Sebor <msebor at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Keywords| |diagnostic Status|NEW |RESOLVED Known to work| |10.0, 7.3.0, 8.3.0, 9.1.0 See Also| |https://gcc.gnu.org/bugzill | |a/show_bug.cgi?id=86349 Resolution|--- |DUPLICATE Known to fail| |6.3.0 --- Comment #18 from Martin Sebor <msebor at gcc dot gnu.org> --- Starting with r240298, GCC 7 and later diagnose the buffer overflow in both calls so this request can be resolved as a duplicate of pr49905. The output with the current trunk at -O0 is below. $ gcc -S -Wall pr54582.c pr54582.c: In function ‘f’: pr54582.c:8:18: warning: ‘%d’ directive writing between 1 and 11 bytes into a region of size 0 [-Wformat-overflow=] 8 | sprintf(buf, "ab%d", n); | ^~ pr54582.c:8:2: note: ‘sprintf’ output between 4 and 14 bytes into a destination of size 2 8 | sprintf(buf, "ab%d", n); | ^~~~~~~~~~~~~~~~~~~~~~~ pr54582.c:11:18: warning: ‘sprintf’ writing a terminating nul past the end of the destination [-Wformat-overflow=] 11 | sprintf(buf, "ab"); | ^ pr54582.c:11:2: note: ‘sprintf’ output 3 bytes into a destination of size 2 11 | sprintf(buf, "ab"); | ^~~~~~~~~~~~~~~~~~ With -D_FORTIFY_SOURCE, both calls are still instrumented. ;; Function f (f, funcdef_no=23, decl_uid=2524, cgraph_uid=24, symbol_order=23) f (int n) { char buf[2]; <bb 2> [local count: 1073741824]: __builtin___sprintf_chk (&buf, 1, 2, "ab%d", n_2(D)); __builtin_puts (&buf); __builtin___sprintf_chk (&buf, 1, 2, "ab"); __builtin_puts (&buf); buf ={v} {CLOBBER}; return; } What still doesn't work is the overflow detection/prevention for dynamically allocated objects and VLAs. Bug 86349 records this limitation. The strlen pass tracks dynamic allocation and uses it for optimization but not yet to detect buffer overflow. Making use of it is a relatively simple enhancement. Now that the sprintf checker runs as part of the strlen pass, with the enhancement in place, exposing the dynamic allocation sizes to it to detect the overflow should be straightforward (and is on my list of things to do). $ cat t.c && gcc -O2 -D_FORTIFY_SOURCE=2 -S -Wall -fdump-tree-optimized=/dev/stdout t.c #include <stdio.h> int n = 2; void f (int n) { char buf[n]; sprintf (buf, "abcdef"); printf ("%s\n", buf); } ;; Function f (f, funcdef_no=23, decl_uid=2525, cgraph_uid=24, symbol_order=24) f (int n) { char[0:D.2530] * buf.1; sizetype _1; <bb 2> [local count: 1073741824]: _1 = (sizetype) n_2(D); buf.1_7 = __builtin_alloca_with_align (_1, 8); __builtin_memcpy (buf.1_7, "abcdef", 7); __builtin_puts (buf.1_7); return; } *** This bug has been marked as a duplicate of bug 49905 ***