https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103736
Martin Sebor <msebor at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |msebor at gcc dot gnu.org --- Comment #1 from Martin Sebor <msebor at gcc dot gnu.org> --- The warning is based on the annotated IL below. The duplicate modulo computation is optimized to take place just once (in PRE), before the negativity test, the range of the result in the else branch is greater than the code permits. void func () { char timezone[4]; signed char timezoneval.0_1; int _4; int _12; signed char _13; <bb 2> [local count: 1073741824]: timezoneval.0_1 = timezoneval; _13 = timezoneval.0_1 % 100; _12 = (int) _13; >>> _12's range is [-99, 99] if (timezoneval.0_1 < 0) goto <bb 3>; [41.00%] else goto <bb 4>; [59.00%] <bb 3> [local count: 440234144]: _4 = -_12; _4's range is [0, 99] snprintf (&timezone, 4, "-%02d", _4); so no warning here goto <bb 5>; [100.00%] <bb 4> [local count: 633507681]: snprintf (&timezone, 4, "+%02d", _12); << -Wformat-truncation <bb 5> [local count: 1073741824]: timezone ={v} {CLOBBER}; return; } The warning can be avoided by using a local temporary copy of the extern variable, like so int x = timezoneval; if(x < 0) { snprintf(timezone, sizeof(timezone),"-%02d",-(x % 100)); } else { snprintf(timezone, sizeof(timezone),"+%02d", x % 100); } or simply: int x = timezoneval % 100; if(x < 0) { snprintf(timezone, sizeof(timezone),"-%02d",-x); } else { snprintf(timezone, sizeof(timezone),"+%02d", x); }