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.