libstdc++: std::variant doesn't like types with a defaulted virtual destructor [PR95915]

Message ID CAFk2RUYKAU14-o2xis0remMRGq80md6wMCUD=9ZFG2wUy0w3SA@mail.gmail.com
State New
Headers show
Series
  • libstdc++: std::variant doesn't like types with a defaulted virtual destructor [PR95915]
Related show

Commit Message

Peter Bergner via Gcc-patches June 26, 2020, 4:12 p.m.
This patch also deprecates std::is_literal_type.

2020-06-26  Ville Voutilainen  <ville.voutilainen@gmail.com>

    PR libstdc++/95915
    * include/std/type_traits (is_literal_type, is_literal_type_v):
    Deprecate in C++17.
    * include/std/variant (_Uninitialized):
    Adjust the condition and the comment.
    * testsuite/20_util/is_literal_type/deprecated-1z.cc: New.
    * testsuite/20_util/is_literal_type/requirements/explicit_instantiation.cc:
    Adjust.
    * testsuite/20_util/is_literal_type/requirements/typedefs.cc: Likewise.
    * testsuite/20_util/is_literal_type/value.cc: Likewise.
    * testsuite/20_util/variant/95915.cc: New.
    * testsuite/20_util/variant/compile.cc: Add new test.

Comments

Peter Bergner via Gcc-patches June 26, 2020, 4:18 p.m. | #1
On Fri, 26 Jun 2020 at 19:12, Ville Voutilainen
<ville.voutilainen@gmail.com> wrote:
>

> This patch also deprecates std::is_literal_type.


I forgot to ask, OK for trunk and GCC 10 if full suite testing passes?
The problematic compiler bug has been
gone since GCC 10, so we can just as well backport this there, but not further.
Peter Bergner via Gcc-patches June 26, 2020, 6:20 p.m. | #2
On 26/06/20 19:12 +0300, Ville Voutilainen via Libstdc++ wrote:
>This patch also deprecates std::is_literal_type.

>

>2020-06-26  Ville Voutilainen  <ville.voutilainen@gmail.com>

>

>    PR libstdc++/95915

>    * include/std/type_traits (is_literal_type, is_literal_type_v):

>    Deprecate in C++17.

>    * include/std/variant (_Uninitialized):

>    Adjust the condition and the comment.

>    * testsuite/20_util/is_literal_type/deprecated-1z.cc: New.

>    * testsuite/20_util/is_literal_type/requirements/explicit_instantiation.cc:

>    Adjust.

>    * testsuite/20_util/is_literal_type/requirements/typedefs.cc: Likewise.

>    * testsuite/20_util/is_literal_type/value.cc: Likewise.

>    * testsuite/20_util/variant/95915.cc: New.

>    * testsuite/20_util/variant/compile.cc: Add new test.


+
>+// { dg-prune-output "declared here" }

>diff --git a/libstdc++-v3/testsuite/20_util/is_literal_type/requirements/explicit_instantiation.cc b/libstdc++-v3/testsuite/20_util/is_literal_type/requirements/explicit_instantiation.cc

>index d0a20f3cf4e..d9c57bb8ef4 100644

>--- a/libstdc++-v3/testsuite/20_util/is_literal_type/requirements/explicit_instantiation.cc

>+++ b/libstdc++-v3/testsuite/20_util/is_literal_type/requirements/explicit_instantiation.cc

>@@ -1,3 +1,4 @@

>+// { dg-options "-Wno-deprecated" }


For these three tests I think this would be slightly better:

// { dg-additional-options "-Wno-deprecated" { target c++17 } }

That way we only ignore the warning when actually needed.

> // { dg-do compile { target c++11 } }

> // 2010-02-21  Paolo Carlini  <paolo.carlini@oracle.com>

> 

>diff --git a/libstdc++-v3/testsuite/20_util/is_literal_type/requirements/typedefs.cc b/libstdc++-v3/testsuite/20_util/is_literal_type/requirements/typedefs.cc

>index 9b7ae894725..24f508805f2 100644

>--- a/libstdc++-v3/testsuite/20_util/is_literal_type/requirements/typedefs.cc

