[Bug other/103736] snprintf bogus format-truncation, disregarding modulo on argument
msebor at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Wed Dec 15 17:12:37 GMT 2021
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);
}
More information about the Gcc-bugs
mailing list