re PR libstdc++/77641 (std::variant copy-initialization fails for type with non-trivi...
authorTim Shen <timshen@google.com>
Thu, 22 Sep 2016 03:15:58 +0000 (03:15 +0000)
committerTim Shen <timshen@gcc.gnu.org>
Thu, 22 Sep 2016 03:15:58 +0000 (03:15 +0000)
PR libstdc++/77641
* include/std/variant (_Variant_storage::_Variant_storage):
Change _Variant_storage's union to be default constructible.
* testsuite/20_util/variant/compile.cc: New test.

From-SVN: r240340

libstdc++-v3/ChangeLog
libstdc++-v3/include/std/variant
libstdc++-v3/testsuite/20_util/variant/compile.cc

index 7e7c3468c2abf312010ebfb91a89378a11901eaf..0de2044de14d18f9e33a04ee9243bcb7f4f6ea0f 100644 (file)
@@ -1,3 +1,10 @@
+2016-09-22  Tim Shen  <timshen@google.com>
+
+       PR libstdc++/77641
+       * include/std/variant (_Variant_storage::_Variant_storage):
+       Change _Variant_storage's union to be default constructible.
+       * testsuite/20_util/variant/compile.cc: New test.
+
 2016-09-21  Ville Voutilainen  <ville.voutilainen@gmail.com>
 
        PR libstdc++/77288
index 7dbb533dd83b46c23d2f6938a9cc9bbcf478fb22..013884bb23ec17f0bd41f52e8f522963edcabcd0 100644 (file)
@@ -296,15 +296,9 @@ namespace __variant
     {
       constexpr _Variant_storage() = default;
 
-      template<typename... _Args>
-       constexpr _Variant_storage(in_place_index_t<0>, _Args&&... __args)
-       : _M_first(in_place<0>, forward<_Args>(__args)...)
-       { }
-
-      template<size_t _Np, typename... _Args,
-              typename = enable_if_t<0 < _Np && _Np < sizeof...(_Rest) + 1>>
+      template<size_t _Np, typename... _Args>
        constexpr _Variant_storage(in_place_index_t<_Np>, _Args&&... __args)
-       : _M_rest(in_place<_Np - 1>, forward<_Args>(__args)...)
+       : _M_union(in_place<_Np>, forward<_Args>(__args)...)
        { }
 
       ~_Variant_storage() = default;
@@ -313,14 +307,27 @@ namespace __variant
       _M_storage() const
       {
        return const_cast<void*>(
-         static_cast<const void*>(std::addressof(_M_first._M_storage)));
+         static_cast<const void*>(std::addressof(_M_union._M_first._M_storage)));
       }
 
-      union
+      union _Union
       {
+       constexpr _Union() {};
+
+       template<typename... _Args>
+         constexpr _Union(in_place_index_t<0>, _Args&&... __args)
+         : _M_first(in_place<0>, forward<_Args>(__args)...)
+         { }
+
+       template<size_t _Np, typename... _Args,
+                typename = enable_if_t<0 < _Np && _Np < sizeof...(_Rest) + 1>>
+         constexpr _Union(in_place_index_t<_Np>, _Args&&... __args)
+         : _M_rest(in_place<_Np - 1>, forward<_Args>(__args)...)
+         { }
+
        _Uninitialized<__storage<_First>> _M_first;
        _Variant_storage<_Rest...> _M_rest;
-      };
+      } _M_union;
     };
 
   template<typename _Derived, bool __is_trivially_destructible>
index b57d356d3016fa7c4b3f43adc33ff557398bc9fa..99f980a72db039e4bdf730cdfcfa2a33218e3120 100644 (file)
@@ -403,3 +403,12 @@ void test_void()
   v = 3;
   v = "asdf";
 }
+
+void test_pr77641()
+{
+  struct X {
+    constexpr X() { }
+  };
+
+  constexpr std::variant<X> v1 = X{};
+}