I updated the operating system from Fedora 37 to Fedora 38, and my program started to produce new compilation warnings: array-bounds and stringop-overflow. The program depends on the libraries from the standard packages coming with the operating system, which in Fedora 38 are
spdlogv1.11fmtv9.1gtestv1.13
and is compiled with Fedora 38's standard GCC 13.2.1.
After the simplification I managed to get the following minimal example:
#include <spdlog/spdlog.h>
#include <gtest/gtest.h>
TEST( a, b ) {
spdlog::info( "info {}", 1 );
}
which if compiled with the flags -Wall -Werror -pedantic-errors shows
In file included from /usr/include/c++/13/string:51,
from /usr/include/c++/13/bits/locale_classes.h:40,
from /usr/include/c++/13/bits/ios_base.h:41,
from /usr/include/c++/13/ios:44,
from /usr/include/c++/13/istream:40,
from /usr/include/c++/13/sstream:40,
from /usr/include/c++/13/chrono:45,
from /usr/include/spdlog/common.h:10,
from /usr/include/spdlog/spdlog.h:12,
from test.cpp:3:
In static member function 'static constexpr _Up* std::__copy_move<_IsMove, true, std::random_access_iterator_tag>::__copy_m(_Tp*, _Tp*, _Up*) [with _Tp = unsigned int; _Up = unsigned int; bool _IsMove = false]',
inlined from 'constexpr _OI std::__copy_move_a2(_II, _II, _OI) [with bool _IsMove = false; _II = unsigned int*; _OI = unsigned int*]' at /usr/include/c++/13/bits/stl_algobase.h:506:30,
inlined from 'constexpr _OI std::__copy_move_a1(_II, _II, _OI) [with bool _IsMove = false; _II = unsigned int*; _OI = unsigned int*]' at /usr/include/c++/13/bits/stl_algobase.h:533:42,
inlined from 'constexpr _OI std::__copy_move_a(_II, _II, _OI) [with bool _IsMove = false; _II = unsigned int*; _OI = unsigned int*]' at /usr/include/c++/13/bits/stl_algobase.h:540:31,
inlined from 'constexpr _OI std::copy(_II, _II, _OI) [with _II = unsigned int*; _OI = unsigned int*]' 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 = unsigned int*; _ForwardIterator = unsigned int*]' at /usr/include/c++/13/bits/stl_uninitialized.h:147:27,
inlined from '_ForwardIterator std::uninitialized_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = unsigned int*; _ForwardIterator = unsigned int*]' at /usr/include/c++/13/bits/stl_uninitialized.h:185:15,
inlined from 'constexpr void fmt::v9::basic_memory_buffer<T, SIZE, Allocator>::grow(size_t) [with T = unsigned int; long unsigned int SIZE = 32; Allocator = std::allocator<unsigned int>]' at /usr/include/fmt/format.h:925:26,
inlined from 'constexpr void fmt::v9::detail::buffer<T>::try_reserve(size_t) [with T = unsigned int]' at /usr/include/fmt/core.h:928:39,
inlined from 'constexpr void fmt::v9::detail::buffer<T>::try_resize(size_t) [with T = unsigned int]' at /usr/include/fmt/core.h:919:16,
inlined from 'constexpr void fmt::v9::basic_memory_buffer<T, SIZE, Allocator>::resize(size_t) [with T = unsigned int; long unsigned int SIZE = 32; Allocator = std::allocator<unsigned int>]' at /usr/include/fmt/format.h:897:63,
inlined from 'constexpr void fmt::v9::detail::bigint::assign(UInt) [with UInt = long unsigned int; typename std::enable_if<(std::is_same<UInt, long unsigned int>::value || std::is_same<UInt, __int128 unsigned>::value), int>::type <anonymous> = 0]' at /usr/include/fmt/format.h:2792:19,
inlined from 'constexpr void fmt::v9::detail::bigint::operator=(Int) [with Int = int]' at /usr/include/fmt/format.h:2813:11,
inlined from 'constexpr void fmt::v9::detail::bigint::assign_pow10(int)' at /usr/include/fmt/format.h:2893:11,
inlined from 'constexpr void fmt::v9::detail::bigint::assign_pow10(int)' at /usr/include/fmt/format.h:2884:24,
inlined from 'constexpr void fmt::v9::detail::format_dragon(basic_fp<__int128 unsigned>, unsigned int, int, buffer<char>&, int&)' at /usr/include/fmt/format.h:3011:29:
/usr/include/c++/13/bits/stl_algobase.h:437:30: error: 'void* __builtin_memmove(void*, const void*, long unsigned int)' forming offset 4 is out of the bounds [0, 4] [-Werror=array-bounds=]
437 | __builtin_memmove(__result, __first, sizeof(_Tp) * _Num);
| ~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
If I silence the first warning with #pragma GCC diagnostic ignored "-Warray-bounds", then another one appears:
In file included from /usr/include/c++/13/string:51,
from /usr/include/c++/13/bits/locale_classes.h:40,
from /usr/include/c++/13/bits/ios_base.h:41,
from /usr/include/c++/13/ios:44,
from /usr/include/c++/13/istream:40,
from /usr/include/c++/13/sstream:40,
from /usr/include/c++/13/chrono:45,
from /usr/include/spdlog/common.h:10,
from /usr/include/spdlog/spdlog.h:12,
from test.cpp:7:
In static member function 'static constexpr _Up* std::__copy_move<_IsMove, true, std::random_access_iterator_tag>::__copy_m(_Tp*, _Tp*, _Up*) [with _Tp = unsigned int; _Up = unsigned int; bool _IsMove = false]',
inlined from 'constexpr _OI std::__copy_move_a2(_II, _II, _OI) [with bool _IsMove = false; _II = unsigned int*; _OI = unsigned int*]' at /usr/include/c++/13/bits/stl_algobase.h:506:30,
inlined from 'constexpr _OI std::__copy_move_a1(_II, _II, _OI) [with bool _IsMove = false; _II = unsigned int*; _OI = unsigned int*]' at /usr/include/c++/13/bits/stl_algobase.h:533:42,
inlined from 'constexpr _OI std::__copy_move_a(_II, _II, _OI) [with bool _IsMove = false; _II = unsigned int*; _OI = unsigned int*]' at /usr/include/c++/13/bits/stl_algobase.h:540:31,
inlined from 'constexpr _OI std::copy(_II, _II, _OI) [with _II = unsigned int*; _OI = unsigned int*]' 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 = unsigned int*; _ForwardIterator = unsigned int*]' at /usr/include/c++/13/bits/stl_uninitialized.h:147:27,
inlined from '_ForwardIterator std::uninitialized_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = unsigned int*; _ForwardIterator = unsigned int*]' at /usr/include/c++/13/bits/stl_uninitialized.h:185:15,
inlined from 'constexpr void fmt::v9::basic_memory_buffer<T, SIZE, Allocator>::grow(size_t) [with T = unsigned int; long unsigned int SIZE = 32; Allocator = std::allocator<unsigned int>]' at /usr/include/fmt/format.h:925:26,
inlined from 'constexpr void fmt::v9::detail::buffer<T>::try_reserve(size_t) [with T = unsigned int]' at /usr/include/fmt/core.h:928:39,
inlined from 'constexpr void fmt::v9::detail::buffer<T>::try_resize(size_t) [with T = unsigned int]' at /usr/include/fmt/core.h:919:16,
inlined from 'constexpr void fmt::v9::basic_memory_buffer<T, SIZE, Allocator>::resize(size_t) [with T = unsigned int; long unsigned int SIZE = 32; Allocator = std::allocator<unsigned int>]' at /usr/include/fmt/format.h:897:63,
inlined from 'constexpr void fmt::v9::detail::bigint::assign(UInt) [with UInt = long unsigned int; typename std::enable_if<(std::is_same<UInt, long unsigned int>::value || std::is_same<UInt, __int128 unsigned>::value), int>::type <anonymous> = 0]' at /usr/include/fmt/format.h:2792:19,
inlined from 'constexpr void fmt::v9::detail::bigint::operator=(Int) [with Int = int]' at /usr/include/fmt/format.h:2813:11,
inlined from 'constexpr void fmt::v9::detail::bigint::assign_pow10(int)' at /usr/include/fmt/format.h:2893:11,
inlined from 'constexpr void fmt::v9::detail::bigint::assign_pow10(int)' at /usr/include/fmt/format.h:2884:24,
inlined from 'constexpr void fmt::v9::detail::format_dragon(basic_fp<__int128 unsigned>, unsigned int, int, buffer<char>&, int&)' at /usr/include/fmt/format.h:3011:29:
/usr/include/c++/13/bits/stl_algobase.h:437:30: error: 'void* __builtin_memmove(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);
| ~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /usr/include/c++/13/x86_64-redhat-linux/bits/c++allocator.h:33,
from /usr/include/c++/13/bits/allocator.h:46,
from /usr/include/c++/13/string:43:
In member function '_Tp* std::__new_allocator<_Tp>::allocate(size_type, const void*) [with _Tp = unsigned int]',
inlined from 'constexpr _Tp* std::allocator< <template-parameter-1-1> >::allocate(std::size_t) [with _Tp = unsigned int]' at /usr/include/c++/13/bits/allocator.h:198:40,
inlined from 'static constexpr _Tp* std::allocator_traits<std::allocator<_CharT> >::allocate(allocator_type&, size_type) [with _Tp = unsigned int]' at /usr/include/c++/13/bits/alloc_traits.h:482:28,
inlined from 'constexpr void fmt::v9::basic_memory_buffer<T, SIZE, Allocator>::grow(size_t) [with T = unsigned int; long unsigned int SIZE = 32; Allocator = std::allocator<unsigned int>]' at /usr/include/fmt/format.h:923:49,
inlined from 'constexpr void fmt::v9::detail::buffer<T>::try_reserve(size_t) [with T = unsigned int]' at /usr/include/fmt/core.h:928:39,
inlined from 'constexpr void fmt::v9::detail::buffer<T>::try_resize(size_t) [with T = unsigned int]' at /usr/include/fmt/core.h:919:16,
inlined from 'constexpr void fmt::v9::basic_memory_buffer<T, SIZE, Allocator>::resize(size_t) [with T = unsigned int; long unsigned int SIZE = 32; Allocator = std::allocator<unsigned int>]' at /usr/include/fmt/format.h:897:63,
inlined from 'constexpr void fmt::v9::detail::bigint::assign(UInt) [with UInt = long unsigned int; typename std::enable_if<(std::is_same<UInt, long unsigned int>::value || std::is_same<UInt, __int128 unsigned>::value), int>::type <anonymous> = 0]' at /usr/include/fmt/format.h:2792:19,
inlined from 'constexpr void fmt::v9::detail::bigint::operator=(Int) [with Int = int]' at /usr/include/fmt/format.h:2813:11,
inlined from 'constexpr void fmt::v9::detail::bigint::assign_pow10(int)' at /usr/include/fmt/format.h:2893:11,
inlined from 'constexpr void fmt::v9::detail::bigint::assign_pow10(int)' at /usr/include/fmt/format.h:2884:24,
inlined from 'constexpr void fmt::v9::detail::format_dragon(basic_fp<__int128 unsigned>, unsigned int, int, buffer<char>&, int&)' at /usr/include/fmt/format.h:3011:29:
/usr/include/c++/13/bits/new_allocator.h:147:55: note: destination object of size 4 allocated by 'operator new'
147 | return static_cast<_Tp*>(_GLIBCXX_OPERATOR_NEW(__n * sizeof(_Tp)));
|
Unfortunetly, I cannot reproduce it in online compiler godbolt.org because it lacks exactly the same versions of the libraries.
I guess that the problem is in one of the libraries involved (but in which of the three). Can the example be simplified even more to find it out?