This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
[v3 PATCH] PR libstdc++/89816
- From: Ville Voutilainen <ville dot voutilainen at gmail dot com>
- To: gcc-patches List <gcc-patches at gcc dot gnu dot org>, "libstdc++" <libstdc++ at gcc dot gnu dot org>, Antony Polukhin <antoshkka at gmail dot com>
- Date: Mon, 25 Mar 2019 18:23:25 +0200
- Subject: [v3 PATCH] PR libstdc++/89816
I looked at the codegen of this before and after the patch, and
it does the right thing. Variant's tests run on Linux-x64. OK for
trunk?
2019-03-25 Ville Voutilainen <ville.voutilainen@gmail.com>
PR libstdc++/89816
Fix based on a suggestion by Antony Polukhin.
* include/std/variant (__variant_construct): Capture a pointer
to the storage and visit just one variant.
diff --git a/libstdc++-v3/include/std/variant b/libstdc++-v3/include/std/variant
index a5b8fa8..0984e13 100644
--- a/libstdc++-v3/include/std/variant
+++ b/libstdc++-v3/include/std/variant
@@ -426,18 +426,18 @@ namespace __variant
void __variant_construct(_Tp&& __lhs, _Up&& __rhs)
{
__lhs._M_index = __rhs._M_index;
- __do_visit([](auto&& __this_mem, auto&& __rhs_mem) mutable
+ void* __storage = std::addressof(__lhs._M_u);
+ __do_visit([__storage](auto&& __rhs_mem) mutable
-> __detail::__variant::__variant_cookie
{
- using _Type = remove_reference_t<decltype(__this_mem)>;
+ using _Type = remove_reference_t<decltype(__rhs_mem)>;
if constexpr (is_same_v<__remove_cvref_t<decltype(__rhs_mem)>,
remove_cv_t<_Type>>
&& !is_same_v<_Type, __variant_cookie>)
- ::new ((void*)std::addressof(__this_mem))
+ ::new (__storage)
_Type(std::forward<decltype(__rhs_mem)>(__rhs_mem));
return {};
- }, __variant_cast<_Types...>(__lhs),
- __variant_cast<_Types...>(std::forward<decltype(__rhs)>(__rhs)));
+ }, __variant_cast<_Types...>(std::forward<decltype(__rhs)>(__rhs)));
}
// The following are (Copy|Move) (ctor|assign) layers for forwarding