With the new -Wstringop-overflow option GCC diagnoses the more involved buffer overflow in function foo() but misses the more straightforward case of the same overflow in bar(). This because the second call to __builtin_strcpy is transformed into __builtin_memcpy by one of the optimization passes, apparently without regard to the possibility of overflow. $ cat x.C && gcc -O2 -S -Wstringop-overflow=2 x.C struct S { char a[3]; void (*pf)(void); }; void foo (struct S *s, int i) { const char *str = i ? "1234578" : "87654321"; __builtin_strcpy (s->a, str); } void bar (struct S *s, int i) { const char *str = "1234578"; __builtin_strcpy (s->a, str); // missing -Wstringop-overflow } x.C: In function ‘void foo(S*, int)’: x.C:9:31: warning: ‘char* __builtin_strcpy(char*, const char*)’ writing 8 bytes into a region of size 3 overflows the destination [-Wstringop-overflow=] __builtin_strcpy (s->a, str); ^
Confirmed.
cc-ing diagnostics maintainers