[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