From 41501d1ae708f6977d957b61f797fda15ce33f0b Mon Sep 17 00:00:00 2001 From: Tim Shen Date: Thu, 22 Sep 2016 03:15:58 +0000 Subject: [PATCH] re PR libstdc++/77641 (std::variant copy-initialization fails for type with non-trivial constexpr ctor) 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 | 7 +++++ libstdc++-v3/include/std/variant | 29 ++++++++++++------- .../testsuite/20_util/variant/compile.cc | 9 ++++++ 3 files changed, 34 insertions(+), 11 deletions(-) diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 7e7c3468c2a..0de2044de14 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,10 @@ +2016-09-22 Tim Shen + + 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 PR libstdc++/77288 diff --git a/libstdc++-v3/include/std/variant b/libstdc++-v3/include/std/variant index 7dbb533dd83..013884bb23e 100644 --- a/libstdc++-v3/include/std/variant +++ b/libstdc++-v3/include/std/variant @@ -296,15 +296,9 @@ namespace __variant { constexpr _Variant_storage() = default; - template - constexpr _Variant_storage(in_place_index_t<0>, _Args&&... __args) - : _M_first(in_place<0>, forward<_Args>(__args)...) - { } - - template> + template 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( - static_cast(std::addressof(_M_first._M_storage))); + static_cast(std::addressof(_M_union._M_first._M_storage))); } - union + union _Union { + constexpr _Union() {}; + + template + constexpr _Union(in_place_index_t<0>, _Args&&... __args) + : _M_first(in_place<0>, forward<_Args>(__args)...) + { } + + template> + 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 diff --git a/libstdc++-v3/testsuite/20_util/variant/compile.cc b/libstdc++-v3/testsuite/20_util/variant/compile.cc index b57d356d301..99f980a72db 100644 --- a/libstdc++-v3/testsuite/20_util/variant/compile.cc +++ b/libstdc++-v3/testsuite/20_util/variant/compile.cc @@ -403,3 +403,12 @@ void test_void() v = 3; v = "asdf"; } + +void test_pr77641() +{ + struct X { + constexpr X() { } + }; + + constexpr std::variant v1 = X{}; +} -- 2.30.2