From 329c0f891a8e5a18ef8154abca252aeb23585ce2 Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Wed, 13 Feb 2019 22:13:45 +0000 Subject: [PATCH] PR libstdc++/89345 Only define std::destroying_delete for C++2a 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 | 11 ++++ libstdc++-v3/include/std/version | 7 +-- libstdc++-v3/libsupc++/new | 9 ++- .../testsuite/18_support/destroying_delete.cc | 58 +++++++++++++++++++ 4 files changed, 78 insertions(+), 7 deletions(-) create mode 100644 libstdc++-v3/testsuite/18_support/destroying_delete.cc diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index d792ea6556b..e8be1b86630 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,14 @@ +2019-02-13 Jonathan Wakely + + 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 PR libstdc++/89023 diff --git a/libstdc++-v3/include/std/version b/libstdc++-v3/include/std/version index 38277b9ecf2..fa3d473759b 100644 --- a/libstdc++-v3/include/std/version +++ b/libstdc++-v3/include/std/version @@ -42,10 +42,6 @@ # 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 @@ -152,6 +148,9 @@ #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 diff --git a/libstdc++-v3/libsupc++/new b/libstdc++-v3/libsupc++/new index 6347d21b26f..24d897a8f22 100644 --- a/libstdc++-v3/libsupc++/new +++ b/libstdc++-v3/libsupc++/new @@ -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 index 00000000000..8682ccce9fd --- /dev/null +++ b/libstdc++-v3/testsuite/18_support/destroying_delete.cc @@ -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 +// . + +// { dg-options "-std=gnu++2a" } +// { dg-do run { target c++2a } } + +#include +#include + +#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); + +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(); +}