https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118088
Bug ID: 118088 Summary: std::priority_queue doesn't maintain invariants after being moved Product: gcc Version: 15.0 Status: UNCONFIRMED Keywords: wrong-code Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: redi at gcc dot gnu.org Target Milestone: --- #include <queue> #include <vector> #include <iostream> // A vector-like type that has a non-empty moved-from state. struct Vector : std::vector<int> { using Base = std::vector<int>; using Base::Base; Vector(const Vector&) = default; Vector& operator=(const Vector&) = default; Vector(Vector&& v) : Base(static_cast<const Base&>(v)) { invalidate_heap(v); } Vector(Vector&& v, const std::allocator<int>&) : Base(static_cast<const Base&>(v)) { invalidate_heap(v); } Vector& operator=(Vector&& v) { static_cast<Base&>(*this) = static_cast<const Base&>(v); invalidate_heap(v); return *this; } void invalidate_heap(Base& v) { v = {1,2,3}; } }; int main() { std::priority_queue<int, Vector> p; p.push(1); p.push(3); p.push(5); p.push(2); p.push(2); p.push(2); p.push(2); std::priority_queue<int, Vector> p2 = std::move(p); while (!p.empty()) { std::cout << p.top() << ' '; p.pop(); } std::cout << '\n'; // Allocator-extended move constructor: std::priority_queue<int, Vector> p3(std::move(p2), std::allocator<int>()); while (!p2.empty()) { std::cout << p2.top() << ' '; p2.pop(); } std::cout << '\n'; p2 = std::move(p3); while (!p3.empty()) { std::cout << p3.top() << ' '; p3.pop(); } std::cout << '\n'; } This prints: 1 3 2 1 3 2 1 3 2 But a priority_queue should print "3 2 1"