diff mbox series

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] | expand

Commit Message

Ville Voutilainen June 26, 2020, 4:12 p.m. UTC
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

Ville Voutilainen June 26, 2020, 4:18 p.m. UTC | #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.
Jonathan Wakely June 26, 2020, 6:20 p.m. UTC | #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!
Ville Voutilainen June 27, 2020, 2:53 p.m. UTC | #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.
Ville Voutilainen June 27, 2020, 3:20 p.m. UTC | #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.
Jonathan Wakely June 28, 2020, 9:18 p.m. UTC | #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
diff mbox series

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()