This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] fix std::variant::swap for trivially-move-assignable types
- From: Jonathan Wakely <jwakely at redhat dot com>
- To: libstdc++ at gcc dot gnu dot org, gcc-patches at gcc dot gnu dot org
- Cc: Tim Shen <timshen91 at gmail dot com>, Ville Voutilainen <ville dot voutilainen at gmail dot com>
- Date: Tue, 7 Aug 2018 15:24:03 +0100
- Subject: [PATCH] fix std::variant::swap for trivially-move-assignable types
This patch fixes the bug, but is it correct?
IIUC the _M_destructive_move effects don't depend on whether move
assignment is trivial, so should be defined the same way in both
specializations. It also looks like we can use it in the non-trivial
move assignment.
Should we define _M_destructive_move on _Move_ctor_base instead of
_Move_assign_base, so the duplication could be avoided?
Obviously this needs a ChangeLog entry and tests.
diff --git a/libstdc++-v3/include/std/variant b/libstdc++-v3/include/std/variant
index 66d878142a4..7d691c487fd 100644
--- a/libstdc++-v3/include/std/variant
+++ b/libstdc++-v3/include/std/variant
@@ -613,16 +613,7 @@ namespace __variant
else
{
_Move_assign_base __tmp(std::move(__rhs));
- this->~_Move_assign_base();
- __try
- {
- ::new (this) _Move_assign_base(std::move(__tmp));
- }
- __catch (...)
- {
- this->_M_index = variant_npos;
- __throw_exception_again;
- }
+ _M_destructive_move(std::move(__tmp));
}
__glibcxx_assert(this->_M_index == __rhs._M_index);
return *this;
@@ -638,6 +629,19 @@ namespace __variant
{
using _Base = _Copy_assign_alias<_Types...>;
using _Base::_Base;
+ void _M_destructive_move(_Move_assign_base&& __rhs)
+ {
+ this->~_Move_assign_base();
+ __try
+ {
+ ::new (this) _Move_assign_base(std::move(__rhs));
+ }
+ __catch (...)
+ {
+ this->_M_index = variant_npos;
+ __throw_exception_again;
+ }
+ }
};
template<typename... _Types>