Bug 111073 - [13/14/15 regression] False-positive -Wstringop-overflow when building gdb from trunk with -D_GLIBCXX_ASSERTIONS
Summary: [13/14/15 regression] False-positive -Wstringop-overflow when building gdb fr...
Status: UNCONFIRMED
Alias: None
Product: gcc
Classification: Unclassified
Component: tree-optimization (show other bugs)
Version: 14.0
: P2 normal
Target Milestone: 13.4
Assignee: Not yet assigned to anyone
URL:
Keywords: diagnostic
Depends on:
Blocks: Warray-bounds Wstringop-overflow
  Show dependency treegraph
 
Reported: 2023-08-19 06:48 UTC by Sam James
Modified: 2024-08-05 22:04 UTC (History)
5 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments
infcall.ii.xz (329.16 KB, application/x-xz)
2023-08-19 06:48 UTC, Sam James
Details
creduced example (1.56 KB, text/plain)
2024-08-05 13:38 UTC, Simon Marchi
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Sam James 2023-08-19 06:48:42 UTC
Created attachment 55762 [details]
infcall.ii.xz

12.3.1 20230818 is OK, but 13.2.1 20230812 and 14.0.0 20230813 aren't.

I filed this over at gdb first: https://sourceware.org/bugzilla/show_bug.cgi?id=30780.

