https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107087
Ted Lyngmo <ted at lyncon dot se> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |ted at lyncon dot se --- Comment #20 from Ted Lyngmo <ted at lyncon dot se> --- I noticed something very similar that started with 12.4 and that is still there. I think it's a duplicate this ticket so I'll post here for you to decide. This gives ``` warning: 'void* __builtin_memmove(void*, const void*, long unsigned int)' forming offset 8 is out of the bounds [0, 8] [-Warray-bounds=] 452 | __builtin_memmove(__result, __first, sizeof(_Tp) * _Num); ``` with (at least) "-O2", "-O3", "-Os" and "-Ofast" and only without "-m32". ``` #include <algorithm> #include <array> #include <iostream> #include <iterator> // get an array of the N biggest elements in the order // they appeared in the original array template <size_t N, class T, std::size_t S> auto get_the_biggest(const std::array<T, S>& in) { static_assert(N <= S, "N can't be larger than the array"); auto res = [&]<std::size_t... Is>(std::index_sequence<Is...>) { return std::array<T, N>{in[Is]...}; }(std::make_index_sequence<N>{}); if constexpr (N == 0) return res; auto min = std::min_element(res.begin(), res.end()); for (size_t i = N; i < in.size(); ++i) { if (in[i] > *min) { // current is bigger than the min element if (auto next = std::next(min); next != res.end()) { // move everything after the min element down std::move(next, res.end(), min); } res[N - 1] = in[i]; // put the new value last min = std::min_element(res.begin(), res.end()); } } return res; } int main() { // prints "3 2" for (auto& arr : {std::array{1, 3, 2}}) { for (auto val : get_the_biggest<2>(arr)) std::cout << val << ' '; std::cout << '\n'; } } ```