if (__str._M_is_local())
          {
-           // We've always got room for a short string, just copy it.
-           if (__str.size())
-             this->_S_copy(_M_data(), __str._M_data(), __str.size());
-           _M_set_length(__str.size());
+           // We've always got room for a short string, just copy it
+           // (unless this is a self-move, because that would violate the
+           // char_traits::copy precondition that the ranges don't overlap).
+           if (__builtin_expect(std::__addressof(__str) != this, true))
+             {
+               if (__str.size())
+                 this->_S_copy(_M_data(), __str._M_data(), __str.size());
+               _M_set_length(__str.size());
+             }
          }
        else if (_Alloc_traits::_S_propagate_on_move_assign()
            || _Alloc_traits::_S_always_equal()
 
               _H1, _H2, _Hash, _RehashPolicy, _Traits>::
     _M_move_assign(_Hashtable&& __ht, true_type)
     {
+      if (__builtin_expect(std::__addressof(__ht) == this, false))
+       return;
+
       this->_M_deallocate_nodes(_M_begin());
       _M_deallocate_buckets();
       __hashtable_base::operator=(std::move(__ht));
 
       void
       _M_move_assign1(deque&& __x, /* always equal: */ false_type)
       {
+       if (_M_get_Tp_allocator() == __x._M_get_Tp_allocator())
+         return _M_move_assign1(std::move(__x), true_type());
+
        constexpr bool __move_storage =
          _Alloc_traits::_S_propagate_on_move_assign();
        _M_move_assign2(std::move(__x), __bool_constant<__move_storage>());
 
       void
       _M_move_assign(list&& __x, true_type) noexcept
       {
-       this->_M_clear();
+       this->clear();
        this->_M_move_nodes(std::move(__x));
        std::__alloc_on_move(this->_M_get_Node_allocator(),
                             __x._M_get_Node_allocator());
 
     // unordered container local iterators
     __msg_local_iter_compare_bad,
     __msg_non_empty_range,
-    // self move assign
+    // self move assign (no longer used)
     __msg_self_move_assign,
     // unordered container buckets
     __msg_bucket_index_oob,
 
                      ._M_iterator(_Last, #_Last)                       \
                      ._M_string(#_Pred))
 
-// Verify that the container is not self move assigned
-#define __glibcxx_check_self_move_assign(_Other)                       \
-_GLIBCXX_DEBUG_VERIFY(this != &_Other,                                 \
-                     _M_message(__gnu_debug::__msg_self_move_assign)   \
-                      ._M_sequence(*this, "this"))
-
 // Verify that load factor is positive
 #define __glibcxx_check_max_load_factor(_F)                            \
 _GLIBCXX_DEBUG_VERIFY(_F > 0.0f,                                       \
 
       _Safe_container&
       operator=(_Safe_container&& __x) noexcept
       {
-       __glibcxx_check_self_move_assign(__x);
+       if (std::__addressof(__x) == this)
+         {
+           // Standard containers have a valid but unspecified value after
+           // self-move, so we invalidate all debug iterators even if the
+           // underlying container happens to preserve its contents.
+           this->_M_invalidate_all();
+           return *this;
+         }
 
        if (_IsCxx11AllocatorAware)
          {
 
       _Safe_iterator&
       operator=(_Safe_iterator&& __x) noexcept
       {
-       _GLIBCXX_DEBUG_VERIFY(this != &__x,
-                             _M_message(__msg_self_move_assign)
-                             ._M_iterator(*this, "this"));
        _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
                              || __x.base() == _Iterator(),
                              _M_message(__msg_copy_singular)
                              ._M_iterator(*this, "this")
                              ._M_iterator(__x, "other"));
 
+       if (std::__addressof(__x) == this)
+         return *this;
+
        if (this->_M_sequence && this->_M_sequence == __x._M_sequence)
          {
            __gnu_cxx::__scoped_lock __l(this->_M_get_mutex());
 
       _Safe_local_iterator&
       operator=(_Safe_local_iterator&& __x) noexcept
       {
-       _GLIBCXX_DEBUG_VERIFY(this != &__x,
-                             _M_message(__msg_self_move_assign)
-                             ._M_iterator(*this, "this"));
        _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
                              || __x.base() == _Iterator(),
                              _M_message(__msg_copy_singular)
                              ._M_iterator(*this, "this")
                              ._M_iterator(__x, "other"));
 
+       if (std::__addressof(__x) == this)
+         return *this;
+
        if (this->_M_sequence && this->_M_sequence == __x._M_sequence)
          {
            __gnu_cxx::__scoped_lock __l(this->_M_get_mutex());
 
--- /dev/null
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-do run { target c++11 } }
+
+#include <string>
+#include <debug/string>
+#include <testsuite_hooks.h>
+
+template<typename String>
+void
+test(const char* s)
+{
+  String s1 = s;
+  std::string s2 __attribute__((unused)) = s1.c_str();
+  s1 = std::move(s1);
+
+  String s3 __attribute__((unused)) = s1;
+  s1 = std::move(s1);
+
+  s1.begin(); // causes COW string to "leak"
+  s1 = std::move(s1);
+
+  String s4 __attribute__((unused)) = s1;
+  s1 = std::move(s1);
+
+  s1.reserve(2 * s1.capacity()); // causes SSO string to be on the heap
+  s1 = std::move(s1);
+}
+
+int
+main()
+{
+  test<std::string>("short");
+  test<std::string>("very, very, very, VERY long");
+  test<__gnu_debug::string>("short");
+  test<__gnu_debug::string>("very, very, very, VERY long");
+}
 
--- /dev/null
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-do run { target c++11 } }
+
+#include <deque>
+#include <debug/deque>
+#include <testsuite_hooks.h>
+
+template<typename Container>
+void
+test(std::initializer_list<typename Container::value_type> vals)
+{
+  Container c{vals};
+  c = std::move(c);
+  VERIFY( c == c );
+
+  auto it = c.begin();
+  it = std::move(it);
+  VERIFY( it == c.begin() );
+}
+
+int
+main()
+{
+  test<std::deque<int>>({1, 2, 3});
+  test<std::deque<std::deque<int>>>({{1,2}, {3,4}, {5,6}, {7,8}});
+  test<__gnu_debug::deque<int>>({1, 2, 3});
+  test<__gnu_debug::deque<std::deque<int>>>({{1,2}, {3,4}});
+}
 
--- /dev/null
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-do run { target c++11 } }
+
+#include <forward_list>
+#include <debug/forward_list>
+#include <testsuite_hooks.h>
+
+template<typename Container>
+void
+test(std::initializer_list<typename Container::value_type> vals)
+{
+  Container c{vals};
+  c = std::move(c);
+  VERIFY( c == c );
+
+  auto it = c.begin();
+  it = std::move(it);
+  VERIFY( it == c.begin() );
+}
+
+int
+main()
+{
+  test<std::forward_list<int>>({1, 2, 3});
+  test<std::forward_list<std::forward_list<int>>>({{1,2}, {3,4}, {5,6}, {7,8}});
+  test<__gnu_debug::forward_list<int>>({1, 2, 3});
+  test<__gnu_debug::forward_list<std::forward_list<int>>>({{1,2}, {3,4}});
+}
 
--- /dev/null
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-do run { target c++11 } }
+
+#include <list>
+#include <debug/list>
+#include <testsuite_hooks.h>
+
+template<typename Container>
+void
+test(std::initializer_list<typename Container::value_type> vals)
+{
+  Container c{vals};
+  c = std::move(c);
+  VERIFY( c == c );
+
+  auto it = c.begin();
+  it = std::move(it);
+  VERIFY( it == c.begin() );
+}
+
+int
+main()
+{
+  test<std::list<int>>({1, 2, 3});
+  test<std::list<std::list<int>>>({{1,2}, {3,4}, {5,6}, {7,8}});
+  test<__gnu_debug::list<int>>({1, 2, 3});
+  test<__gnu_debug::list<std::list<int>>>({{1,2}, {3,4}});
+}
 
--- /dev/null
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-do run { target c++11 } }
+
+#include <set>
+#include <debug/set>
+#include <string>
+#include <stdlib.h>
+#include <testsuite_hooks.h>
+
+template<typename Container>
+void
+test(std::initializer_list<typename Container::value_type> vals)
+{
+  Container c{vals};
+  c = std::move(c);
+  VERIFY( c == c );
+
+  auto it = c.begin();
+  it = std::move(it);
+  VERIFY( it == c.begin() );
+}
+
+int
+main()
+{
+  std::string s = "how long is a piece of SSO string?";
+  test<std::set<int>>({1, 2, 3});
+  test<std::set<std::string>>({s, s, s, s});
+  test<__gnu_debug::set<int>>({1, 2, 3});
+  test<__gnu_debug::set<std::string>>({s, s, s, s});
+}
 
--- /dev/null
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-do run { target c++11 } }
+
+#include <unordered_set>
+#include <debug/unordered_set>
+#include <string>
+#include <stdlib.h>
+#include <testsuite_hooks.h>
+
+template<typename Container>
+void
+test(std::initializer_list<typename Container::value_type> vals)
+{
+  Container c{vals};
+  c = std::move(c);
+  VERIFY( c == c );
+
+  auto it = c.begin();
+  it = std::move(it);
+  VERIFY( it == c.begin() );
+
+  auto localit = c.begin(0);
+  localit = std::move(localit);
+}
+
+int
+main()
+{
+  std::string s = "how long is a piece of SSO string?";
+  test<std::unordered_set<int>>({1, 2, 3});
+  test<std::unordered_set<std::string>>({s, s, s, s});
+  test<__gnu_debug::unordered_set<int>>({1, 2, 3});
+  test<__gnu_debug::unordered_set<std::string>>({s, s, s, s});
+}
 
--- /dev/null
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-do run { target c++11 } }
+
+#include <vector>
+#include <debug/vector>
+#include <testsuite_hooks.h>
+
+template<typename Container>
+void
+test(std::initializer_list<typename Container::value_type> vals)
+{
+  Container c{vals};
+  c = std::move(c);
+  VERIFY( c == c );
+
+  auto it = c.begin();
+  it = std::move(it);
+  VERIFY( it == c.begin() );
+}
+
+int
+main()
+{
+  test<std::vector<int>>({1, 2, 3});
+  test<std::vector<std::vector<int>>>({{1,2}, {3,4}, {5,6}, {7,8}});
+  test<__gnu_debug::vector<int>>({1, 2, 3});
+  test<__gnu_debug::vector<std::vector<int>>>({{1,2}, {3,4}});
+}