```
$ g++-14 -x c++    -I. -I. -I./config -DLOCALEDIR="\"/usr/local/share/locale\"" -DHAVE_CONFIG_H -I./../include/opcode -I../bfd -I./../bfd -I./../include -I./../readline/readline/.. -I./../zlib  -I../libdecnumber -I./../libdecnumber  -I./../gnulib/import -I../gnulib/import -I./.. -I.. -I./../libbacktrace/ -I../libbacktrace/ -DTUI=1    -I/usr/include/python3.12 -I/usr/include/python3.12   -I./.. -pthread    -Wall -Wpointer-arith -Wno-unused -Wunused-value -Wunused-variable -Wunused-function -Wno-switch -Wno-char-subscripts -Wempty-body -Wunused-but-set-parameter -Wunused-but-set-variable -Wno-sign-compare -Wno-error=maybe-uninitialized -Wno-mismatched-tags -Wsuggest-override -Wimplicit-fallthrough=3 -Wduplicated-cond -Wshadow=local -Wdeprecated-copy -Wdeprecated-copy-dtor -Wredundant-move -Wmissing-declarations -Wstrict-null-sentinel -Wformat -Wformat-nonliteral -Werror -g -O2     -c -o infcall.o -MT infcall.o -MMD -MP -MF ./.deps/infcall.Tpo infcall.c
In file included from /usr/lib/gcc/x86_64-pc-linux-gnu/14/include/g++-v14/bits/hashtable_policy.h:36,
                 from /usr/lib/gcc/x86_64-pc-linux-gnu/14/include/g++-v14/bits/hashtable.h:35,
                 from /usr/lib/gcc/x86_64-pc-linux-gnu/14/include/g++-v14/bits/unordered_map.h:33,
                 from /usr/lib/gcc/x86_64-pc-linux-gnu/14/include/g++-v14/unordered_map:41,
                 from /usr/lib/gcc/x86_64-pc-linux-gnu/14/include/g++-v14/functional:63,
                 from ./../gdbsupport/ptid.h:35,
                 from ./../gdbsupport/common-defs.h:206,
                 from defs.h:26,
                 from infcall.c:20:
In static member function ‘static _Up* std::__copy_move<_IsMove, true, std::random_access_iterator_tag>::__copy_m(_Tp*, _Tp*, _Up*) [with _Tp = value*; _Up = value*; bool _IsMove = false]’,
    inlined from ‘_OI std::__copy_move_a2(_II, _II, _OI) [with bool _IsMove = false; _II = value**; _OI = value**]’ at /usr/lib/gcc/x86_64-pc-linux-gnu/14/include/g++-v14/bits/stl_algobase.h:506:30,
    inlined from ‘_OI std::__copy_move_a1(_II, _II, _OI) [with bool _IsMove = false; _II = value**; _OI = value**]’ at /usr/lib/gcc/x86_64-pc-linux-gnu/14/include/g++-v14/bits/stl_algobase.h:533:42,
    inlined from ‘_OI std::__copy_move_a(_II, _II, _OI) [with bool _IsMove = false; _II = value**; _OI = value**]’ at /usr/lib/gcc/x86_64-pc-linux-gnu/14/include/g++-v14/bits/stl_algobase.h:540:31,
    inlined from ‘_OI std::copy(_II, _II, _OI) [with _II = value**; _OI = value**]’ at /usr/lib/gcc/x86_64-pc-linux-gnu/14/include/g++-v14/bits/stl_algobase.h:633:7,
    inlined from ‘static _ForwardIterator std::__uninitialized_copy<true>::__uninit_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = value**; _ForwardIterator = value**]’ at /usr/lib/gcc/x86_64-pc-linux-gnu/14/include/g++-v14/bits/stl_uninitialized.h:147:27,
    inlined from ‘_ForwardIterator std::uninitialized_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = value**; _ForwardIterator = value**]’ at /usr/lib/gcc/x86_64-pc-linux-gnu/14/include/g++-v14/bits/stl_uninitialized.h:185:15,
    inlined from ‘_ForwardIterator std::__uninitialized_copy_a(_InputIterator, _InputIterator, _ForwardIterator, allocator<_Tp>&) [with _InputIterator = value**; _ForwardIterator = value**; _Tp = value*]’ at /usr/lib/gcc/x86_64-pc-linux-gnu/14/include/g++-v14/bits/stl_uninitialized.h:373:37,
    inlined from ‘void std::vector<_Tp, _Alloc>::_M_range_insert(iterator, _ForwardIterator, _ForwardIterator, std::forward_iterator_tag) [with _ForwardIterator = value**; _Tp = value*; _Alloc = std::allocator<value*>]’ at /usr/lib/gcc/x86_64-pc-linux-gnu/14/include/g++-v14/bits/vector.tcc:884:38,
    inlined from ‘std::vector<_Tp, _Alloc>::iterator std::vector<_Tp, _Alloc>::insert(const_iterator, _InputIterator, _InputIterator) [with _InputIterator = value**; <template-parameter-2-2> = void; _Tp = value*; _Alloc = std::allocator<value*>]’ at /usr/lib/gcc/x86_64-pc-linux-gnu/14/include/g++-v14/bits/stl_vector.h:1486:19,
    inlined from ‘value* call_function_by_hand_dummy(value*, type*, gdb::array_view<value*>, void (*)(void*, int), void*)’ at infcall.c:1239:23:
/usr/lib/gcc/x86_64-pc-linux-gnu/14/include/g++-v14/bits/stl_algobase.h:437:30: error: ‘void* __builtin_memmove(void*, const void*, long unsigned int)’ writing 9 or more bytes into a region of size 0 overflows the destination [-Werror=stringop-overflow=]
  437 |             __builtin_memmove(__result, __first, sizeof(_Tp) * _Num);
      |             ~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /usr/lib/gcc/x86_64-pc-linux-gnu/14/include/g++-v14/x86_64-pc-linux-gnu/bits/c++allocator.h:33,
                 from /usr/lib/gcc/x86_64-pc-linux-gnu/14/include/g++-v14/bits/allocator.h:46,
                 from /usr/lib/gcc/x86_64-pc-linux-gnu/14/include/g++-v14/bits/alloc_traits.h:39,
                 from /usr/lib/gcc/x86_64-pc-linux-gnu/14/include/g++-v14/ext/alloc_traits.h:34,
                 from /usr/lib/gcc/x86_64-pc-linux-gnu/14/include/g++-v14/bits/hashtable_policy.h:39:
In member function ‘_Tp* std::__new_allocator<_Tp>::allocate(size_type, const void*) [with _Tp = value*]’,
    inlined from ‘static _Tp* std::allocator_traits<std::allocator<_Tp1> >::allocate(allocator_type&, size_type) [with _Tp = value*]’ at /usr/lib/gcc/x86_64-pc-linux-gnu/14/include/g++-v14/bits/alloc_traits.h:482:28,
    inlined from ‘std::_Vector_base<_Tp, _Alloc>::pointer std::_Vector_base<_Tp, _Alloc>::_M_allocate(std::size_t) [with _Tp = value*; _Alloc = std::allocator<value*>]’ at /usr/lib/gcc/x86_64-pc-linux-gnu/14/include/g++-v14/bits/stl_vector.h:378:33,
    inlined from ‘void std::vector<_Tp, _Alloc>::_M_range_insert(iterator, _ForwardIterator, _ForwardIterator, std::forward_iterator_tag) [with _ForwardIterator = value**; _Tp = value*; _Alloc = std::allocator<value*>]’ at /usr/lib/gcc/x86_64-pc-linux-gnu/14/include/g++-v14/bits/vector.tcc:875:40,
    inlined from ‘std::vector<_Tp, _Alloc>::iterator std::vector<_Tp, _Alloc>::insert(const_iterator, _InputIterator, _InputIterator) [with _InputIterator = value**; <template-parameter-2-2> = void; _Tp = value*; _Alloc = std::allocator<value*>]’ at /usr/lib/gcc/x86_64-pc-linux-gnu/14/include/g++-v14/bits/stl_vector.h:1486:19,
    inlined from ‘value* call_function_by_hand_dummy(value*, type*, gdb::array_view<value*>, void (*)(void*, int), void*)’ at infcall.c:1239:23:
/usr/lib/gcc/x86_64-pc-linux-gnu/14/include/g++-v14/bits/new_allocator.h:151:55: note: at offset [-9223372036854775808, -1] into destination object of size [8, 9223372036854775800] allocated by ‘operator new’
  151 |         return static_cast<_Tp*>(_GLIBCXX_OPERATOR_NEW(__n * sizeof(_Tp)));
      |                                                       ^
cc1plus: all warnings being treated as errors
```
Comment 1 Sam James 2023-08-19 06:49:25 UTC
I can reproduce it with:
```
$ g++-14 -c infcall.ii -O2 -Werror=stringop-overflow
[...]
/usr/lib/gcc/x86_64-pc-linux-gnu/14/include/g++-v14/bits/stl_algobase.h:437:30: error: ‘void* __builtin_memmove(void*, const void*, long unsigned int)’ writing 9 or more bytes into a region of size 0 overflows the destination [-Werror=stringop-overflow=]
  437 |             __builtin_memmove(__result, __first, sizeof(_Tp) * _Num);
      |             ~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[...]
```
Comment 2 Sam James 2023-08-19 06:51:20 UTC
Oh, interesting. It needs -D_GLIBCXX_ASSERTIONS (which my gcc has on by default) to trigger.
Comment 3 Jakub Jelinek 2024-05-21 09:16:37 UTC
GCC 13.3 is being released, retargeting bugs to GCC 13.4.
Comment 4 Simon Marchi 2024-08-05 13:08:43 UTC
I have a similar one from GDB.  It's -Warray-bounds, not -Wstringop-overflow, but the symptoms are really similar (needs _GLIBCXX_ASSERTIONS/_GLIBCXX_DEBUG, error reported at same line):

