Created attachment 44335 [details] testcase The attached testcase warns like this with trunk@262215: gcc-trunk -c -O2 -Wstringop-overflow test-stringop-overflow.c test-stringop-overflow.c: In function 'func2': test-stringop-overflow.c:56:3: warning: 'memset' specified size between 18446744071562067968 and 18446744073709551615 exceeds maximum object size 9223372036854775807 [-Wstringop-overflow=] memset ((buf), 0, (len)); ^~~~~~~~~~~~~~~~~~~~~~~~ This is a relatively new regression on trunk (gcc-8-branch is fine). The code is quite sensitive to changes, so I didn't reduce it further.
I can confirm the warning with the (possibly overly) reduced test case below but not really that it's a bug in the warning code. In the reduced test case, memset() is called with a size that's either zero or in excess of PTRDIFF_MAX. The call is diagnosed by design because the zero size is unlikely. In the bigger test case, GCC (I think the jump threading pass) introduces a couple of earlier calls to memset that VRP substitutes constant arguments into and leaves the last call with the non-constant argument in the same ~[1, PTRDIFF_MAX] anti-range. One solution would be to improve GCC to eliminate the last memcpy() call because it's either dead (zero size) or invalid. In the meantime, changing the type of the argument to func2() to unsigned avoids the warning. It's better to use unsigned variables to represent quantities that cannot be negative; that way the whole issue or excessively large results as a result of sign extension becomes moot. $ cat c.c && gcc -O2 -S -Wall -fdump-tree-vrp=/dev/stdout c.c void g (int *a, int n) { if (n == 2) *a = 0; else if (n > 0) return; char b[8]; __builtin_memset (b, 0, n); if (n == 2) return; __builtin_puts (b); } ... Value ranges after VRP: ... _20: ~[1, 18446744071562067967] g (int * a, int n) { char b[8]; long unsigned int _20; <bb 2> [local count: 1073741825]: if (n_5(D) == 2) goto <bb 3>; [34.00%] else goto <bb 4>; [66.00%] <bb 3> [local count: 365072220]: *a_7(D) = 0; goto <bb 5>; [100.00%] <bb 4> [local count: 708669604]: if (n_5(D) > 0) goto <bb 5>; [42.57%] else goto <bb 7>; [57.43%] <bb 5> [local count: 571979267]: b ={v} {CLOBBER}; <bb 6> [local count: 1073741825]: return; <bb 7> [local count: 501762557]: _20 = (long unsigned int) n_5(D); __builtin_memset (&b, 0, _20); __builtin_puts (&b); b ={v} {CLOBBER}; goto <bb 6>; [100.00%] } c.c: In function ‘g’: c.c:9:3: warning: ‘__builtin_memset’ specified size between 18446744071562067968 and 18446744073709551615 exceeds maximum object size 9223372036854775807 [-Wstringop-overflow=] __builtin_memset (b, 0, n); ^~~~~~~~~~~~~~~~~~~~~~~~~~
As an aside, the warning first appeared with r260350 as a result of improvements to switch statement handling.
I can reproduce the warning in GCC 9.1.0-trunk with the reduced testcase but not with the original testcase.
The original test-case is fixed with r9-2639-gbb79aba479cf2288.