>+++ b/libstdc++-v3/testsuite/20_util/is_literal_type/requirements/typedefs.cc

>@@ -1,3 +1,4 @@

>+// { dg-options "-Wno-deprecated" }

> // { dg-do compile { target c++11 } }

> 

> // 2010-02-21  Paolo Carlini  <paolo.carlini@oracle.com>

>diff --git a/libstdc++-v3/testsuite/20_util/is_literal_type/value.cc b/libstdc++-v3/testsuite/20_util/is_literal_type/value.cc

>index a6624774ef0..3bd6fe373f7 100644

>--- a/libstdc++-v3/testsuite/20_util/is_literal_type/value.cc

>+++ b/libstdc++-v3/testsuite/20_util/is_literal_type/value.cc

>@@ -1,3 +1,4 @@

>+// { dg-options "-Wno-deprecated" }

> // { dg-do compile { target c++11 } }

> 

> // 2010-03-23  Paolo Carlini  <paolo.carlini@oracle.com>


OK for master and gcc-10 with that change. Thanks!
Peter Bergner via Gcc-patches June 27, 2020, 2:53 p.m. | #3
On Fri, 26 Jun 2020 at 21:20, Jonathan Wakely <jwakely@redhat.com> wrote:
> For these three tests I think this would be slightly better:

>

> // { dg-additional-options "-Wno-deprecated" { target c++17 } }

>

> That way we only ignore the warning when actually needed.


Sure thing. The test run revealed some additional things to tweak. OK for trunk
and GCC 10?

2020-06-27  Ville Voutilainen  <ville.voutilainen@gmail.com>

    PR libstdc++/95915
    * include/std/type_traits (is_literal_type, is_literal_type_v):
    Deprecate in C++17.
    * include/std/variant (_Uninitialized):
    Adjust the condition and the comment.
    * testsuite/20_util/is_literal_type/deprecated-1z.cc: New.
    * testsuite/20_util/is_literal_type/requirements/explicit_instantiation.cc:
    Adjust.
    * testsuite/20_util/is_literal_type/requirements/typedefs.cc: Likewise.
    * testsuite/20_util/is_literal_type/value.cc: Likewise.
    * testsuite/20_util/optional/constexpr/nullopt.cc:
    Use __is_literal_type directly.
    * testsuite/20_util/optional/nullopt.cc: Likewise.
    * testsuite/20_util/variable_templates_for_traits.cc: Adjust.
    * testsuite/20_util/variant/95915.cc: New.
    * testsuite/20_util/variant/compile.cc: Add new test.
    * testsuite/experimental/optional/constexpr/nullopt.cc:
    Use __is_literal_type directly.
    * testsuite/experimental/optional/nullopt.cc: Likewise.
    * testsuite/experimental/type_traits/value.cc: Adjust.
    * testsuite/util/testsuite_common_types.h:
    Use __is_literal_type directly.
diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-v3/include/std/type_traits
index bc9a45b3746..9cd3a2df41a 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -703,7 +703,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   /// is_literal_type
   template<typename _Tp>
-    struct is_literal_type
+    struct
+    _GLIBCXX17_DEPRECATED
+    is_literal_type
     : public integral_constant<bool, __is_literal_type(_Tp)>
     {
       static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
@@ -3085,10 +3087,11 @@ template <typename _Tp>
 template <typename _Tp>
   _GLIBCXX20_DEPRECATED("use is_standard_layout_v && is_trivial_v instead")
   inline constexpr bool is_pod_v = is_pod<_Tp>::value;
-#pragma GCC diagnostic pop
 template <typename _Tp>
+  _GLIBCXX17_DEPRECATED
   inline constexpr bool is_literal_type_v = is_literal_type<_Tp>::value;
-template <typename _Tp>
+#pragma GCC diagnostic pop
+ template <typename _Tp>
   inline constexpr bool is_empty_v = is_empty<_Tp>::value;
 template <typename _Tp>
   inline constexpr bool is_polymorphic_v = is_polymorphic<_Tp>::value;
diff --git a/libstdc++-v3/include/std/variant b/libstdc++-v3/include/std/variant
index 6eeb3c80ec2..c9504914365 100644
--- a/libstdc++-v3/include/std/variant
+++ b/libstdc++-v3/include/std/variant
@@ -202,15 +202,9 @@ namespace __variant
 	  std::forward<_Variants>(__variants)...);
     }
 
