Closed prlw1 closed 1 year ago
GCC 14 hasn't been released yet but I wasn't able to repro the issue on the GCC trunk in godbolt: https://godbolt.org/z/MYKTr7cKx. Could you provide a link to the godbolt repro?
Very interesting: add -O2
to the flags, and godbolt reproduces it. I was using -std=c++23
, but the same effect happens with -std=c++20
as you had.
OK, it does repro (https://godbolt.org/z/cqjrM3s7e) and it's actually a warning:
/opt/compiler-explorer/gcc-trunk-20230612/include/c++/14.0.0/bits/stl_algobase.h:437:30: warning: 'void* __builtin_memmove(void*, const void*, long unsigned int)' writing between 5 and 9223372036854775807 bytes into a region of size 4 overflows the destination [-Wstringop-overflow=]
437 | __builtin_memmove(__result, __first, sizeof(_Tp) * _Num);
| ~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
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 /opt/compiler-explorer/gcc-trunk-20230612/include/c++/14.0.0/bits/allocator.h:198:40,
inlined from 'static constexpr _Tp* std::allocator_traits<std::allocator<_Up> >::allocate(allocator_type&, size_type) [with _Tp = unsigned int]' at /opt/compiler-explorer/gcc-trunk-20230612/include/c++/14.0.0/bits/alloc_traits.h:482:28,
inlined from 'constexpr void fmt::v10::basic_memory_buffer<T, SIZE, Allocator>::grow(size_t) [with T = unsigned int; long unsigned int SIZE = 32; Allocator = std::allocator<unsigned int>]' at /opt/compiler-explorer/libs/fmt/trunk/include/fmt/format.h:943:51,
inlined from 'constexpr void fmt::v10::detail::buffer<T>::try_reserve(size_t) [with T = unsigned int]' at /opt/compiler-explorer/libs/fmt/trunk/include/fmt/core.h:858:39,
inlined from 'constexpr void fmt::v10::detail::buffer<T>::try_reserve(size_t) [with T = unsigned int]' at /opt/compiler-explorer/libs/fmt/trunk/include/fmt/core.h:857:24,
inlined from 'constexpr void fmt::v10::detail::buffer<T>::try_resize(size_t) [with T = unsigned int]' at /opt/compiler-explorer/libs/fmt/trunk/include/fmt/core.h:849:16,
inlined from 'constexpr void fmt::v10::basic_memory_buffer<T, SIZE, Allocator>::resize(size_t) [with T = unsigned int; long unsigned int SIZE = 32; Allocator = std::allocator<unsigned int>]' at /opt/compiler-explorer/libs/fmt/trunk/include/fmt/format.h:1016:63,
inlined from 'constexpr void fmt::v10::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 /opt/compiler-explorer/libs/fmt/trunk/include/fmt/format.h:2833:19,
inlined from 'constexpr void fmt::v10::detail::bigint::operator=(Int) [with Int = long long unsigned int]' at /opt/compiler-explorer/libs/fmt/trunk/include/fmt/format.h:2854:11,
inlined from 'constexpr void fmt::v10::detail::format_dragon(basic_fp<__int128 unsigned>, unsigned int, int, buffer<char>&, int&)' at /opt/compiler-explorer/libs/fmt/trunk/include/fmt/format.h:3056:19,
inlined from 'constexpr int fmt::v10::detail::format_float(Float, int, float_specs, buffer<char>&) [with Float = double]' at /opt/compiler-explorer/libs/fmt/trunk/include/fmt/format.h:3524:18:
/opt/compiler-explorer/gcc-trunk-20230612/include/c++/14.0.0/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)));
| ^
Oh dear: my system build adds -O2 -fPIE -g -Werror
to my own CXXFLAGS
, which explains why I saw it as an error.
So the surprise is that int & float behave differently, but I suppose this can be closed as NOTABUG.
This is a false positive suppressed in https://github.com/fmtlib/fmt/commit/977d887a4ea9ae82182d6c26b2114a0fb0cade72. I recommend reporting to GCC.
Using today's
g++ (GCC) 14.0.0 20230610 (experimental)
on today's fmt checkout 8fe893c0ac54c83a08c2492a7ac790c1a2bdd577, the following simple codecompiles and does what you expect.
If I change
vector<int>
tovector<float>
(optionally changing1
to1.0f
etc.), the code fails to compile.The head and tail of the error message spew is: