https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85828
--- Comment #2 from Jonathan Wakely <redi at gcc dot gnu.org> --- This is ugly but it works: --- a/libstdc++-v3/include/bits/stl_algo.h +++ b/libstdc++-v3/include/bits/stl_algo.h @@ -3827,7 +3827,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION if ((__urange % 2) == 0) { __distr_type __d{0, 1}; - std::iter_swap(__i++, __first + __d(__g)); + if (__d(__g) == 0) + std::iter_swap(__i, __first); + ++__i; } // Now we know that __last - __i is even, so we do the rest in pairs, @@ -3841,8 +3843,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION const pair<__uc_type, __uc_type> __pospos = __gen_two_uniform_ints(__swap_range, __swap_range + 1, __g); - std::iter_swap(__i++, __first + __pospos.first); - std::iter_swap(__i++, __first + __pospos.second); + _RandomAccessIterator __pos1 = __first + __pospos.first; + _RandomAccessIterator __pos2 = __first + __pospos.second; + if (__i != __pos1) + std::iter_swap(__i, __pos1); + ++__i; + if (__i != __pos2) + std::iter_swap(__i, __pos2); + ++__i; } return; I think we also want to remove the __glibcxx_check_self_move_assign assertions completely.