-  // _Uninitialized<T> is guaranteed to be a literal type, even if T is not.
-  // We have to do this, because [basic.types]p10.5.3 (n4606) is not implemented
-  // yet. When it's implemented, _Uninitialized<T> can be changed to the alias
-  // to T, therefore equivalent to being removed entirely.
-  //
-  // Another reason we may not want to remove _Uninitialzied<T> may be that, we
-  // want _Uninitialized<T> to be trivially destructible, no matter whether T
-  // is; but we will see.
-  template<typename _Type, bool = std::is_literal_type_v<_Type>>
+  // _Uninitialized<T> is guaranteed to be a trivially destructible type,
+  // even if T is not.
+  template<typename _Type, bool = std::is_trivially_destructible_v<_Type>>
     struct _Uninitialized;
 
   template<typename _Type>
diff --git a/libstdc++-v3/testsuite/20_util/is_literal_type/deprecated-1z.cc b/libstdc++-v3/testsuite/20_util/is_literal_type/deprecated-1z.cc
new file mode 100644
index 00000000000..a91ff56dcf6
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/is_literal_type/deprecated-1z.cc
@@ -0,0 +1,26 @@
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++17" }
+// { dg-do compile { target c++17 } }
+
+#include <type_traits>
+
+static_assert(std::is_literal_type<int>::value); // { dg-warning "is deprecated" }
+static_assert(std::is_literal_type_v<int>); // { dg-warning "is deprecated" }
+
+// { dg-prune-output "declared here" }
diff --git a/libstdc++-v3/testsuite/20_util/is_literal_type/requirements/explicit_instantiation.cc b/libstdc++-v3/testsuite/20_util/is_literal_type/requirements/explicit_instantiation.cc
index d0a20f3cf4e..aa2a80e84e4 100644
--- a/libstdc++-v3/testsuite/20_util/is_literal_type/requirements/explicit_instantiation.cc
+++ b/libstdc++-v3/testsuite/20_util/is_literal_type/requirements/explicit_instantiation.cc
@@ -1,3 +1,4 @@
+// { dg-additional-options "-Wno-deprecated" { target c++17 } }
 // { dg-do compile { target c++11 } }
 // 2010-02-21  Paolo Carlini  <paolo.carlini@oracle.com>
 
diff --git a/libstdc++-v3/testsuite/20_util/is_literal_type/requirements/typedefs.cc b/libstdc++-v3/testsuite/20_util/is_literal_type/requirements/typedefs.cc
index 9b7ae894725..2bb75544280 100644
--- a/libstdc++-v3/testsuite/20_util/is_literal_type/requirements/typedefs.cc
+++ b/libstdc++-v3/testsuite/20_util/is_literal_type/requirements/typedefs.cc
@@ -1,3 +1,4 @@
+// { dg-additional-options "-Wno-deprecated" { target c++17 } }
 // { dg-do compile { target c++11 } }
 
 // 2010-02-21  Paolo Carlini  <paolo.carlini@oracle.com>
diff --git a/libstdc++-v3/testsuite/20_util/is_literal_type/value.cc b/libstdc++-v3/testsuite/20_util/is_literal_type/value.cc
index a6624774ef0..56c5b8d268f 100644
--- a/libstdc++-v3/testsuite/20_util/is_literal_type/value.cc
+++ b/libstdc++-v3/testsuite/20_util/is_literal_type/value.cc
@@ -1,3 +1,4 @@
+// { dg-additional-options "-Wno-deprecated" { target c++17 } }
 // { dg-do compile { target c++11 } }
 
 // 2010-03-23  Paolo Carlini  <paolo.carlini@oracle.com>
