The -Wformat-overflow option detects the possible buffer overflow in function f below but missed the same possible overflow in function g. The function it relies on to detect the sizes of the array, get_range_strlen() in gimple-fold.c, handles member arrays but not the non-member array case. $ cat u.c && gcc -O2 -S -Wall -Wformat-overflow u.c char d[3]; struct S { char a3[3]; char a4[4]; }; void f (int i, const struct S *p) { const char *s = i < 0 ? p->a3 : p->a4; __builtin_sprintf (d, "%-s", s); } char a3[3]; char a4[4]; void g (int i) { const char *s = i < 0 ? a3 : a4; __builtin_sprintf (d, "%-s", s); } u.c: In function ‘f’: u.c:11:25: warning: ‘__builtin_sprintf’ may write a terminating nul past the end of the destination [-Wformat-overflow=] __builtin_sprintf (d, "%-s", s); ^~~~~ u.c:11:3: note: ‘__builtin_sprintf’ output between 1 and 4 bytes into a destination of size 3 __builtin_sprintf (d, "%-s", s); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Confirming my own bug and adjusting the Summary to make it clear that the problem isn't specific to global arrays and affects local arrays as well. The following test case shows that. $ cat z.c && gcc -O2 -S -Wall -Wextra -Wpedantic -fdump-tree-printf-return-value=/dev/stdout z.c int main () { char d[3]; char s[] = "abcd"; __builtin_sprintf (d, "%-s", s); __builtin_printf ("%s\n", d); } ;; Function main (main, funcdef_no=0, decl_uid=1794, cgraph_uid=0, symbol_order=0) (executed once) z.c:6: __builtin_sprintf: objsize = 3, fmtstr = "%-s" Directive 1 at offset 0: "%-s" Result: 0, 0, -1, 9223372036854775807 (0, 0, -1, -1) Directive 2 at offset 3: "", length = 1 main () { char s[5]; char d[3]; <bb 2> [100.00%]: s = "abcd"; __builtin_sprintf (&d, "%-s", &s); __builtin_puts (&d); d ={v} {CLOBBER}; s ={v} {CLOBBER}; return 0; }
this is because the routine "get_range_strlen" misses the handling of regular arrays. adding the support should fix this issue.
Qing is on it.
fixed in https://gcc.gnu.org/viewcvs/gcc?view=revision&revision=255654
this bug has been fixed in upstream. and is decided not back port to Gcc 7. so close it as resolved