https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92124
Bug ID: 92124 Summary: std::vector copy-assigning when it should move-assign. Product: gcc Version: 9.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: cassio.neri at gmail dot com Target Milestone: --- Consider two vectors a and rv. In the situation below a = std::move(rv) copy-assigns elements of rv into a, violating [container.requirements.general]/4, Table 83: "All existing elements of a are either move assigned to or destroyed" (See [1].) It happens with std::vector<X, A<X>> such that: 1) X's move-constructor might throw (though I'm assigning and not constructing); 2) A<X> does not propagate on move-assignment and allocators used by source and target vectors do not compare equal. The following MCVE contains some boiler plate and the most important parts are indicated by comments. #include <cstdio> #include <vector> #include <memory> #include <type_traits> struct X { X() = default; X(const X&) = default; // Move constructor might throw X(X&&) noexcept(false) {} // "= default" changes reported behaviour // Tracking calls to assignment functions X& operator=(const X&) { putchar('c'); return *this; } X& operator=(X&&) noexcept(true) { putchar('m'); return *this; } }; unsigned counter = 0; template <typename T> struct A : std::allocator<T> { template <typename U> struct rebind { using other = A<U>; }; A() : std::allocator<T>(), id(++counter) {} // Does not propagate using propagate_on_container_move_assignment = std::false_type; // Does not always compare equal using is_always_equal = std::false_type; bool operator ==(const A& o) { return id == o.id; } bool operator !=(const A& o) { return id != o.id; } unsigned id; }; int main() { std::vector<X, A<X>> a(2), rv(2); a = std::move(rv); } Running the code above outputs "cc" (instead of "mm") confirming the two elements of rv are copy-assigned into a. See relevant discussion in [2] (with link to possible culprit lines of code in libstdc++) and life example above in [3] [1] https://timsong-cpp.github.io/cppwp/n4659/container.requirements#tab:containers.container.requirements [2] https://stackoverflow.com/questions/58378051/issue-when-compiling-libstdc-with-clang?noredirect=1#comment103136248_58378051 [3] https://godbolt.org/z/EgkPrP