https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79095
Martin Sebor <msebor at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|UNCONFIRMED |ASSIGNED Last reconfirmed| |2017-01-17 Assignee|unassigned at gcc dot gnu.org |msebor at gcc dot gnu.org Ever confirmed|0 |1 --- Comment #2 from Martin Sebor <msebor at gcc dot gnu.org> --- The warning is reproducible with the test case below. The memset call is inserted by the loop distribution pass. The pass should avoid inserting memcpy/memmove/memset calls with excessively large arguments (> SIZE_MAX / 2) because they are certainly incorrect and, if executed, will lead to buffer overflow and memory corruption. I'm testing a patch that inserts a trap instead. FWIW, the warning is working as I hoped it would: it's helping find bugs. In this case, the problem is exposed by the loop to memset transformation. The warning isn't necessarily useful to the user because the code is inserted by GCC itself but it has exposed an opportunity to both make the generated code safer (avoid the memory corruption) and more efficient (it can help GCC generate code based on the assumption that the overflow is unlikely to happen). $ cat t.ii && gcc -O3 -S -Wall -Wextra -Wpedantic -xc++ -fdump-tree-optimized=/dev/stdout t.ii typedef long unsigned int size_t; inline void fill (int *p, size_t n, int) { while (n--) *p++ = 0; } struct B { int* p0, *p1, *p2; size_t size () const { return size_t (p1 - p0); } void resize (size_t n) { if (n > size()) append (n - size()); } void append (size_t n) { if (size_t (p2 - p1) >= n) { fill (p1, n, 0); } } }; void foo (B &b) { b.resize (b.size () - 1); } ;; Function void foo(B&) (_Z3fooR1B, funcdef_no=4, decl_uid=2299, cgraph_uid=4, symbol_order=4) Removing basic block 6 Removing basic block 7 void foo(B&) (struct B & b) { int * _4; int * _5; int * _6; long int _7; long int _8; long int _13; long int _14; <bb 2> [4.91%]: _4 = MEM[(int * *)b_3(D)]; _5 = MEM[(int * *)b_3(D) + 8B]; _13 = (long int) _5; _14 = (long int) _4; if (_13 == _14) goto <bb 3>; [54.00%] else goto <bb 5>; [46.00%] <bb 3> [2.65%]: _6 = MEM[(int * *)b_3(D) + 16B]; _7 = (long int) _6; _8 = _7 - _13; if (_8 == -4) goto <bb 4>; [37.68%] else goto <bb 5>; [62.32%] <bb 4> [1.00%]: __builtin_memset (_5, 0, 18446744073709551612); [tail call] <bb 5> [4.91%]: return; } In function ‘void foo(B&)’: cc1plus: warning: ‘void* __builtin_memset(void*, int, long unsigned int)’: specified size 18446744073709551612 exceeds maximum object size 9223372036854775807 -Wstringop-overflow=]