$ g++ -x c++    -I. -I/home/smarchi/src/wt/amd/gdb -I/home/smarchi/src/wt/amd/gdb/config -include /home/smarchi/src/wt/amd/gdb/defs.h -DLOCALEDIR="\"/tmp/roc-gdb/share/locale\"" -DHAVE_CONFIG_H -I/home/smarchi/src/wt/amd/gdb/../include/opcode -I../bfd -I/home/smarchi/src/wt/amd/gdb/../bfd -I/home/smarchi/src/wt/amd/gdb/../include -I/home/smarchi/src/wt/amd/gdb/../readline/readline/..   -I../libdecnumber -I/home/smarchi/src/wt/amd/gdb/../libdecnumber  -I/home/smarchi/src/wt/amd/gdb/../gnulib/import -I../gnulib/import -I/home/smarchi/src/wt/amd/gdb/.. -I.. -I/home/smarchi/src/wt/amd/gdb/../libbacktrace/ -I../libbacktrace/ -DTUI=1    -I/usr/include/python3.12 -I/usr/include/python3.12   -I/home/smarchi/src/wt/amd/gdb/.. -pthread   -I/tmp/roc-gdb/share/pkgconfig/../../include  -Wall -Wpointer-arith -Wno-unused -Wunused-value -Wunused-variable -Wunused-function -Wno-switch -Wno-char-subscripts -Wempty-body -Wunused-but-set-parameter -Wunused-but-set-variable -Wno-sign-compare -Wno-error=maybe-uninitialized -Wno-mismatched-tags -Wsuggest-override -Wimplicit-fallthrough=5 -Wduplicated-cond -Wshadow=local -Wdeprecated-copy -Wdeprecated-copy-dtor -Wredundant-move -Wmissing-declarations -Wstrict-null-sentinel -Wvla -Wformat -Wformat-nonliteral -Werror -g3 -O2 -fmax-errors=1 -fdiagnostics-color=always -fsanitize=address -D_GLIBCXX_DEBUG=1     -c -o symfile.o -MT symfile.o -MMD -MP -MF ./.deps/symfile.Tpo /home/smarchi/src/wt/amd/gdb/symfile.c
In file included from /usr/include/c++/13/bits/hashtable_policy.h:36,
                 from /usr/include/c++/13/bits/hashtable.h:35,
                 from /usr/include/c++/13/bits/unordered_map.h:33,
                 from /usr/include/c++/13/unordered_map:41,
                 from /usr/include/c++/13/functional:63,
                 from /home/smarchi/src/wt/amd/gdb/../gdbsupport/ptid.h:35,
                 from /home/smarchi/src/wt/amd/gdb/../gdbsupport/common-defs.h:197,
                 from /home/smarchi/src/wt/amd/gdb/defs.h:27,
                 from <command-line>:
