https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100442
Martin Sebor <msebor at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Resolution|--- |INVALID Status|WAITING |RESOLVED --- Comment #3 from Martin Sebor <msebor at gcc dot gnu.org> --- The warning is working correctly: it sees (and prints) the range below. ;; basic block 7, loop depth 1, count 2036975 (estimated locally), maybe hot ;; Invalid sum of incoming counts 4073950 (estimated locally), should be 2036975 (estimated locally) ;; prev block 6, next block 8, flags: (NEW, REACHABLE, VISITED) ;; pred: 5 [50.0% (guessed)] count:4073950 (estimated locally) (FALSE_VALUE,EXECUTABLE) # RANGE [18446744073709551612, 18446744073709551615] <<< excessive range _78 = (long unsigned intD.10) lexeme_len_24(D); # RANGE [0, 1048575] NONZERO 1048575 _79 = (sizetype) _75; # PT = nonlocal _80 = _7 + _79; # VUSE <.MEM_20(D)> # USE = nonlocal escaped cmp_81 = memcmpD.890 (lexeme_23(D), _80, _78); <<< -Wstringop-overead if (cmp_81 == 0) goto <bb 9>; [50.00%] else goto <bb 8>; [50.00%] Ending up with an excessive range isn't uncommon in code that freely converts between signed and unsigned integers (e.g., by passing an int to a size_t argument) and involves conditionals like those in tsCompareString(). GCC must assume the signed integers may be negative and convert to very large positive values. Changing tsCompareString() to take size_t arguments instead of int avoids the warning: int32 tsCompareString(char *a, size_t lena, char *b, size_t lenb, _Bool prefix); Alternatively, asserting that the signed arguments aren't negative also prevents the warning and in addition appears to result in better code (tsvector_bsearch is inlined as well): ... else { if (lena < 0 || lenb < 0) __builtin_unreachable (); cmp = memcmp(a, b, ((lena) < (lenb) ? (lena) : (lenb))); I don't think there is anything for GCC to do here.