PR libstdc++/89345 Only define std::destroying_delete for C++2a
authorJonathan Wakely <jwakely@redhat.com>
Wed, 13 Feb 2019 22:13:45 +0000 (22:13 +0000)
committerJonathan Wakely <redi@gcc.gnu.org>
Wed, 13 Feb 2019 22:13:45 +0000 (22:13 +0000)
Clang defines the __cpp_impl_destroying_delete macro unconditionally, so
that the feature is supported whenever the library type is defined. This
is incompatible with the current definition in libstdc++ because we use
constexpr and inline variables, which will give an error for older -std
modes.

This patch defines the destroying_delete_t type and destroying_delete
variable independently of the __cpp_impl_destroying_delete macro, but
only for C++2a (because the names aren't reserved for previous
standards). The __cpp_lib_destroying_delete macro is only defined when
both the library type and compiler macro are defined (i.e. when the type
can actually be used as intended).

PR libstdc++/89345
* include/std/version [__cpp_impl_destroying_delete]
(__cpp_lib_destroying_delete): Only define for C++2a and later.
* libsupc++/new [__cpp_impl_destroying_delete]
(__cpp_lib_destroying_delete): Likewise.
(destroying_delete_t, destroying_delete): Likewise, but define even
when __cpp_impl_destroying_delete is not defined.
* testsuite/18_support/destroying_delete.cc: New test.

From-SVN: r268856

libstdc++-v3/ChangeLog
libstdc++-v3/include/std/version
libstdc++-v3/libsupc++/new
libstdc++-v3/testsuite/18_support/destroying_delete.cc [new file with mode: 0644]

index d792ea6556b73678734d54964e306330a2848616..e8be1b866306ea06a58cc5509565c22d3570c25d 100644 (file)
@@ -1,3 +1,14 @@
+2019-02-13  Jonathan Wakely  <jwakely@redhat.com>
+
+       PR libstdc++/89345
+       * include/std/version [__cpp_impl_destroying_delete]
+       (__cpp_lib_destroying_delete): Only define for C++2a and later.
+       * libsupc++/new [__cpp_impl_destroying_delete]
+       (__cpp_lib_destroying_delete): Likewise.
+       (destroying_delete_t, destroying_delete): Likewise, but define even
+       when __cpp_impl_destroying_delete is not defined.
+       * testsuite/18_support/destroying_delete.cc: New test.
+
 2019-02-11  Jonathan Wakely  <jwakely@redhat.com>
 
        PR libstdc++/89023
index 38277b9ecf2c4173f6101cc19dd410b25584f2a2..fa3d473759b1433691f71d853595041f1470dc06 100644 (file)
 # define __cpp_lib_uncaught_exceptions 201411L
 #endif
 
-#if __cpp_impl_destroying_delete
-# define __cpp_lib_destroying_delete 201806L
-#endif
-
 #if __cplusplus >= 201103L
 // c++11
 #define __cpp_lib_allocator_is_always_equal 201411
 
 #if __cplusplus > 201703L
 // c++2a
+#if __cpp_impl_destroying_delete
+# define __cpp_lib_destroying_delete 201806L
+#endif
 #define __cpp_lib_erase_if 201900L
 #ifdef _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED
 # define __cpp_lib_is_constant_evaluated 201811L
index 6347d21b26f74a938492a2db381b44563619d5c0..24d897a8f22fae2b99bf519774c7997c66129bb8 100644 (file)
@@ -208,8 +208,7 @@ namespace std
 #endif // _GLIBCXX_HAVE_BUILTIN_LAUNDER
 #endif // C++17
 
-#if __cpp_impl_destroying_delete
-#define __cpp_lib_destroying_delete 201806L
+#if __cplusplus > 201703L
 namespace std
 {
   struct destroying_delete_t
@@ -218,7 +217,11 @@ namespace std
   };
   inline constexpr destroying_delete_t destroying_delete{};
 }
-#endif // destroying delete
+// Only define the feature test macro if the compiler supports the feature:
+#if __cpp_impl_destroying_delete
+# define __cpp_lib_destroying_delete 201806L
+#endif
+#endif // C++20
 
 #pragma GCC visibility pop
 
diff --git a/libstdc++-v3/testsuite/18_support/destroying_delete.cc b/libstdc++-v3/testsuite/18_support/destroying_delete.cc
new file mode 100644 (file)
index 0000000..8682ccc
--- /dev/null
@@ -0,0 +1,58 @@
+// Copyright (C) 2019 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++2a" }
+// { dg-do run { target c++2a } }
+
+#include <new>
+#include <testsuite_hooks.h>
+
+#ifndef __cpp_lib_destroying_delete
+# error "Feature-test macro for destroying_delete missing"
+#elif __cpp_lib_destroying_delete != 201806L
+# error "Feature-test macro for destroying_delete has wrong value"
+#endif
+
+const std::destroying_delete_t d{};
+static_assert(std::is_same_v<decltype(d), decltype(std::destroying_delete)>);
+
+struct X
+{
+  static bool called;
+
+  void operator delete(X* p, std::destroying_delete_t)
+  {
+    called = true;
+    p->~X();
+    ::operator delete(p);
+  }
+};
+
+bool X::called = false;
+
+void
+test01()
+{
+  X* x = new X;
+  delete x;
+  VERIFY( X::called );
+}
+
+int main()
+{
+  test01();
+}