https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79082
--- Comment #7 from Martin Sebor <msebor at gcc dot gnu.org> --- Except for #8, none of the sprintf calls in the extended testcase in attachment 40566 can be handled as accurately at -O0 as with optimization because the arguments to the format directives are treated as if they had the full range of int. The question in my mind is whether, in the absence of any other hints or constraints (see below), -Wformat-truncation should warn if truncation is possible (again, given that at -O0 (val & 0xfff) is no different than val) but not inevitable, or whether it should only warn when truncation certain. Put another way, should the set of warnings at -O0 be a strict subset of those with optimization? I think you are suggesting that it should be and I tend to agree. With my latest patch for bug 78703 (still under review), GCC doesn't issue any warnings for this test case at -O0. I suspect trunk warns not so much as a feature but more by accident. With optimization enabled, GCC can determine the values (or ranges) of some non-constant arguments. The warning pass can then use those to give more accurate warnings. It's important to keep in mind that a) due to limitations or bugs the range information is not available for every expression (e.g., bug 78969 or bug 79191), and b) sometimes these limitations affect the range information available for unrelated expressions in the same function (e.g., bug 79054). Your test case unfortunately happens to trigger (b) and as a result ends up with a false positive for case 3. You can see that in the dump created by the -ftree-dump-vrp option where the argument is assumed to include the negative subrange: Value ranges after VRP: ... iftmp.0_11: [-99, 99] ... snprintf (buffer_8(D), 3, "%2d", iftmp.0_5); With the other snprintf calls removed or moved into their own function the false positive goes away and the test case produces warnings for just the first two cases with the "should warn" comment. These cases are diagnosed for two reasons: 1) given the right value of the argument the directive can overflow, and 2) the argument conversion has been constrained to some subrange of its full range. (2) is important because it suggests that the programmer may have made an effort to constrain the output to avoid the truncation but didn't go quite far enough to prevent it. A common mistake is to forget that the argument is signed and can be negative (as in assuming that (val % 100) results in at most 2 bytes). The last case (#8) isn't diagnosed because it doesn't meet condition (2). Since the argument appears completely unconstrained, the conservative level 1 of the warning assumes that may be constrained elsewhere (in the caller of function test). The warning should be issued at level 2 but on trunk isn't. That's a bug that's also fixed by my latest patch.