https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77784
Bug ID: 77784 Summary: duplicate warning for snprintf for n > object size 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: --- As mentioned in bug 77762#2, with both the -Wformat-length option used and _FORTIFY_SOURCE defined (and with optimization enabled), GCC now prints two warnings for calls to functions like snprintf (which normally calls __builtin___snprintf_chk). Only one warning should be printed. $ cat zzz.c && /build/gcc-trunk-svn/gcc/xgcc -B /build/gcc-trunk-svn/gcc -S -Wall -Wformat-length=1 zzz.c char d [2]; void f (const char *s) { __builtin___snprintf_chk (d, 4, 0, 2, s); } zzz.c: In function ‘f’: zzz.c:5:3: warning: specified size 4 exceeds the size 2 of the destination object [-Wformat-length=] __builtin___snprintf_chk (d, 4, 0, 2, s); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ zzz.c:5:3: warning: call to __builtin___snprintf_chk will always overflow destination buffer As also pointed out in bug 77762 and as the following program shows, the latter warning is misleading because a buffer overflow need not actually take place and the call may be valid. This is just a minor detail when the default implementation of the __snprintf_chk function is used that calls abort in this case, but printing a more accurate message becomes important when an alternate implementation is used that does not abort (as is sometimes done in operating system kernels, for example). $ cat zzz.c && /build/gcc-trunk-svn/gcc/xgcc -B /build/gcc-trunk-svn/gcc -Wall -Wformat -Wextra -Wpedantic -Wformat-length=1 zzz.c && ./a.out typedef __SIZE_TYPE__ size_t; char d [2]; int main (void) { char s[] = "x"; __builtin___snprintf_chk (d, 4, 0, 2, s); } int __snprintf_chk (char *s, size_t maxlen, int flag, size_t os, const char *fmt, ...) { __builtin_printf ("%s(%p, %zu, %i, %zu, \"%s\"...)\n", __func__, s, maxlen, flag, os, fmt); return __builtin_puts (fmt); } zzz.c: In function ‘main’: zzz.c:8:3: warning: specified size 4 exceeds the size 2 of the destination object [-Wformat-length=] __builtin___snprintf_chk (d, 4, 0, 2, s); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ zzz.c:8:3: warning: call to __builtin___snprintf_chk will always overflow destination buffer __snprintf_chk(0x601049, 4, 0, 2, "x"...) x