https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117204
Bug ID: 117204 Summary: [12/13/14/15 regression] After r12-2132-ga1108556677, bogus -Warray-bounds warnings in std::vector::back() Product: gcc Version: 15.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: dimi...@unified-streaming.com Target Milestone: --- We noticed spurious -Warray-bounds warnings in some C++20 code compiled with g++ 13, and I bisected it to commit r12-2132-ga1108556677 ("Correct handling of variable offset minus constant in -Warray-bounds [PR100137]"), also meant to resolve bug 97027, bug 99121 and bug 100137. Minimized test case: ---------------------------------------------------------------------- // g++ -std=c++20 -Wall -O2 -c splice-min.cpp template <typename> struct allocator; template <typename> struct allocator_traits; template <typename _Tp> struct allocator_traits<allocator<_Tp>> { using value_type = _Tp; using pointer = _Tp *; template <typename _Up> using rebind_alloc = allocator<_Up>; }; template <typename _Alloc> struct __alloc_traits : allocator_traits<_Alloc> { typedef allocator_traits<_Alloc> _Base_type; typedef _Base_type::value_type reference; template <typename _Tp> struct rebind { typedef _Base_type::template rebind_alloc<_Tp> other; }; }; int nullopt, timescale_, add_chunk_duration = timescale_, __trans_tmp_1, chunker_next_media_segment; struct optional { template <typename _Up> optional(_Up); operator bool(); }; template <typename _Tp, typename _Alloc> struct _Vector_base { typedef __alloc_traits<_Alloc>::template rebind<_Tp>::other _Tp_alloc_type; typedef __alloc_traits<_Tp_alloc_type>::pointer pointer; struct { pointer _M_finish; } _M_impl; }; template <typename _Tp, typename _Alloc = allocator<_Tp>> struct vector : _Vector_base<_Tp, _Alloc> { typedef _Vector_base<_Tp, _Alloc> _Base; typedef _Base::pointer iterator; using _Base::_M_impl; vector(); vector(vector &) { _M_impl._M_finish = 0; } __alloc_traits<typename _Base::_Tp_alloc_type>::reference back() { iterator __trans_tmp_5 = _M_impl._M_finish, __trans_tmp_2 = __trans_tmp_5; return *(__trans_tmp_2 - 1); } }; struct timespan_t { unsigned get_end(); }; enum gap_t {}; struct tdr_t { void end_time(); long time_; long duration_; gap_t gap_; }; struct fragment_timeline_t { void append(long, long) { tdr_t last = times_.back(); last.end_time(); } vector<tdr_t> times_; }; vector<fragment_timeline_t> timelines_; struct chunk_t { long time_; } __trans_tmp_3, chunker_chunk = __trans_tmp_3; struct collector_t { collector_t(long); bool add_chunk(chunk_t chunk) { fragment_timeline_t __trans_tmp_4; auto time = chunk.time_; __trans_tmp_4 = timelines_.back(); __trans_tmp_4.append(time, add_chunk_duration); return true; } }; struct unpack_t { unpack_t(int); optional operator()(); }; timespan_t chunker_timespan; unsigned int chunker_end = chunker_timespan.get_end(); int chunker() { unpack_t unpack(chunker_next_media_segment), opt_curr = unpack; collector_t collector(0); auto opt_next = unpack(); auto get_chunk = [&]() -> optional { if (opt_next) { auto chunk = opt_curr; return chunk; } return nullopt; }; while (get_chunk()) { if (chunker_end) collector.add_chunk(chunker_chunk); } return __trans_tmp_1; } ---------------------------------------------------------------------- $ ~/ins/gcc-12-2131-g6278065af07/bin/g++ -std=c++20 -Wall -O2 -c splice-min.cpp <silent> $ ~/ins/gcc-12-2132-ga1108556677/bin/g++ -std=c++20 -Wall -O2 -c splice-min.cpp In member function 'typename __alloc_traits<typename _Vector_base<_Tp, _Alloc>::_Tp_alloc_type>::reference vector<_Tp, _Alloc>::back() [with _Tp = tdr_t; _Alloc = allocator<tdr_t>]', inlined from 'void fragment_timeline_t::append(long int, long int)' at splice-min.cpp:53:29, inlined from 'bool collector_t::add_chunk(chunk_t)' at splice-min.cpp:68:25, inlined from 'int chunker()' at splice-min.cpp:91:26: splice-min.cpp:38:31: warning: array subscript -1 is outside array bounds of 'tdr_t [384307168202282325]' [-Warray-bounds] 38 | return *(__trans_tmp_2 - 1); | ^ Especially the value 384307168202282325, which corresponds to 0x555555555555555, is suspect. I am guessing that gcc is accessing some uninitialized memory here, which was pre-filled with 0x55 bytes by the allocator?