Fedora Account System
Red Hat Associate
Red Hat Customer
This occurs with gcc-16.1.1-2.fc44.x86_64 at O2 and above. Testing on godbolt reproduces it in gcc 16 and trunk but not in gcc 15. As best I can tell the summary is that constructing a std::shared_ptr with a custom free function and then later constructing one for a different type that doesn't use a custom free function causes bogus array bounds warnings in that second pointer's destructor. Reproducible: Always Steps to Reproduce: 1. Save the attached file as test.cpp and compile with "g++ -std=c++23 -O2 -Wall -Werror test.cpp" Actual Results: In file included from /usr/include/c++/16/bits/shared_ptr.h:53, from /usr/include/c++/16/memory:82, from test.cpp:1: In member function ‘void std::_Sp_counted_deleter<_Ptr, _Deleter, _Alloc, _Lp>::_M_dispose() [with _Ptr = value*; _Deleter = void (*)(value*); _Alloc = std::allocator<void>; __gnu_cxx::_Lock_policy _Lp = __gnu_cxx::_S_atomic]’, inlined from ‘void std::_Sp_counted_base<_Lp>::_M_release() [with __gnu_cxx::_Lock_policy _Lp = __gnu_cxx::_S_atomic]’ at /usr/include/c++/16/bits/shared_ptr_base.h:423:18, inlined from ‘void std::_Sp_counted_base<_Lp>::_M_release() [with __gnu_cxx::_Lock_policy _Lp = __gnu_cxx::_S_atomic]’ at /usr/include/c++/16/bits/shared_ptr_base.h:392:5, inlined from ‘std::__shared_count<_Lp>::~__shared_count() [with __gnu_cxx::_Lock_policy _Lp = __gnu_cxx::_S_atomic]’ at /usr/include/c++/16/bits/shared_ptr_base.h:1136:21, inlined from ‘std::__shared_ptr<_Tp, _Lp>::~__shared_ptr() [with _Tp = baz; __gnu_cxx::_Lock_policy _Lp = __gnu_cxx::_S_atomic]’ at /usr/include/c++/16/bits/shared_ptr_base.h:1610:7, inlined from ‘std::shared_ptr<baz>::~shared_ptr()’ at /usr/include/c++/16/bits/shared_ptr.h:175:11, inlined from ‘void bar()’ at test.cpp:27:1: /usr/include/c++/16/bits/shared_ptr_base.h:590:25: error: array subscript ‘std::_Sp_counted_deleter<value*, void (*)(value*), std::allocator<void>, __gnu_cxx::_S_atomic>[0]’ is partly outside array bounds of ‘unsigned char [24]’ [-Werror=array-bounds=] 590 | { _M_impl._M_del()(_M_impl._M_ptr); } | ~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~ In constructor ‘std::__shared_count<_Lp>::__shared_count(_Ptr) [with _Ptr = baz*; __gnu_cxx::_Lock_policy _Lp = __gnu_cxx::_S_atomic]’, inlined from ‘std::__shared_count<_Lp>::__shared_count(_Ptr, std::false_type) [with _Ptr = baz*; __gnu_cxx::_Lock_policy _Lp = __gnu_cxx::_S_atomic]’ at /usr/include/c++/16/bits/shared_ptr_base.h:992:22, inlined from ‘std::__shared_ptr<_Tp, _Lp>::__shared_ptr(_Yp*) [with _Yp = baz; <template-parameter-2-2> = void; _Tp = baz; __gnu_cxx::_Lock_policy _Lp = __gnu_cxx::_S_atomic]’ at /usr/include/c++/16/bits/shared_ptr_base.h:1555:17, inlined from ‘std::shared_ptr<_Tp>::shared_ptr(_Yp*) [with _Yp = baz; <template-parameter-2-2> = void; _Tp = baz]’ at /usr/include/c++/16/bits/shared_ptr.h:213:46, inlined from ‘void bar()’ at test.cpp:26:7: /usr/include/c++/16/bits/shared_ptr_base.h:981:23: note: object of size 24 allocated by ‘operator new’ 981 | _M_pi = new _Sp_counted_ptr<_Ptr, _Lp>(__p); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In destructor ‘std::_Sp_counted_deleter<_Ptr, _Deleter, _Alloc, _Lp>::~_Sp_counted_deleter() [with _Ptr = value*; _Deleter = void (*)(value*); _Alloc = std::allocator<void>; __gnu_cxx::_Lock_policy _Lp = __gnu_cxx::_S_atomic]’, inlined from ‘void std::_Sp_counted_deleter<_Ptr, _Deleter, _Alloc, _Lp>::_M_destroy() [with _Ptr = value*; _Deleter = void (*)(value*); _Alloc = std::allocator<void>; __gnu_cxx::_Lock_policy _Lp = __gnu_cxx::_S_atomic]’ at /usr/include/c++/16/bits/shared_ptr_base.h:597:28, inlined from ‘void std::_Sp_counted_base<_Lp>::_M_release() [with __gnu_cxx::_Lock_policy _Lp = __gnu_cxx::_S_atomic]’ at /usr/include/c++/16/bits/shared_ptr_base.h:424:18, inlined from ‘void std::_Sp_counted_base<_Lp>::_M_release() [with __gnu_cxx::_Lock_policy _Lp = __gnu_cxx::_S_atomic]’ at /usr/include/c++/16/bits/shared_ptr_base.h:392:5, inlined from ‘std::__shared_count<_Lp>::~__shared_count() [with __gnu_cxx::_Lock_policy _Lp = __gnu_cxx::_S_atomic]’ at /usr/include/c++/16/bits/shared_ptr_base.h:1136:21, inlined from ‘std::__shared_ptr<_Tp, _Lp>::~__shared_ptr() [with _Tp = baz; __gnu_cxx::_Lock_policy _Lp = __gnu_cxx::_S_atomic]’ at /usr/include/c++/16/bits/shared_ptr_base.h:1610:7, inlined from ‘std::shared_ptr<baz>::~shared_ptr()’ at /usr/include/c++/16/bits/shared_ptr.h:175:11, inlined from ‘void bar()’ at test.cpp:27:1: /usr/include/c++/16/bits/shared_ptr_base.h:585:41: error: array subscript ‘std::_Sp_counted_deleter<value*, void (*)(value*), std::allocator<void>, __gnu_cxx::_S_atomic>[0]’ is partly outside array bounds of ‘unsigned char [24]’ [-Werror=array-bounds=] 585 | ~_Sp_counted_deleter() noexcept { } | ^ In constructor ‘std::__shared_count<_Lp>::__shared_count(_Ptr) [with _Ptr = baz*; __gnu_cxx::_Lock_policy _Lp = __gnu_cxx::_S_atomic]’, inlined from ‘std::__shared_count<_Lp>::__shared_count(_Ptr, std::false_type) [with _Ptr = baz*; __gnu_cxx::_Lock_policy _Lp = __gnu_cxx::_S_atomic]’ at /usr/include/c++/16/bits/shared_ptr_base.h:992:22, inlined from ‘std::__shared_ptr<_Tp, _Lp>::__shared_ptr(_Yp*) [with _Yp = baz; <template-parameter-2-2> = void; _Tp = baz; __gnu_cxx::_Lock_policy _Lp = __gnu_cxx::_S_atomic]’ at /usr/include/c++/16/bits/shared_ptr_base.h:1555:17, inlined from ‘std::shared_ptr<_Tp>::shared_ptr(_Yp*) [with _Yp = baz; <template-parameter-2-2> = void; _Tp = baz]’ at /usr/include/c++/16/bits/shared_ptr.h:213:46, inlined from ‘void bar()’ at test.cpp:26:7: /usr/include/c++/16/bits/shared_ptr_base.h:981:23: note: object of size 24 allocated by ‘operator new’ 981 | _M_pi = new _Sp_counted_ptr<_Ptr, _Lp>(__p); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In destructor ‘std::_Sp_counted_deleter<_Ptr, _Deleter, _Alloc, _Lp>::~_Sp_counted_deleter() [with _Ptr = value*; _Deleter = void (*)(value*); _Alloc = std::allocator<void>; __gnu_cxx::_Lock_policy _Lp = __gnu_cxx::_S_atomic]’, inlined from ‘std::_Sp_counted_deleter<_Ptr, _Deleter, _Alloc, _Lp>::~_Sp_counted_deleter() [with _Ptr = value*; _Deleter = void (*)(value*); _Alloc = std::allocator<void>; __gnu_cxx::_Lock_policy _Lp = __gnu_cxx::_S_atomic]’ at /usr/include/c++/16/bits/shared_ptr_base.h:585:41, inlined from ‘void std::_Sp_counted_base<_Lp>::_M_destroy() [with __gnu_cxx::_Lock_policy _Lp = __gnu_cxx::_S_atomic]’ at /usr/include/c++/16/bits/shared_ptr_base.h:143:9, inlined from ‘void std::_Sp_counted_base<_Lp>::_M_release() [with __gnu_cxx::_Lock_policy _Lp = __gnu_cxx::_S_atomic]’ at /usr/include/c++/16/bits/shared_ptr_base.h:424:18, inlined from ‘void std::_Sp_counted_base<_Lp>::_M_release() [with __gnu_cxx::_Lock_policy _Lp = __gnu_cxx::_S_atomic]’ at /usr/include/c++/16/bits/shared_ptr_base.h:392:5, inlined from ‘std::__shared_count<_Lp>::~__shared_count() [with __gnu_cxx::_Lock_policy _Lp = __gnu_cxx::_S_atomic]’ at /usr/include/c++/16/bits/shared_ptr_base.h:1136:21, inlined from ‘std::__shared_ptr<_Tp, _Lp>::~__shared_ptr() [with _Tp = baz; __gnu_cxx::_Lock_policy _Lp = __gnu_cxx::_S_atomic]’ at /usr/include/c++/16/bits/shared_ptr_base.h:1610:7, inlined from ‘std::shared_ptr<baz>::~shared_ptr()’ at /usr/include/c++/16/bits/shared_ptr.h:175:11, inlined from ‘void bar()’ at test.cpp:27:1: /usr/include/c++/16/bits/shared_ptr_base.h:585:41: error: array subscript ‘std::_Sp_counted_deleter<value*, void (*)(value*), std::allocator<void>, __gnu_cxx::_S_atomic>[0]’ is partly outside array bounds of ‘unsigned char [24]’ [-Werror=array-bounds=] 585 | ~_Sp_counted_deleter() noexcept { } | ^ In constructor ‘std::__shared_count<_Lp>::__shared_count(_Ptr) [with _Ptr = baz*; __gnu_cxx::_Lock_policy _Lp = __gnu_cxx::_S_atomic]’, inlined from ‘std::__shared_count<_Lp>::__shared_count(_Ptr, std::false_type) [with _Ptr = baz*; __gnu_cxx::_Lock_policy _Lp = __gnu_cxx::_S_atomic]’ at /usr/include/c++/16/bits/shared_ptr_base.h:992:22, inlined from ‘std::__shared_ptr<_Tp, _Lp>::__shared_ptr(_Yp*) [with _Yp = baz; <template-parameter-2-2> = void; _Tp = baz; __gnu_cxx::_Lock_policy _Lp = __gnu_cxx::_S_atomic]’ at /usr/include/c++/16/bits/shared_ptr_base.h:1555:17, inlined from ‘std::shared_ptr<_Tp>::shared_ptr(_Yp*) [with _Yp = baz; <template-parameter-2-2> = void; _Tp = baz]’ at /usr/include/c++/16/bits/shared_ptr.h:213:46, inlined from ‘void bar()’ at test.cpp:26:7: /usr/include/c++/16/bits/shared_ptr_base.h:981:23: note: object of size 24 allocated by ‘operator new’ 981 | _M_pi = new _Sp_counted_ptr<_Ptr, _Lp>(__p); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ cc1plus: all warnings being treated as errors Expected Results: File compiles.
Created attachment 2152817 [details] Test case
I pushed a workaround upstream.