In static member function ‘static _Up* std::__copy_move<_IsMove, true, std::random_access_iterator_tag>::__copy_m(_Tp*, _Tp*, _Up*) [with _Tp = const add_symbol_file_command(const char*, int)::sect_opt; _Up = add_symbol_file_command(const char*, int)::sect_opt; bool _IsMove = false]’,
    inlined from ‘_OI std::__copy_move_a2(_II, _II, _OI) [with bool _IsMove = false; _II = const add_symbol_file_command(const char*, int)::sect_opt*; _OI = add_symbol_file_command(const char*, int)::sect_opt*]’ at /usr/include/c++/13/bits/stl_algobase.h:506:30,
    inlined from ‘_OI std::__copy_move_a1(_II, _II, _OI) [with bool _IsMove = false; _II = const add_symbol_file_command(const char*, int)::sect_opt*; _OI = add_symbol_file_command(const char*, int)::sect_opt*]’ at /usr/include/c++/13/bits/stl_algobase.h:533:42,
    inlined from ‘_OI std::__copy_move_a(_II, _II, _OI) [with bool _IsMove = false; _II = const add_symbol_file_command(const char*, int)::sect_opt*; _OI = add_symbol_file_command(const char*, int)::sect_opt*]’ at /usr/include/c++/13/bits/stl_algobase.h:540:31,
    inlined from ‘_OI std::copy(_II, _II, _OI) [with _II = const add_symbol_file_command(const char*, int)::sect_opt*; _OI = add_symbol_file_command(const char*, int)::sect_opt*]’ at /usr/include/c++/13/bits/stl_algobase.h:633:7,
    inlined from ‘static _ForwardIterator std::__uninitialized_copy<true>::__uninit_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = const add_symbol_file_command(const char*, int)::sect_opt*; _ForwardIterator = add_symbol_file_command(const char*, int)::sect_opt*]’ at /usr/include/c++/13/bits/stl_uninitialized.h:147:27,
    inlined from ‘_ForwardIterator std::uninitialized_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = const add_symbol_file_command(const char*, int)::sect_opt*; _ForwardIterator = add_symbol_file_command(const char*, int)::sect_opt*]’ at /usr/include/c++/13/bits/stl_uninitialized.h:185:15,
    inlined from ‘_ForwardIterator std::__uninitialized_copy_a(_InputIterator, _InputIterator, _ForwardIterator, allocator<_Tp>&) [with _InputIterator = const add_symbol_file_command(const char*, int)::sect_opt*; _ForwardIterator = add_symbol_file_command(const char*, int)::sect_opt*; _Tp = add_symbol_file_command(const char*, int)::sect_opt]’ at /usr/include/c++/13/bits/stl_uninitialized.h:373:37,
    inlined from ‘void std::__cxx1998::vector<_Tp, _Alloc>::_M_range_initialize(_ForwardIterator, _ForwardIterator, std::forward_iterator_tag) [with _ForwardIterator = const add_symbol_file_command(const char*, int)::sect_opt*; _Tp = add_symbol_file_command(const char*, int)::sect_opt; _Alloc = std::allocator<add_symbol_file_command(const char*, int)::sect_opt>]’ at /usr/include/c++/13/bits/stl_vector.h:1695:33,
    inlined from ‘std::__cxx1998::vector<_Tp, _Alloc>::vector(std::initializer_list<_Tp>, const allocator_type&) [with _Tp = add_symbol_file_command(const char*, int)::sect_opt; _Alloc = std::allocator<add_symbol_file_command(const char*, int)::sect_opt>]’ at /usr/include/c++/13/bits/stl_vector.h:682:21,
    inlined from ‘std::__debug::vector<_Tp, _Allocator>::vector(std::initializer_list<_Tp>, const allocator_type&) [with _Tp = add_symbol_file_command(const char*, int)::sect_opt; _Allocator = std::allocator<add_symbol_file_command(const char*, int)::sect_opt>]’ at /usr/include/c++/13/debug/vector:228:23,
    inlined from ‘void add_symbol_file_command(const char*, int)’ at /home/smarchi/src/wt/amd/gdb/symfile.c:2224:57:
