public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/111273] New: Spurious array-bounds error when copying data using _GLIBCXX_DEBUG iterators
@ 2023-09-01 21:16 jgrossma at qti dot qualcomm.com
  2023-09-02 21:03 ` [Bug tree-optimization/111273] " redi at gcc dot gnu.org
  2023-09-03 12:06 ` jgrossma at qti dot qualcomm.com
  0 siblings, 2 replies; 3+ messages in thread
From: jgrossma at qti dot qualcomm.com @ 2023-09-01 21:16 UTC (permalink / raw)
  To: gcc-bugs

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

            Bug ID: 111273
           Summary: Spurious array-bounds error when copying data using
                    _GLIBCXX_DEBUG iterators
           Product: gcc
           Version: 13.2.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: jgrossma at qti dot qualcomm.com
  Target Milestone: ---

When compiling with -Warray-bounds and -D_GLIBCXX_DEBUG on g++ 13.2.0, copying
from a vector to an array throws the Warray-bounds error during compilation.

Source:

#include <vector>
#include <array>
#include <algorithm>

static const int N = 1;

int func(std::vector<int> const &v) {
    std::array<int, N> a;
    std::copy_n(v.begin(), N, a.begin());
    return a[0];
}


Program should not have any problems at compile time. Copies 1 location to a 1
element array. Changing N=2 doesn't show the error. 

Compile options:

-Werror -O3 -Warray-bounds -D_GLIBCXX_DEBUG -std=c++20


Disabling -D_GLIBCXX_DEBUG doesn't show the error.


Output:

---

In file included from
/opt/compiler-explorer/gcc-13.2.0/include/c++/13.2.0/vector:62,
                 from <source>:1:
In static member function 'static constexpr _Up* std::__copy_move<_IsMove,
true, std::random_access_iterator_tag>::__copy_m(_Tp*, _Tp*, _Up*) [with _Tp =
const int; _Up = int; bool _IsMove = false]',
    inlined from 'constexpr _OI std::__copy_move_a2(_II, _II, _OI) [with bool
_IsMove = false; _II = const int*; _OI = int*]' at
/opt/compiler-explorer/gcc-13.2.0/include/c++/13.2.0/bits/stl_algobase.h:506:30,
    inlined from 'constexpr _OI std::__copy_move_a1(_II, _II, _OI) [with bool
_IsMove = false; _II = const int*; _OI = int*]' at
/opt/compiler-explorer/gcc-13.2.0/include/c++/13.2.0/bits/stl_algobase.h:533:42,
    inlined from 'constexpr _OI std::__copy_move_a(_II, _II, _OI) [with bool
_IsMove = false; _II = __gnu_cxx::__normal_iterator<const int*,
__cxx1998::vector<int, allocator<int> > >; _OI = int*]' at
/opt/compiler-explorer/gcc-13.2.0/include/c++/13.2.0/bits/stl_algobase.h:540:31,
    inlined from '_OI std::__copy_move_a(const
__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>&, const
__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>&, _OI) [with bool _IsMove =
false; _Ite = __gnu_cxx::__normal_iterator<const int*, __cxx1998::vector<int,
allocator<int> > >; _Seq = __debug::vector<int>; _Cat =
random_access_iterator_tag; _OI = int*]' at
/opt/compiler-explorer/gcc-13.2.0/include/c++/13.2.0/debug/safe_iterator.tcc:257:36,
    inlined from 'constexpr _OI std::copy(_II, _II, _OI) [with _II =
__gnu_debug::_Safe_iterator<__gnu_cxx::__normal_iterator<const int*,
__cxx1998::vector<int, allocator<int> > >, __debug::vector<int>,
random_access_iterator_tag>; _OI = int*]' at
/opt/compiler-explorer/gcc-13.2.0/include/c++/13.2.0/bits/stl_algobase.h:633:7,
    inlined from 'constexpr _OutputIterator
std::__copy_n(_RandomAccessIterator, _Size, _OutputIterator,
random_access_iterator_tag) [with _RandomAccessIterator =
__gnu_debug::_Safe_iterator<__gnu_cxx::__normal_iterator<const int*,
__cxx1998::vector<int, allocator<int> > >, __debug::vector<int>,
random_access_iterator_tag>; _Size = int; _OutputIterator = int*]' at
/opt/compiler-explorer/gcc-13.2.0/include/c++/13.2.0/bits/stl_algo.h:731:23,
    inlined from 'constexpr _OIter std::copy_n(_IIter, _Size, _OIter) [with
