http://gcc.gnu.org/bugzilla/show_bug.cgi?id=46830
Summary: s.swap(s) triggers overlapped memcpy() for versa_string Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: ppluzhni...@google.com Consider this test case: //--- cut --- #include <ext/vstring.h> #include <ext/vstring_fwd.h> typedef __gnu_cxx::__vstring string; int main() { string s = "Hello"; s.swap(s); } //--- cut --- When built with current GCC SVN (rev 167521), and run under Valgrind, it produces: ==21887== Source and destination overlap in memcpy(0x7ffefff390, 0x7ffefff390, 16) ==21887== at 0x4C2C364: memcpy (valgrind/memcheck/mc_replace_strmem.c:523) ==21887== by 0x400B92: std::char_traits<char>::copy(char*, char const*, unsigned long) (/t/gcc-svn-install/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.6.0/../../../../include/c++/4.6.0/bits/char_traits.h:268) ==21887== by 0x400DD4: __gnu_cxx::__sso_string_base<char, std::char_traits<char>, std::allocator<char> >::_M_swap(__gnu_cxx::__sso_string_base<char, std::char_traits<char>, std::allocator<char> >&) (/t/gcc-svn-install/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.6.0/../../../../include/c++/4.6.0/ext/sso_string_base.h:248) ==21887== by 0x400C20: __gnu_cxx::__versa_string<char, std::char_traits<char>, std::allocator<char>, __gnu_cxx::__sso_string_base>::swap(__gnu_cxx::__versa_string<char, std::char_traits<char>, std::allocator<char>, __gnu_cxx::__sso_string_base>&) (/t/gcc-svn-install/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.6.0/../../../../include/c++/4.6.0/ext/vstring.h:1475) ==21887== by 0x400ACC: main (/g/tmp/t.cc:9) I can't find any prohibition in C++ standards on calling s.swap(s), nor any indication in POSIX standards that memcpy(p, p, ...) is allowed. Proposed fix: Index: libstdc++-v3/include/ext/sso_string_base.h =================================================================== --- libstdc++-v3/include/ext/sso_string_base.h (revision 167521) +++ libstdc++-v3/include/ext/sso_string_base.h (working copy) @@ -232,6 +232,9 @@ __sso_string_base<_CharT, _Traits, _Alloc>:: _M_swap(__sso_string_base& __rcs) { + if (this == &__rcs) + return; + // _GLIBCXX_RESOLVE_LIB_DEFECTS // 431. Swapping containers with unequal allocators. std::__alloc_swap<_CharT_alloc_type>::_S_do_it(_M_get_allocator(),