This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug c++/79095] [7 regression] spurious stringop-overflow warning
- From: "msebor at gcc dot gnu.org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Sun, 22 Jan 2017 17:57:31 +0000
- Subject: [Bug c++/79095] [7 regression] spurious stringop-overflow warning
- Auto-submitted: auto-generated
- References: <bug-79095-4@http.gcc.gnu.org/bugzilla/>
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79095
--- Comment #8 from Martin Sebor <msebor at gcc dot gnu.org> ---
(In reply to Jeffrey A. Law from comment #4)
> So the simplified tests are interesting, but ultimately too simplified.
You're right, the test case in comment #2 is oversimplified. The one in the
thread on gcc-patches should be closer (it includes the ADD_OVERFLOW):
$ cat t.C && gcc -O2 -S -Wall -fdump-tree-optimized=/dev/stdout t.C
typedef __SIZE_TYPE__ size_t;
struct S {
int *p0, *p1, *p2;
size_t size () const { return p1 - p0; }
void f (size_t n) {
if (n > size ()) // can't happen because
foo (n - size ()); // n is in [1, MIN(size() - 1, 3)]
else if (n < size ())
bar (p0 + n);
}
void foo (size_t n)
{
size_t left = (size_t)(p2 - p1);
if (left >= n)
__builtin_memset (p2, 0, n * sizeof *p2);
}
void bar (int*);
};
void f (S &s)
{
size_t n = s.size ();
if (n > 1 && n < 5)
s.f (n - 1);
}
;; Function void f(S&) (_Z1fR1S, funcdef_no=3, decl_uid=2296, cgraph_uid=3,
symbol_order=3)
Removing basic block 9
Removing basic block 10
Removing basic block 11
void f(S&) (struct S & s)
{
long unsigned int _1;
long unsigned int _2;
int * _7;
int * _8;
long int _9;
long int _10;
long int _11;
long int _12;
long unsigned int _13;
long unsigned int _17;
int * _22;
long int _23;
long int _24;
__complex__ long unsigned int _25;
long unsigned int _28;
int * _29;
<bb 2> [100.00%]:
_7 = MEM[(int * *)s_5(D)];
_8 = MEM[(int * *)s_5(D) + 8B];
_9 = (long int) _8;
_10 = (long int) _7;
_11 = _9 - _10;
_12 = _11 /[ex] 4;
_13 = (long unsigned int) _12;
_1 = _13 + 18446744073709551614;
if (_1 <= 2)
goto <bb 3>; [36.64%]
else
goto <bb 8>; [63.36%]
<bb 3> [36.64%]:
_25 = ADD_OVERFLOW (_13, 18446744073709551615);
_2 = REALPART_EXPR <_25>;
_17 = IMAGPART_EXPR <_25>;
if (_2 > _13)
goto <bb 4>; [50.00%]
else
goto <bb 6>; [50.00%]
<bb 4> [18.32%]:
_22 = MEM[(int * *)s_5(D) + 16B];
_23 = (long int) _22;
_24 = _23 - _9;
if (_24 == -4)
goto <bb 5>; [33.00%]
else
goto <bb 8>; [67.00%]
<bb 5> [6.05%]:
__builtin_memset (_22, 0, 18446744073709551612); [tail call]
goto <bb 8>; [100.00%]
<bb 6> [18.32%]:
if (_17 != 0)
goto <bb 7>; [36.64%]
else
goto <bb 8>; [63.36%]
<bb 7> [6.71%]:
_28 = _2 * 4;
_29 = _7 + _28;
S::bar (s_5(D), _29); [tail call]
<bb 8> [100.00%]:
return;
}
In function ‘void S::foo(size_t)’,
inlined from ‘void S::f(size_t)’ at t.C:10:24,
inlined from ‘void f(S&)’ at t.C:29:16:
t.C:19:47: warning: ‘void* __builtin_memset(void*, int, long unsigned int)’:
specified size 18446744073709551612 exceeds maximum object size
9223372036854775807 [-Wstringop-overflow=]
__builtin_memset (p2, 0, n * sizeof *p2);
^