_IIter = __gnu_debug::_Safe_iterator<__gnu_cxx::__normal_iterator<const int*,
__cxx1998::vector<int, allocator<int> > >, __debug::vector<int>,
random_access_iterator_tag>; _Size = int; _OIter = int*]' at
/opt/compiler-explorer/gcc-13.2.0/include/c++/13.2.0/bits/stl_algo.h:763:27,
    inlined from 'int func(const std::__debug::vector<int>&)' at <source>:9:16:
/opt/compiler-explorer/gcc-13.2.0/include/c++/13.2.0/bits/stl_algobase.h:437:30:
error: 'void* __builtin_memcpy(void*, const void*, long unsigned int)' forming
offset 4 is out of the bounds [0, 4] of object 'a' with type 'std::array<int,
1>' [-Werror=array-bounds=]
  437 |             __builtin_memmove(__result, __first, sizeof(_Tp) * _Num);
      |             ~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>: In function 'int func(const std::__debug::vector<int>&)':
<source>:8:24: note: 'a' declared here
    8 |     std::array<int, N> a;
      |                        ^
cc1plus: all warnings being treated as errors
Compiler returned: 1

---

Interestingly, the error location should not even be hit for a 1 element copy
as it's inside a check for length>1.


Godbolt link shows as well: https://godbolt.org/z/v8GK4nzde


GCC 12 does not seem to show this issue.

Seems related to this one: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107852

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

* [Bug tree-optimization/111273] Spurious array-bounds error when copying data using _GLIBCXX_DEBUG iterators
  2023-09-01 21:16 [Bug c++/111273] New: Spurious array-bounds error when copying data using _GLIBCXX_DEBUG iterators jgrossma at qti dot qualcomm.com
@ 2023-09-02 21:03 ` redi at gcc dot gnu.org
  2023-09-03 12:06 ` jgrossma at qti dot qualcomm.com
  1 sibling, 0 replies; 3+ messages in thread
From: redi at gcc dot gnu.org @ 2023-09-02 21:03 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #1 from Jonathan Wakely <redi at gcc dot gnu.org> ---
That's not an error, it's a warning.

It's only an error because you asked for it to be an error.

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

* [Bug tree-optimization/111273] Spurious array-bounds error when copying data using _GLIBCXX_DEBUG iterators
  2023-09-01 21:16 [Bug c++/111273] New: Spurious array-bounds error when copying data using _GLIBCXX_DEBUG iterators jgrossma at qti dot qualcomm.com
  2023-09-02 21:03 ` [Bug tree-optimization/111273] " redi at gcc dot gnu.org
@ 2023-09-03 12:06 ` jgrossma at qti dot qualcomm.com
  1 sibling, 0 replies; 3+ messages in thread
From: jgrossma at qti dot qualcomm.com @ 2023-09-03 12:06 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #2 from J Grossman <jgrossma at qti dot qualcomm.com> ---
@Jonathan whether it's a warning or an error, it's incorrect. I'm filling a 1
element array with 1 element and it's saying it's out of bounds. That's a bug.

I would like to use -Warray-bounds to catch coding mistakes, but to do that it
needs to be reliable. Whether it's a warning or an error, if if there are
false-positives, I have no choice but to turn it off. (And it's not like
Wmaybe-uninitialized where if there is a false-positive, there's an easy
workaround. If Warray-bounds has a false-positive, what can I do?) I've
disabled -Warray-bounds to move forward, but that means some illegal operations
that GCC could catch for us are going to go uncaught.

If a warning option like this isn't reliable, people can't use it.


BTW, if you disable Warray-bounds and add Wstringop-overflow, you get this for
the same code:

error: 'void* __builtin_memcpy(void*, const void*, long unsigned int)' writing
between 5 and 9223372036854775807 bytes into a region of size 4 overflows the
destination [-Werror=stringop-overflow=]
  437 |             __builtin_memmove(__result, __first, sizeof(_Tp) * _Num);

https://godbolt.org/z/T5W95hahx

So I need to disable both.


Once again, the code path here through `std::copy_n` is *incorrect*. It is in
the "length > 1" section of memcpy, but I'm only moving 1 element, and in fact,
when I set the size to 2, the warning/error disappears.

Things that eliminate the error:

- Using O2 instead of O3
- Using regular STL containers instead of GLIBCXX_DEBUG containers
- Using size > 1 for the array
- GCC 12, though I see similar spurious errors in GCC 12 as well, but not on
this exact code

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

end of thread, other threads:[~2023-09-03 12:06 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-09-01 21:16 [Bug c++/111273] New: Spurious array-bounds error when copying data using _GLIBCXX_DEBUG iterators jgrossma at qti dot qualcomm.com
2023-09-02 21:03 ` [Bug tree-optimization/111273] " redi at gcc dot gnu.org
2023-09-03 12:06 ` jgrossma at qti dot qualcomm.com

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).