public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/107252] New: False positive stringop-overflow, warning disappears if I remove unrelated code!
@ 2022-10-13 15:51 carlosgalvezp at gmail dot com
  2022-10-13 15:55 ` [Bug tree-optimization/107252] " pinskia at gcc dot gnu.org
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: carlosgalvezp at gmail dot com @ 2022-10-13 15:51 UTC (permalink / raw)
  To: gcc-bugs

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

            Bug ID: 107252
           Summary: False positive stringop-overflow, warning disappears
                    if I remove unrelated code!
           Product: gcc
           Version: 13.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: carlosgalvezp at gmail dot com
  Target Milestone: ---

Created attachment 53702
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=53702&action=edit
Preprocessed source

Hi, 

I'm getting a false positive in the following reduced example (preprocessed
source attached):

#include <gmock/gmock.h>
#include <gtest/gtest.h>


class Test : public ::testing::Test
{
 public:
    std::vector<std::uint8_t> x_{};
};

struct Bar
{
    std::vector<std::uint8_t> a;
    std::vector<std::uint8_t> b;
};

TEST_F(Test, Test1)
{
    const std::vector<std::uint8_t> x{1};
    const std::vector<std::uint8_t> y(2, 1);

    std::vector<std::uint8_t> z;
    z.insert(z.end(), x.begin(),x.end());

    Bar bar{};
    bar.a = z;
}

TEST_F(Test, Test2)
{
    const std::vector<std::uint8_t> z{
        1, 2, 3, 4, 5, 6,
        7, 8, 9, 10, 11, 12,
        13, 14, 15, 16, 17, 18,
        19, 20, 21, 22, 23, 24,
        25, 26
    };
    Bar bar{};
    bar.a = x_;
}


In file included from
/opt/compiler-explorer/gcc-trunk-20221013/include/c++/13.0.0/algorithm:60,
                 from
/opt/compiler-explorer/libs/googletest/trunk/googlemock/include/gmock/gmock-actions.h:137,
                 from
/opt/compiler-explorer/libs/googletest/trunk/googlemock/include/gmock/gmock.h:56,
                 from <source>:1:
In static member function 'static _Tp* std::__copy_move<_IsMove, true,
std::random_access_iterator_tag>::__copy_m(const _Tp*, const _Tp*, _Tp*) [with
_Tp = unsigned char; bool _IsMove = true]',
    inlined from '_OI std::__copy_move_a2(_II, _II, _OI) [with bool _IsMove =
true; _II = unsigned char*; _OI = unsigned char*]' at
/opt/compiler-explorer/gcc-trunk-20221013/include/c++/13.0.0/bits/stl_algobase.h:497:30,
    inlined from '_OI std::__copy_move_a1(_II, _II, _OI) [with bool _IsMove =
true; _II = unsigned char*; _OI = unsigned char*]' at
/opt/compiler-explorer/gcc-trunk-20221013/include/c++/13.0.0/bits/stl_algobase.h:524:42,
    inlined from '_OI std::__copy_move_a(_II, _II, _OI) [with bool _IsMove =
true; _II = unsigned char*; _OI = unsigned char*]' at
/opt/compiler-explorer/gcc-trunk-20221013/include/c++/13.0.0/bits/stl_algobase.h:531:31,
    inlined from '_OI std::copy(_II, _II, _OI) [with _II =
move_iterator<unsigned char*>; _OI = unsigned char*]' at
/opt/compiler-explorer/gcc-trunk-20221013/include/c++/13.0.0/bits/stl_algobase.h:624:7,
    inlined from 'static _ForwardIterator
std::__uninitialized_copy<true>::__uninit_copy(_InputIterator, _InputIterator,
_ForwardIterator) [with _InputIterator = std::move_iterator<unsigned char*>;
_ForwardIterator = unsigned char*]' at
/opt/compiler-explorer/gcc-trunk-20221013/include/c++/13.0.0/bits/stl_uninitialized.h:147:27,
    inlined from '_ForwardIterator std::uninitialized_copy(_InputIterator,
_InputIterator, _ForwardIterator) [with _InputIterator = move_iterator<unsigned
char*>; _ForwardIterator = unsigned char*]' at
/opt/compiler-explorer/gcc-trunk-20221013/include/c++/13.0.0/bits/stl_uninitialized.h:185:15,
    inlined from '_ForwardIterator std::__uninitialized_copy_a(_InputIterator,
_InputIterator, _ForwardIterator, allocator<_Tp>&) [with _InputIterator =
move_iterator<unsigned char*>; _ForwardIterator = unsigned char*; _Tp =
unsigned char]' at
/opt/compiler-explorer/gcc-trunk-20221013/include/c++/13.0.0/bits/stl_uninitialized.h:373:37,
    inlined from '_ForwardIterator
std::__uninitialized_move_if_noexcept_a(_InputIterator, _InputIterator,
_ForwardIterator, _Allocator&) [with _InputIterator = unsigned char*;
_ForwardIterator = unsigned char*; _Allocator = allocator<unsigned char>]' at
/opt/compiler-explorer/gcc-trunk-20221013/include/c++/13.0.0/bits/stl_uninitialized.h:399:2,
    inlined from 'void std::vector<_Tp, _Alloc>::_M_range_insert(iterator,
_ForwardIterator, _ForwardIterator, std::forward_iterator_tag) [with
_ForwardIterator = __gnu_cxx::__normal_iterator<const unsigned char*,
std::vector<unsigned char> >; _Tp = unsigned char; _Alloc =
std::allocator<unsigned char>]' at
/opt/compiler-explorer/gcc-trunk-20221013/include/c++/13.0.0/bits/vector.tcc:801:9,
    inlined from 'void std::vector<_Tp, _Alloc>::_M_insert_dispatch(iterator,
_InputIterator, _InputIterator, std::__false_type) [with _InputIterator =
__gnu_cxx::__normal_iterator<const unsigned char*, std::vector<unsigned char>
>; _Tp = unsigned char; _Alloc = std::allocator<unsigned char>]' at
/opt/compiler-explorer/gcc-trunk-20221013/include/c++/13.0.0/bits/stl_vector.h:1779:19,
    inlined from 'std::vector<_Tp, _Alloc>::iterator std::vector<_Tp,
_Alloc>::insert(const_iterator, _InputIterator, _InputIterator) [with
_InputIterator = __gnu_cxx::__normal_iterator<const unsigned char*,
std::vector<unsigned char> >; <template-parameter-2-2> = void; _Tp = unsigned
char; _Alloc = std::allocator<unsigned char>]' at
/opt/compiler-explorer/gcc-trunk-20221013/include/c++/13.0.0/bits/stl_vector.h:1481:22,
    inlined from 'virtual void Test_Test1_Test::TestBody()' at <source>:23:13:
/opt/compiler-explorer/gcc-trunk-20221013/include/c++/13.0.0/bits/stl_algobase.h:431:30:
warning: 'void* __builtin_memcpy(void*, const void*, long unsigned int)'
writing 1 or more bytes into a region of size 0 overflows the destination
[-Wstringop-overflow=]
  431 |             __builtin_memmove(__result, __first, sizeof(_Tp) * _Num);
      |             ~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from
/opt/compiler-explorer/gcc-trunk-20221013/include/c++/13.0.0/x86_64-linux-gnu/bits/c++allocator.h:33,
                 from
/opt/compiler-explorer/gcc-trunk-20221013/include/c++/13.0.0/bits/allocator.h:46,
                 from
/opt/compiler-explorer/gcc-trunk-20221013/include/c++/13.0.0/memory:65,
                 from
/opt/compiler-explorer/libs/googletest/trunk/googlemock/include/gmock/gmock-actions.h:139:
In member function '_Tp* std::__new_allocator<_Tp>::allocate(size_type, const
void*) [with _Tp = unsigned char]',
    inlined from 'static _Tp* std::allocator_traits<std::allocator<_Tp1>
>::allocate(allocator_type&, size_type) [with _Tp = unsigned char]' at
/opt/compiler-explorer/gcc-trunk-20221013/include/c++/13.0.0/bits/alloc_traits.h:468:28,
    inlined from 'std::_Vector_base<_Tp, _Alloc>::pointer
std::_Vector_base<_Tp, _Alloc>::_M_allocate(std::size_t) [with _Tp = unsigned
char; _Alloc = std::allocator<unsigned char>]' at
/opt/compiler-explorer/gcc-trunk-20221013/include/c++/13.0.0/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 = __gnu_cxx::__normal_iterator<const unsigned char*,
std::vector<unsigned char> >; _Tp = unsigned char; _Alloc =
std::allocator<unsigned char>]' at
/opt/compiler-explorer/gcc-trunk-20221013/include/c++/13.0.0/bits/vector.tcc:787:40,
    inlined from 'void std::vector<_Tp, _Alloc>::_M_insert_dispatch(iterator,
_InputIterator, _InputIterator, std::__false_type) [with _InputIterator =
__gnu_cxx::__normal_iterator<const unsigned char*, std::vector<unsigned char>
>; _Tp = unsigned char; _Alloc = std::allocator<unsigned char>]' at
/opt/compiler-explorer/gcc-trunk-20221013/include/c++/13.0.0/bits/stl_vector.h:1779:19,
    inlined from 'std::vector<_Tp, _Alloc>::iterator std::vector<_Tp,
_Alloc>::insert(const_iterator, _InputIterator, _InputIterator) [with
_InputIterator = __gnu_cxx::__normal_iterator<const unsigned char*,
std::vector<unsigned char> >; <template-parameter-2-2> = void; _Tp = unsigned
char; _Alloc = std::allocator<unsigned char>]' at
/opt/compiler-explorer/gcc-trunk-20221013/include/c++/13.0.0/bits/stl_vector.h:1481:22,
    inlined from 'virtual void Test_Test1_Test::TestBody()' at <source>:23:13:
/opt/compiler-explorer/gcc-trunk-20221013/include/c++/13.0.0/bits/new_allocator.h:144:55:
note: at offset 1 into destination object of size 1 allocated by 'operator new'
  144 |         return static_cast<_Tp*>(_GLIBCXX_OPERATOR_NEW(__n *
sizeof(_Tp)));
      |                                                       ^
In static member function 'static _Tp* std::__copy_move<_IsMove, true,
std::random_access_iterator_tag>::__copy_m(const _Tp*, const _Tp*, _Tp*) [with
_Tp = unsigned char; bool _IsMove = true]',
    inlined from '_OI std::__copy_move_a2(_II, _II, _OI) [with bool _IsMove =
true; _II = unsigned char*; _OI = unsigned char*]' at
/opt/compiler-explorer/gcc-trunk-20221013/include/c++/13.0.0/bits/stl_algobase.h:497:30,
    inlined from '_OI std::__copy_move_a1(_II, _II, _OI) [with bool _IsMove =
true; _II = unsigned char*; _OI = unsigned char*]' at
/opt/compiler-explorer/gcc-trunk-20221013/include/c++/13.0.0/bits/stl_algobase.h:524:42,
    inlined from '_OI std::__copy_move_a(_II, _II, _OI) [with bool _IsMove =
true; _II = unsigned char*; _OI = unsigned char*]' at
/opt/compiler-explorer/gcc-trunk-20221013/include/c++/13.0.0/bits/stl_algobase.h:531:31,
    inlined from '_OI std::copy(_II, _II, _OI) [with _II =
move_iterator<unsigned char*>; _OI = unsigned char*]' at
/opt/compiler-explorer/gcc-trunk-20221013/include/c++/13.0.0/bits/stl_algobase.h:624:7,
    inlined from 'static _ForwardIterator
std::__uninitialized_copy<true>::__uninit_copy(_InputIterator, _InputIterator,
_ForwardIterator) [with _InputIterator = std::move_iterator<unsigned char*>;
_ForwardIterator = unsigned char*]' at
/opt/compiler-explorer/gcc-trunk-20221013/include/c++/13.0.0/bits/stl_uninitialized.h:147:27,
    inlined from '_ForwardIterator std::uninitialized_copy(_InputIterator,
_InputIterator, _ForwardIterator) [with _InputIterator = move_iterator<unsigned
char*>; _ForwardIterator = unsigned char*]' at
/opt/compiler-explorer/gcc-trunk-20221013/include/c++/13.0.0/bits/stl_uninitialized.h:185:15,
    inlined from '_ForwardIterator std::__uninitialized_copy_a(_InputIterator,
_InputIterator, _ForwardIterator, allocator<_Tp>&) [with _InputIterator =
move_iterator<unsigned char*>; _ForwardIterator = unsigned char*; _Tp =
unsigned char]' at
/opt/compiler-explorer/gcc-trunk-20221013/include/c++/13.0.0/bits/stl_uninitialized.h:373:37,
    inlined from '_ForwardIterator
std::__uninitialized_move_if_noexcept_a(_InputIterator, _InputIterator,
_ForwardIterator, _Allocator&) [with _InputIterator = unsigned char*;
_ForwardIterator = unsigned char*; _Allocator = allocator<unsigned char>]' at
/opt/compiler-explorer/gcc-trunk-20221013/include/c++/13.0.0/bits/stl_uninitialized.h:399:2,
    inlined from 'void std::vector<_Tp, _Alloc>::_M_range_insert(iterator,
_ForwardIterator, _ForwardIterator, std::forward_iterator_tag) [with
_ForwardIterator = __gnu_cxx::__normal_iterator<const unsigned char*,
std::vector<unsigned char> >; _Tp = unsigned char; _Alloc =
std::allocator<unsigned char>]' at
/opt/compiler-explorer/gcc-trunk-20221013/include/c++/13.0.0/bits/vector.tcc:801:9,
    inlined from 'void std::vector<_Tp, _Alloc>::_M_insert_dispatch(iterator,
_InputIterator, _InputIterator, std::__false_type) [with _InputIterator =
__gnu_cxx::__normal_iterator<const unsigned char*, std::vector<unsigned char>
>; _Tp = unsigned char; _Alloc = std::allocator<unsigned char>]' at
/opt/compiler-explorer/gcc-trunk-20221013/include/c++/13.0.0/bits/stl_vector.h:1779:19,
    inlined from 'std::vector<_Tp, _Alloc>::iterator std::vector<_Tp,
_Alloc>::insert(const_iterator, _InputIterator, _InputIterator) [with
_InputIterator = __gnu_cxx::__normal_iterator<const unsigned char*,
std::vector<unsigned char> >; <template-parameter-2-2> = void; _Tp = unsigned
char; _Alloc = std::allocator<unsigned char>]' at
/opt/compiler-explorer/gcc-trunk-20221013/include/c++/13.0.0/bits/stl_vector.h:1481:22,
    inlined from 'virtual void Test_Test1_Test::TestBody()' at <source>:23:13:
/opt/compiler-explorer/gcc-trunk-20221013/include/c++/13.0.0/bits/stl_algobase.h:431:30:
warning: 'void* __builtin_memcpy(void*, const void*, long unsigned int)'
writing 1 or more bytes into a region of size 0 overflows the destination
[-Wstringop-overflow=]
  431 |             __builtin_memmove(__result, __first, sizeof(_Tp) * _Num);
      |             ~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In member function '_Tp* std::__new_allocator<_Tp>::allocate(size_type, const
void*) [with _Tp = unsigned char]',
    inlined from 'static _Tp* std::allocator_traits<std::allocator<_Tp1>
>::allocate(allocator_type&, size_type) [with _Tp = unsigned char]' at
/opt/compiler-explorer/gcc-trunk-20221013/include/c++/13.0.0/bits/alloc_traits.h:468:28,
    inlined from 'std::_Vector_base<_Tp, _Alloc>::pointer
std::_Vector_base<_Tp, _Alloc>::_M_allocate(std::size_t) [with _Tp = unsigned
char; _Alloc = std::allocator<unsigned char>]' at
/opt/compiler-explorer/gcc-trunk-20221013/include/c++/13.0.0/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 = __gnu_cxx::__normal_iterator<const unsigned char*,
std::vector<unsigned char> >; _Tp = unsigned char; _Alloc =
std::allocator<unsigned char>]' at
/opt/compiler-explorer/gcc-trunk-20221013/include/c++/13.0.0/bits/vector.tcc:787:40,
    inlined from 'void std::vector<_Tp, _Alloc>::_M_insert_dispatch(iterator,
_InputIterator, _InputIterator, std::__false_type) [with _InputIterator =
__gnu_cxx::__normal_iterator<const unsigned char*, std::vector<unsigned char>
>; _Tp = unsigned char; _Alloc = std::allocator<unsigned char>]' at
/opt/compiler-explorer/gcc-trunk-20221013/include/c++/13.0.0/bits/stl_vector.h:1779:19,
    inlined from 'std::vector<_Tp, _Alloc>::iterator std::vector<_Tp,
_Alloc>::insert(const_iterator, _InputIterator, _InputIterator) [with
_InputIterator = __gnu_cxx::__normal_iterator<const unsigned char*,
std::vector<unsigned char> >; <template-parameter-2-2> = void; _Tp = unsigned
char; _Alloc = std::allocator<unsigned char>]' at
/opt/compiler-explorer/gcc-trunk-20221013/include/c++/13.0.0/bits/stl_vector.h:1481:22,
    inlined from 'virtual void Test_Test1_Test::TestBody()' at <source>:23:13:
/opt/compiler-explorer/gcc-trunk-20221013/include/c++/13.0.0/bits/new_allocator.h:144:55:
note: at offset 1 into destination object of size 1 allocated by 'operator new'
  144 |         return static_cast<_Tp*>(_GLIBCXX_OPERATOR_NEW(__n *
sizeof(_Tp)));
      |          


Compiling with flags: 
-std=c++14 -Wall -Wextra -pedantic -O3 -D_FORTIFY_SOURCE=1 

Reproducible on Compiler Explorer: https://godbolt.org/z/3qs33fq9o

If I remove anything that is not in use in this file, even if it's in a
separate function, then the warning is gone. This tells me there must be
something fishy going on.

Do you have any hints as to what's happening? It looks totally random to me!

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [Bug tree-optimization/107252] False positive stringop-overflow, warning disappears if I remove unrelated code!
  2022-10-13 15:51 [Bug c++/107252] New: False positive stringop-overflow, warning disappears if I remove unrelated code! carlosgalvezp at gmail dot com
@ 2022-10-13 15:55 ` pinskia at gcc dot gnu.org
  2022-10-13 17:03 ` carlosgalvezp at gmail dot com
  2022-10-13 17:06 ` pinskia at gcc dot gnu.org
  2 siblings, 0 replies; 4+ messages in thread
