https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97336

Martin Sebor <msebor at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
         Resolution|---                         |INVALID
                 CC|                            |msebor at gcc dot gnu.org
             Status|UNCONFIRMED                 |RESOLVED

--- Comment #1 from Martin Sebor <msebor at gcc dot gnu.org> ---
The warning works as intended: unless n > 4, the strncmp call will return
nonzero because the length of buf is less than 5.  GCC partially unrolls the
loop and the first iteration of it is what triggers the warning.  It disappears
when the buffer is cleared with memset only because GCC (as a limitation) loses
track of the length of the string in buf after that.  Handling the case when n
is zero or less (e.g., via if (n <= 0) return 0;) does as well.

The IL that leads up to the warning can be seen in the output of the
-fdump-tree-dom4 option (below).

f (const char * p, int n)
{
  sizetype ivtmp.6;
  int i;
  char buf[10];
  char _3;
  _Bool _4;
  _Bool _5;
  _Bool _6;
  int _7;
  int _10;
  char prephitmp_20;
  int _21;
  unsigned int _25;
  char pretmp_33;

  <bb 2> [local count: 118111600]:
  buf = "";                                     <<< strlen(buf) == 0
  if (n_15(D) > 0)
    goto <bb 11>; [89.00%]
  else
    goto <bb 4>; [11.00%]

  ...
  <bb 4> [local count: 12992276]:               <<< n == 0
  _21 = __builtin_strncmp (&buf, "12345", 5);   <<< warning here
  if (_21 == 0)                                 <<< folded to false
    goto <bb 5>; [50.00%]
  else
    goto <bb 6>; [50.00%]

  <bb 5> [local count: 6496138]:
  # prephitmp_20 = PHI <0(4)>

  <bb 6> [local count: 95940523]:
  goto <bb 10>; [100.00%]

  <bb 7> [local count: 105119324]:
  _7 = __builtin_strncmp (&buf, "12345", 5);    <<< second strncmp call
  if (_7 == 0)
    goto <bb 8>; [50.00%]
  else
    goto <bb 6>; [50.00%]

  <bb 8> [local count: 52559662]:
  if (i_19 == 5)
    goto <bb 10>; [23.93%]
  else
    goto <bb 9>; [76.07%]

  <bb 9> [local count: 40175661]:
  pretmp_33 = buf[5];
  if (pretmp_33 == 32)
    goto <bb 10>; [25.01%]
  else
    goto <bb 6>; [74.99%]

  <bb 10> [local count: 118111600]:
  # _10 = PHI <1(9), 0(6), 1(8)>
  buf ={v} {CLOBBER};
  return _10;

}


Rewriting the code in a way that avoids the loop (e.g., by using memcpy
instead) also avoids the warning.

Reply via email to