https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79082
--- Comment #6 from Franz Sirl <sirl at gcc dot gnu.org> --- Created attachment 40566 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=40566&action=edit extended testcase Hmm, looks like there is an off-by-one bug lurking here? To clarify my setup, here are the warnings for the attached testcase on Linux/x86-64 (SLES12SP2) with a bootstrapped r244773 compiler. First, gcc-trunk -c -Wformat-truncation test-snprintf-2.c -O0: test-snprintf-2.c: In function 'test': test-snprintf-2.c:6:23: warning: '%2d' directive output may be truncated writing between 2 and 11 bytes into a region of size 3 [-Wformat-truncation=] snprintf(buffer, 3, "%2d", val % 100); /* 1 */ /* should warn */ ^~~ test-snprintf-2.c:6:22: note: using the range [1, -2147483648] for directive argument snprintf(buffer, 3, "%2d", val % 100); /* 1 */ /* should warn */ ^~~~~ test-snprintf-2.c:6:2: note: format output between 3 and 12 bytes into a destination of size 3 snprintf(buffer, 3, "%2d", val % 100); /* 1 */ /* should warn */ ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ test-snprintf-2.c:7:23: warning: '%2hhd' directive output may be truncated writing between 2 and 4 bytes into a region of size 3 [-Wformat-truncation=] snprintf(buffer, 3, "%2hhd", val % 100); /* 2 */ /* should warn */ ^~~~~ test-snprintf-2.c:7:22: note: using the range [1, -128] for directive argument snprintf(buffer, 3, "%2hhd", val % 100); /* 2 */ /* should warn */ ^~~~~~~ test-snprintf-2.c:7:2: note: format output between 3 and 5 bytes into a destination of size 3 snprintf(buffer, 3, "%2hhd", val % 100); /* 2 */ /* should warn */ ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ test-snprintf-2.c:9:23: warning: '%2d' directive output may be truncated writing between 2 and 11 bytes into a region of size 3 [-Wformat-truncation=] snprintf(buffer, 3, "%2d", (val < 0) ? -(val % 100): val % 100); /* 3 */ /* should not warn */ ^~~ test-snprintf-2.c:9:22: note: using the range [1, -2147483648] for directive argument snprintf(buffer, 3, "%2d", (val < 0) ? -(val % 100): val % 100); /* 3 */ /* should not warn */ ^~~~~ test-snprintf-2.c:9:2: note: format output between 3 and 12 bytes into a destination of size 3 snprintf(buffer, 3, "%2d", (val < 0) ? -(val % 100): val % 100); /* 3 */ /* should not warn */ ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ test-snprintf-2.c:10:23: warning: '%2d' directive output may be truncated writing between 2 and 11 bytes into a region of size 3 [-Wformat-truncation=] snprintf(buffer, 3, "%2d", __builtin_abs(val % 100)); /* 4 */ /* should not warn */ ^~~ test-snprintf-2.c:10:22: note: using the range [1, -2147483648] for directive argument snprintf(buffer, 3, "%2d", __builtin_abs(val % 100)); /* 4 */ /* should not warn */ ^~~~~ test-snprintf-2.c:10:2: note: format output between 3 and 12 bytes into a destination of size 3 snprintf(buffer, 3, "%2d", __builtin_abs(val % 100)); /* 4 */ /* should not warn */ ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ test-snprintf-2.c:12:23: warning: '%2x' directive output may be truncated writing between 2 and 8 bytes into a region of size 3 [-Wformat-truncation=] snprintf(buffer, 3, "%2x", val & 0xff); /* 5 */ /* should not warn */ ^~~ test-snprintf-2.c:12:22: note: using the range [1, 4294967295] for directive argument snprintf(buffer, 3, "%2x", val & 0xff); /* 5 */ /* should not warn */ ^~~~~ test-snprintf-2.c:12:2: note: format output between 3 and 9 bytes into a destination of size 3 snprintf(buffer, 3, "%2x", val & 0xff); /* 5 */ /* should not warn */ ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ test-snprintf-2.c:13:23: warning: '%03x' directive output may be truncated writing between 3 and 8 bytes into a region of size 4 [-Wformat-truncation=] snprintf(buffer, 4, "%03x", val & 0xfff); /* 6 */ /* should not warn */ ^~~~ test-snprintf-2.c:13:22: note: using the range [1, 4294967295] for directive argument snprintf(buffer, 4, "%03x", val & 0xfff); /* 6 */ /* should not warn */ ^~~~~~ test-snprintf-2.c:13:2: note: format output between 4 and 9 bytes into a destination of size 4 snprintf(buffer, 4, "%03x", val & 0xfff); /* 6 */ /* should not warn */ ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ No idea why 8 (and maybe 7?) does not warn on my machine, certainly the buffer is too small for anything >= 0x1000. Second, gcc-trunk -c -Wformat-truncation test-snprintf-2.c -O2: test-snprintf-2.c: In function 'test': test-snprintf-2.c:6:26: warning: output may be truncated before the last format character [-Wformat-truncation=] snprintf(buffer, 3, "%2d", val % 100); /* 1 */ /* should warn */ ~~~^ test-snprintf-2.c:6:2: note: format output between 3 and 4 bytes into a destination of size 3 snprintf(buffer, 3, "%2d", val % 100); /* 1 */ /* should warn */ ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ test-snprintf-2.c:7:28: warning: output may be truncated before the last format character [-Wformat-truncation=] snprintf(buffer, 3, "%2hhd", val % 100); /* 2 */ /* should warn */ ~~~~~^ test-snprintf-2.c:7:2: note: format output between 3 and 4 bytes into a destination of size 3 snprintf(buffer, 3, "%2hhd", val % 100); /* 2 */ /* should warn */ ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ test-snprintf-2.c:9:26: warning: output may be truncated before the last format character [-Wformat-truncation=] snprintf(buffer, 3, "%2d", (val < 0) ? -(val % 100): val % 100); /* 3 */ /* should not warn */ ~~~^ test-snprintf-2.c:9:2: note: format output between 3 and 4 bytes into a destination of size 3 snprintf(buffer, 3, "%2d", (val < 0) ? -(val % 100): val % 100); /* 3 */ /* should not warn */ ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Also here, no warning for 8?