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.

Reply via email to