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.