/usr/include/c++/13/bits/stl_algobase.h:437:30: error: ‘void* __builtin_memmove(void*, const void*, long unsigned int)’ forming offset 16 is out of the bounds [0, 16] [-Werror=array-bounds=]
  437 |             __builtin_memmove(__result, __first, sizeof(_Tp) * _Num);
      |             ~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


I don't know if it's useful, but I have a creduced version of the file I'll attach.
Comment 5 Simon Marchi 2024-08-05 13:38:04 UTC
Created attachment 58840 [details]
creduced example

To build the creduced example:

$ g++ -x c++ -Wall -Werror -g3 -O2 -c creduced.cpp

Note that I didn't include -D_GLIBCXX_DEBUG here.  I still see the error, perhaps it means my libstdc++ has _GLIBCXX_ASSERTIONS enabled by default like Sam, not sure.

There are a bunch of other errors, but the last one is the same as I pasted before:

creduced.cpp:45:24: error: ‘void* __builtin_memmove(void*, const void*, long unsigned int)’ forming offset 16 is out of the bounds [0, 16] [-Werror=array-bounds=]
   45 |       __builtin_memmove(db, cm, sizeof(c) * dc);
      |       ~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~

Note: I don't know if this is actually a bug, I don't understand what's going on, it just looks like one of those -Warray-bounds false positives.  And if it's not a -Warray-bounds bug, then it means it's probably a libstdc++ bug, so a bug either way.