[v3] PR libstdc++/89816

Message ID CAFk2RUY2yRhhcDCbuKUT5DKQXr0Dv00Vrf19Tp1d-3Wg-6rE1w@mail.gmail.com
State New
Headers show
Series
  • [v3] PR libstdc++/89816
Related show

Commit Message

Ville Voutilainen March 25, 2019, 4:23 p.m.
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.

Comments

Jonathan Wakely March 25, 2019, 4:53 p.m. | #1
On 25/03/19 18:23 +0200, Ville Voutilainen wrote:
>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?


OK, thanks (and thanks Antony for the bug report and suggestion).

Patch

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