From: pinskia at gcc dot gnu.org @ 2022-10-13 15:55 UTC (permalink / raw)
  To: gcc-bugs

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

Andrew Pinski <pinskia at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |diagnostic
          Component|c++                         |tree-optimization

--- Comment #1 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
I suspect inlining heuristics kick in differently when you remove unused code.

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [Bug tree-optimization/107252] False positive stringop-overflow, warning disappears if I remove unrelated code!
  2022-10-13 15:51 [Bug c++/107252] New: False positive stringop-overflow, warning disappears if I remove unrelated code! carlosgalvezp at gmail dot com
  2022-10-13 15:55 ` [Bug tree-optimization/107252] " pinskia at gcc dot gnu.org
@ 2022-10-13 17:03 ` carlosgalvezp at gmail dot com
  2022-10-13 17:06 ` pinskia at gcc dot gnu.org
  2 siblings, 0 replies; 4+ messages in thread
From: carlosgalvezp at gmail dot com @ 2022-10-13 17:03 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #2 from Carlos Galvez <carlosgalvezp at gmail dot com> ---
To clarify, even removing things from the second function has an impact on the
first function (which is where the warning comes from). Shouldn't both
functions be independent?

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [Bug tree-optimization/107252] False positive stringop-overflow, warning disappears if I remove unrelated code!
  2022-10-13 15:51 [Bug c++/107252] New: False positive stringop-overflow, warning disappears if I remove unrelated code! carlosgalvezp at gmail dot com
  2022-10-13 15:55 ` [Bug tree-optimization/107252] " pinskia at gcc dot gnu.org
  2022-10-13 17:03 ` carlosgalvezp at gmail dot com
@ 2022-10-13 17:06 ` pinskia at gcc dot gnu.org
  2 siblings, 0 replies; 4+ messages in thread
From: pinskia at gcc dot gnu.org @ 2022-10-13 17:06 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #3 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
(In reply to Carlos Galvez from comment #2)
> To clarify, even removing things from the second function has an impact on
> the first function (which is where the warning comes from). Shouldn't both
> functions be independent?

No because inlining heuristics takes into account the whole translation unit so
removing things changes how much inlining happens or where it happens (etc.).

The diagnostic with the warning is dependent on the inlining and optimization.

Someone will need to look into the debug dumps to understand what exactly is
going on though.

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2022-10-13 17:06 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-10-13 15:51 [Bug c++/107252] New: False positive stringop-overflow, warning disappears if I remove unrelated code! carlosgalvezp at gmail dot com
2022-10-13 15:55 ` [Bug tree-optimization/107252] " pinskia at gcc dot gnu.org
2022-10-13 17:03 ` carlosgalvezp at gmail dot com
2022-10-13 17:06 ` pinskia at gcc dot gnu.org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).