http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48038
--- Comment #13 from Jonathan Wakely <redi at gcc dot gnu.org> 2011-03-09 11:43:00 UTC --- gah - there was a bug in my reduced testcase, the move assignment operator should have done: ok = rh.ok; that was missing which is why Temporary_buffer left the first element !ok The logic in __ucr is ok, sorry! This one still fails (and only if the operator< takes args by value) #include <algorithm> #include <assert.h> struct V { int val; bool ok; V(int v) : val(v), ok(true) { } V(V const & rh) : val(rh.val), ok(rh.ok) { // assert(rh.ok); } V & operator=(V const &rh) { // assert(rh.ok); val = rh.val; ok = rh.ok; return *this; } V(V && rh) : val(rh.val), ok(rh.ok) { // assert(rh.ok); rh.ok = false; } V & operator=(V && rh) { // assert(rh.ok); val = rh.val; ok = rh.ok; rh.ok = false; return *this; } }; inline bool operator<(V lh, V rh) { assert(rh.ok); assert(lh.ok); return lh.val < rh.val; } int main() { V vvs[] = { 2, 0, 1 }; std::stable_sort(vvs, vvs+3); }