diff --git a/libstdc++-v3/testsuite/20_util/optional/constexpr/nullopt.cc b/libstdc++-v3/testsuite/20_util/optional/constexpr/nullopt.cc
index 62b66814e97..d66728e3700 100644
--- a/libstdc++-v3/testsuite/20_util/optional/constexpr/nullopt.cc
+++ b/libstdc++-v3/testsuite/20_util/optional/constexpr/nullopt.cc
@@ -26,7 +26,7 @@ int main()
   // [20.5.6] Disengaged state indicator
   static_assert( std::is_same<decltype(std::nullopt), const std::nullopt_t>(), "" );
   static_assert( std::is_empty<std::nullopt_t>(), "" );
-  static_assert( std::is_literal_type<std::nullopt_t>(), "" );
+  static_assert( __is_literal_type(std::nullopt_t), "" );
   static_assert( !std::is_default_constructible<std::nullopt_t>(), "" );
 
   {
diff --git a/libstdc++-v3/testsuite/20_util/optional/nullopt.cc b/libstdc++-v3/testsuite/20_util/optional/nullopt.cc
index c0b2184aa58..325e52802b9 100644
--- a/libstdc++-v3/testsuite/20_util/optional/nullopt.cc
+++ b/libstdc++-v3/testsuite/20_util/optional/nullopt.cc
@@ -26,7 +26,7 @@ int main()
   // [20.5.6] Disengaged state indicator
   static_assert( std::is_same<decltype(std::nullopt), const std::nullopt_t>(), "" );
   static_assert( std::is_empty<std::nullopt_t>(), "" );
-  static_assert( std::is_literal_type<std::nullopt_t>(), "" );
+  static_assert( __is_literal_type(std::nullopt_t), "" );
   static_assert( !std::is_default_constructible<std::nullopt_t>(), "" );
 
   {
diff --git a/libstdc++-v3/testsuite/20_util/variable_templates_for_traits.cc b/libstdc++-v3/testsuite/20_util/variable_templates_for_traits.cc
index 40a3f41e0e5..0f1625a8cb6 100644
--- a/libstdc++-v3/testsuite/20_util/variable_templates_for_traits.cc
+++ b/libstdc++-v3/testsuite/20_util/variable_templates_for_traits.cc
@@ -147,10 +147,13 @@ static_assert(is_pod_v<int>
 static_assert(!is_pod_v<NType>
 	      && !is_pod<NType>::value, "");
 
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
 static_assert(is_literal_type_v<int>
 	      && is_literal_type<int>::value, "");
 static_assert(!is_literal_type_v<NType>
 	      && !is_literal_type<NType>::value, "");
+#pragma GCC diagnostic pop
 
 static_assert(is_empty_v<EmptyFinal>
 	      && is_empty<EmptyFinal>::value, "");
diff --git a/libstdc++-v3/testsuite/20_util/variant/95915.cc b/libstdc++-v3/testsuite/20_util/variant/95915.cc
new file mode 100644
index 00000000000..411ff2d36ae
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/variant/95915.cc
@@ -0,0 +1,35 @@
+// { dg-options "-std=gnu++20" }
+// { dg-do compile { target c++20 } }
+
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <variant>
+
+using namespace std;
+
+struct virtual_default_dtor {
+   virtual ~virtual_default_dtor() = default;
+};
+
+void default_ctor()
+{
+  {
+    variant<virtual_default_dtor> a;
+  }
+}
+
diff --git a/libstdc++-v3/testsuite/20_util/variant/compile.cc b/libstdc++-v3/testsuite/20_util/variant/compile.cc
index b2b60d1cf10..5f681754b5f 100644
--- a/libstdc++-v3/testsuite/20_util/variant/compile.cc
+++ b/libstdc++-v3/testsuite/20_util/variant/compile.cc
@@ -84,6 +84,10 @@ struct nonliteral
   bool operator>(const nonliteral&) const;
 };
 
+struct virtual_default_dtor {
+   virtual ~virtual_default_dtor() = default;
+};
+
 void default_ctor()
 {
   static_assert(is_default_constructible_v<variant<int, string>>);
@@ -95,6 +99,9 @@ void default_ctor()
   static_assert(noexcept(variant<int>()));
   static_assert(!noexcept(variant<Empty>()));
   static_assert(noexcept(variant<DefaultNoexcept>()));
+  {
+    variant<virtual_default_dtor> a;
+  }
 }
 
 void copy_ctor()
diff --git a/libstdc++-v3/testsuite/experimental/optional/constexpr/nullopt.cc b/libstdc++-v3/testsuite/experimental/optional/constexpr/nullopt.cc
index 3aa9d0c4c33..6fe9a2a051d 100644
--- a/libstdc++-v3/testsuite/experimental/optional/constexpr/nullopt.cc
+++ b/libstdc++-v3/testsuite/experimental/optional/constexpr/nullopt.cc
@@ -25,7 +25,7 @@ int main()
   // [20.5.6] Disengaged state indicator
   static_assert( std::is_same<decltype(std::experimental::nullopt), const std::experimental::nullopt_t>(), "" );
   static_assert( std::is_empty<std::experimental::nullopt_t>(), "" );
-  static_assert( std::is_literal_type<std::experimental::nullopt_t>(), "" );
+  static_assert( __is_literal_type(std::experimental::nullopt_t), "" );
   static_assert( !std::is_default_constructible<std::experimental::nullopt_t>(), "" );
 
   {
diff --git a/libstdc++-v3/testsuite/experimental/optional/nullopt.cc b/libstdc++-v3/testsuite/experimental/optional/nullopt.cc
index e31fc379e9e..73f6b534b87 100644
--- a/libstdc++-v3/testsuite/experimental/optional/nullopt.cc
+++ b/libstdc++-v3/testsuite/experimental/optional/nullopt.cc
@@ -25,7 +25,7 @@ int main()
   // [20.5.6] Disengaged state indicator
   static_assert( std::is_same<decltype(std::experimental::nullopt), const std::experimental::nullopt_t>(), "" );
   static_assert( std::is_empty<std::experimental::nullopt_t>(), "" );
-  static_assert( std::is_literal_type<std::experimental::nullopt_t>(), "" );
+  static_assert( __is_literal_type(std::experimental::nullopt_t), "" );
   static_assert( !std::is_default_constructible<std::experimental::nullopt_t>(), "" );
 
   {
diff --git a/libstdc++-v3/testsuite/experimental/type_traits/value.cc b/libstdc++-v3/testsuite/experimental/type_traits/value.cc
index 0e1176dd14a..52a6e69cc55 100644
--- a/libstdc++-v3/testsuite/experimental/type_traits/value.cc
+++ b/libstdc++-v3/testsuite/experimental/type_traits/value.cc
@@ -214,10 +214,13 @@ static_assert(is_pod_v<int>
 static_assert(!is_pod_v<NType>
 	      && !is_pod<NType>::value, "");
 
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
 static_assert(is_literal_type_v<int>
 	      && is_literal_type<int>::value, "");
 static_assert(!is_literal_type_v<NType>
 	      && !is_literal_type<NType>::value, "");
+#pragma GCC diagnostic pop
 
 static_assert(is_empty_v<EmptyFinal>
 	      && is_empty<EmptyFinal>::value, "");
diff --git a/libstdc++-v3/testsuite/util/testsuite_common_types.h b/libstdc++-v3/testsuite/util/testsuite_common_types.h
index 2795df36ca3..92af3af7773 100644
--- a/libstdc++-v3/testsuite/util/testsuite_common_types.h
+++ b/libstdc++-v3/testsuite/util/testsuite_common_types.h
@@ -749,7 +749,7 @@ namespace __gnu_test
   // Generator to test default constructor.
   struct constexpr_default_constructible
   {
-    template<typename _Tp, bool _IsLitp = std::is_literal_type<_Tp>::value>
+    template<typename _Tp, bool _IsLitp = __is_literal_type(_Tp)>
       struct _Concept;
 
     // NB: _Tp must be a literal type.
@@ -801,7 +801,7 @@ namespace __gnu_test
   struct constexpr_single_value_constructible
   {
     template<typename _Ttesttype, typename _Tvaluetype,
-	     bool _IsLitp = std::is_literal_type<_Ttesttype>::value>
+	     bool _IsLitp = __is_literal_type(_Ttesttype)>
       struct _Concept;
 
     // NB: _Tvaluetype and _Ttesttype must be literal types.
Peter Bergner via Gcc-patches June 27, 2020, 3:20 p.m. | #4
On Sat, 27 Jun 2020 at 17:53, Ville Voutilainen
<ville.voutilainen@gmail.com> wrote:
>

> On Fri, 26 Jun 2020 at 21:20, Jonathan Wakely <jwakely@redhat.com> wrote:

> > For these three tests I think this would be slightly better:

> >

> > // { dg-additional-options "-Wno-deprecated" { target c++17 } }

> >

> > That way we only ignore the warning when actually needed.

>

> Sure thing. The test run revealed some additional things to tweak. OK for trunk

> and GCC 10?


With a twist, I mean. I don't plan to backport the deprecation, just
the bug fix for variant.
Peter Bergner via Gcc-patches June 28, 2020, 9:18 p.m. | #5
On 27/06/20 18:20 +0300, Ville Voutilainen via Libstdc++ wrote:
>On Sat, 27 Jun 2020 at 17:53, Ville Voutilainen

><ville.voutilainen@gmail.com> wrote:

>>

>> On Fri, 26 Jun 2020 at 21:20, Jonathan Wakely <jwakely@redhat.com> wrote:

>> > For these three tests I think this would be slightly better:

>> >

>> > // { dg-additional-options "-Wno-deprecated" { target c++17 } }

>> >

>> > That way we only ignore the warning when actually needed.

>>

>> Sure thing. The test run revealed some additional things to tweak. OK for trunk

>> and GCC 10?

>

>With a twist, I mean. I don't plan to backport the deprecation, just

>the bug fix for variant.



OK, thanks

Patch

diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-v3/include/std/type_traits
index bc9a45b3746..261f25d21e7 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -703,7 +703,9 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   /// is_literal_type
   template<typename _Tp>
-    struct is_literal_type
+    struct
+    _GLIBCXX17_DEPRECATED
+    is_literal_type
     : public integral_constant<bool, __is_literal_type(_Tp)>
     {
       static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
@@ -3087,6 +3089,7 @@  template <typename _Tp>
   inline constexpr bool is_pod_v = is_pod<_Tp>::value;
 #pragma GCC diagnostic pop
 template <typename _Tp>
+  _GLIBCXX17_DEPRECATED
   inline constexpr bool is_literal_type_v = is_literal_type<_Tp>::value;
 template <typename _Tp>
   inline constexpr bool is_empty_v = is_empty<_Tp>::value;
diff --git a/libstdc++-v3/include/std/variant b/libstdc++-v3/include/std/variant
index 6eeb3c80ec2..c9504914365 100644
--- a/libstdc++-v3/include/std/variant
+++ b/libstdc++-v3/include/std/variant
@@ -202,15 +202,9 @@  namespace __variant
 	  std::forward<_Variants>(__variants)...);
     }
 
-  // _Uninitialized<T> is guaranteed to be a literal type, even if T is not.
-  // We have to do this, because [basic.types]p10.5.3 (n4606) is not implemented
-  // yet. When it's implemented, _Uninitialized<T> can be changed to the alias
-  // to T, therefore equivalent to being removed entirely.
-  //
-  // Another reason we may not want to remove _Uninitialzied<T> may be that, we
-  // want _Uninitialized<T> to be trivially destructible, no matter whether T
-  // is; but we will see.
-  template<typename _Type, bool = std::is_literal_type_v<_Type>>
+  // _Uninitialized<T> is guaranteed to be a trivially destructible type,
+  // even if T is not.
+  template<typename _Type, bool = std::is_trivially_destructible_v<_Type>>
     struct _Uninitialized;
 
   template<typename _Type>
diff --git a/libstdc++-v3/testsuite/20_util/is_literal_type/deprecated-1z.cc b/libstdc++-v3/testsuite/20_util/is_literal_type/deprecated-1z.cc
new file mode 100644
index 00000000000..a91ff56dcf6
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/is_literal_type/deprecated-1z.cc
@@ -0,0 +1,26 @@ 
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++17" }
+// { dg-do compile { target c++17 } }
+
+#include <type_traits>
+
+static_assert(std::is_literal_type<int>::value); // { dg-warning "is deprecated" }
+static_assert(std::is_literal_type_v<int>); // { dg-warning "is deprecated" }
+
+// { dg-prune-output "declared here" }
diff --git a/libstdc++-v3/testsuite/20_util/is_literal_type/requirements/explicit_instantiation.cc b/libstdc++-v3/testsuite/20_util/is_literal_type/requirements/explicit_instantiation.cc
index d0a20f3cf4e..d9c57bb8ef4 100644
--- a/libstdc++-v3/testsuite/20_util/is_literal_type/requirements/explicit_instantiation.cc
+++ b/libstdc++-v3/testsuite/20_util/is_literal_type/requirements/explicit_instantiation.cc
@@ -1,3 +1,4 @@ 
+// { dg-options "-Wno-deprecated" }
 // { dg-do compile { target c++11 } }
 // 2010-02-21  Paolo Carlini  <paolo.carlini@oracle.com>
 
diff --git a/libstdc++-v3/testsuite/20_util/is_literal_type/requirements/typedefs.cc b/libstdc++-v3/testsuite/20_util/is_literal_type/requirements/typedefs.cc
index 9b7ae894725..24f508805f2 100644
--- a/libstdc++-v3/testsuite/20_util/is_literal_type/requirements/typedefs.cc
+++ b/libstdc++-v3/testsuite/20_util/is_literal_type/requirements/typedefs.cc
@@ -1,3 +1,4 @@ 
+// { dg-options "-Wno-deprecated" }
 // { dg-do compile { target c++11 } }
 
 // 2010-02-21  Paolo Carlini  <paolo.carlini@oracle.com>
diff --git a/libstdc++-v3/testsuite/20_util/is_literal_type/value.cc b/libstdc++-v3/testsuite/20_util/is_literal_type/value.cc
index a6624774ef0..3bd6fe373f7 100644
--- a/libstdc++-v3/testsuite/20_util/is_literal_type/value.cc
+++ b/libstdc++-v3/testsuite/20_util/is_literal_type/value.cc
@@ -1,3 +1,4 @@ 
+// { dg-options "-Wno-deprecated" }
 // { dg-do compile { target c++11 } }
 
 // 2010-03-23  Paolo Carlini  <paolo.carlini@oracle.com>
diff --git a/libstdc++-v3/testsuite/20_util/variant/95915.cc b/libstdc++-v3/testsuite/20_util/variant/95915.cc
new file mode 100644
index 00000000000..411ff2d36ae
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/variant/95915.cc
@@ -0,0 +1,35 @@ 
+// { dg-options "-std=gnu++20" }
+// { dg-do compile { target c++20 } }
+
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <variant>
+
+using namespace std;
+
+struct virtual_default_dtor {
+   virtual ~virtual_default_dtor() = default;
+};
+
+void default_ctor()
+{
+  {
+    variant<virtual_default_dtor> a;
+  }
+}
+
diff --git a/libstdc++-v3/testsuite/20_util/variant/compile.cc b/libstdc++-v3/testsuite/20_util/variant/compile.cc
index b2b60d1cf10..5f681754b5f 100644
--- a/libstdc++-v3/testsuite/20_util/variant/compile.cc
+++ b/libstdc++-v3/testsuite/20_util/variant/compile.cc
@@ -84,6 +84,10 @@  struct nonliteral
   bool operator>(const nonliteral&) const;
 };
 
+struct virtual_default_dtor {
+   virtual ~virtual_default_dtor() = default;
+};
+
 void default_ctor()
 {
   static_assert(is_default_constructible_v<variant<int, string>>);
@@ -95,6 +99,9 @@  void default_ctor()
   static_assert(noexcept(variant<int>()));
   static_assert(!noexcept(variant<Empty>()));
   static_assert(noexcept(variant<DefaultNoexcept>()));
+  {
+    variant<virtual_default_dtor> a;
+  }
 }
 
 void copy_ctor()