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

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
         Resolution|---                         |WONTFIX
             Status|UNCONFIRMED                 |RESOLVED

--- Comment #1 from Martin Sebor <msebor at gcc dot gnu.org> ---
I can reproduce the warning (at -O2 and -O3) but I don't see it as a bug in
GCC.  A slightly simplified test case below.  Using unsigned int for the size
avoids the warning but using size_t brings it back again.

The function is undefined when called with (n < 0 || n >= __INT_MAX__ / 2) (or
j_degree in the original test case) and asserting that's not the case makes the
warning go away and results in better code:

  if (n < 0 || n >= __INT_MAX__ / 2)
    __builtin_unreachable ();

I suppose a possible improvement here that would avoid the warning is to teach
GCC to derive the same precondition based on the absence of the undefined
behavior and emit more optimal code.  But that's orthogonal to the warning
itself.

The only thing I find puzzling is that the range for the memset() bound in the
strlen dump (where the warning comes from) looks valid and would not trigger
the warning but the one returned from vr_values::range_of_expr () the warning
actually uses doesn't seem right:But the range returned from
vr_values::range_of_expr () is:

;;   basic block 12, loop depth 0, count 59461674 (estimated locally), maybe
hot
;;    prev block 11, next block 13, flags: (NEW, REACHABLE, VISITED)
;;    pred:       8 [always]  count:59055800 (estimated locally)
(FALLTHRU,EXECUTABLE)
;;                5 [always]  count:405874 (estimated locally)
(FALLTHRU,EXECUTABLE)
  # .MEM_21 = PHI <.MEM_31(8), .MEM_40(5)>
  # VUSE <.MEM_21>
  return;
;;    succ:       EXIT [always]  count:59461674 (estimated locally)
(EXECUTABLE)

;;   basic block 13, loop depth 0, count 52559662 (estimated locally), maybe
hot
;;   Invalid sum of incoming counts 55785408 (estimated locally), should be
52559662 (estimated locally)
;;    prev block 12, next block 1, flags: (NEW, REACHABLE, VISITED)
;;    pred:       6 [5.5% (guessed)]  count:55785408 (estimated locally)
(FALSE_VALUE,EXECUTABLE)
  # RANGE [0, 2147483647] NONZERO 2147483646
  _12 = n_25(D) * 2;
  # RANGE [1, 2147483647] NONZERO 2147483647
  _42 = _12 + 1;
  # RANGE [1, 2147483647] NONZERO 2147483647
  _11 = (sizetype) _42;
  # RANGE [4, 8589934588] NONZERO 8589934588
  _13 = _11 * 4;
  # .MEM_41 = VDEF <.MEM_38>
  # PT = { D.1985 }
  # ALIGN = 4, MISALIGN = 0
  # USE = nonlocal { D.1983 } (escaped, escaped heap)
  # CLB = nonlocal { D.1983 } (escaped, escaped heap)
  a.0_43 = __builtin_alloca_with_alignD.1906 (_13, 32);
  # .MEM_45 = VDEF <.MEM_41>
  # USE = nonlocal { D.1983 } (escaped, escaped heap)
  # CLB = nonlocal { D.1983 } (escaped, escaped heap)
  memsetD.897 (a.0_43, 0, _13);
  goto <bb 9>; [100.00%]
;;    succ:       9 [always]  count:52559662 (estimated locally)
(FALLTHRU,EXECUTABLE)

}


(gdb) p rng
$22 = VR_RANGE
(gdb) p debug_tree(vr.min())
 <integer_cst 0x7fffea95f440 type <integer_type 0x7fffea80f000 sizetype>
constant 18446744065119617028>
$23 = void
(gdb) p debug_tree(vr.max())
 <integer_cst 0x7fffea939fa0 type <integer_type 0x7fffea80f000 sizetype>
constant 18446744073709551612>
$24 = void
(gdb) 


The slightly reduced test case:

$ cat pr100256.c && gcc -O2 -S -Wall pr100256.c 
void f (int n, int *q, int **p)
{
  for (int i = 0; i < n + 1; i++)
    if (!(p[i] = __builtin_calloc (n + 1, sizeof (int))))
      return;

  int a[n * 2 + 1];

  __builtin_memset (a, 0, sizeof a);

  for (int i = 0; i < n * 2 + 1; i++)
    {
      a[i]++;
      if (i < n + 1)
        q[i]++;
    }
}

pr100256.c: In function ‘f’:
pr100256.c:9:3: warning: ‘__builtin_memset’ writing between
18446744065119617028 and 18446744073709551612 bytes into a region of size
9223372036854775807 [-Wstringop-overflow=]
    9 |   __builtin_memset (a, 0, sizeof a);
      |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
pr100256.c:7:7: note: destination object ‘a’ of size 9223372036854775807
    7 |   int a[n * 2 + 1];
      |       ^

Reply via email to