libstdc++: Gate constexpr string and vector on constexpr destructor support
Commit Message
I was going to push this patch to "fix" our C++20 constexpr string and
vector so they depend on __cpp_constexpr_dynamic_alloc. But then I
realised that Clang supports that since 10.0.0 and I don't think we need
to bother supporting anything older than that for C++20 mode (Clang 9
users can still use C++17 mode).
So I'm just posting this here for the archives, but I don't plan to
push it. We could probably remove the __cpp_constexpr_dynamic_alloc
checks in std::allocator and std::unique_ptr now too.
-- >8 --
Declaring a destructor as constexpr is only supported when the
__cpp_constexpr_dynamic_alloc macro is defined. Introduce a new macro,
_GLIBCXX_CONSTEXPR_DTOR, which can be used on destructors. Adjust the
relevant feature test macros to also depend on
__cpp_constexpr_dynamic_alloc.
libstdc++-v3/ChangeLog:
* include/bits/c++config (_GLIBCXX_CONSTEXPR_DTOR): Define new
macro.
(_GLIBCXX23_CONSTEXPR_DTOR): Likewise.
* include/bits/allocator.h (allocator::~allocator()): Use new
macro.
* include/bits/basic_string.h (__cpp_lib_constexpr_string):
Depend on __cpp_constexpr_dynamic_alloc.
(basic_string::~basic_string()): Use new macro.
* include/bits/stl_vector.h (__cpp_lib_constexpr_vector):
Depend on __cpp_constexpr_dynamic_alloc.
(_Vector_base::~_Vector_base(), vector::~vector()): Use new
macro.
* include/bits/unique_ptr.h (unique_ptr, unique_ptr<T[], D>):
Likewise.
* include/std/version (__cpp_lib_constexpr_string)
(__cpp_lib_constexpr_vector): Depend on
__cpp_constexpr_dynamic_alloc.
---
libstdc++-v3/include/bits/allocator.h | 4 +---
libstdc++-v3/include/bits/basic_string.h | 11 ++++++++---
libstdc++-v3/include/bits/c++config | 12 ++++++++++++
libstdc++-v3/include/bits/stl_vector.h | 14 ++++++++------
libstdc++-v3/include/bits/unique_ptr.h | 8 ++------
libstdc++-v3/include/std/version | 6 ++++--
6 files changed, 35 insertions(+), 20 deletions(-)
@@ -168,9 +168,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_GLIBCXX20_CONSTEXPR
allocator(const allocator<_Tp1>&) _GLIBCXX_NOTHROW { }
-#if __cpp_constexpr_dynamic_alloc
- constexpr
-#endif
+ _GLIBCXX_CONSTEXPR_DTOR
~allocator() _GLIBCXX_NOTHROW { }
#if __cplusplus > 201703L
@@ -56,9 +56,14 @@ namespace std _GLIBCXX_VISIBILITY(default)
_GLIBCXX_BEGIN_NAMESPACE_VERSION
_GLIBCXX_BEGIN_NAMESPACE_CXX11
-#ifdef __cpp_lib_is_constant_evaluated
+#if __cpp_lib_is_constant_evaluated
+# if __cpp_constexpr_dynamic_alloc
// Support P0980R1 in C++20.
-# define __cpp_lib_constexpr_string 201907L
+# define __cpp_lib_constexpr_string 201907L
+# else
+// Support P1032R1 in C++20.
+# define __cpp_lib_constexpr_string 201811L
+# endif
#elif __cplusplus >= 201703L && _GLIBCXX_HAVE_IS_CONSTANT_EVALUATED
// Support P0426R1 changes to char_traits in C++17.
# define __cpp_lib_constexpr_string 201611L
@@ -790,7 +795,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
/**
* @brief Destroy the string instance.
*/
- _GLIBCXX20_CONSTEXPR
+ _GLIBCXX_CONSTEXPR_DTOR
~basic_string()
{ _M_dispose(); }
@@ -190,6 +190,18 @@
# endif
#endif
+#ifdef __cpp_constexpr_dynamic_alloc
+# define _GLIBCXX_CONSTEXPR_DTOR constexpr
+#else
+# define _GLIBCXX_CONSTEXPR_DTOR
+#endif
+
+# if __cplusplus >= 202100L
+# define _GLIBCXX23_CONSTEXPR_DTOR _GLIBCXX_CONSTEXPR_DTOR
+#else
+# define _GLIBCXX23_CONSTEXPR_DTOR
+#endif
+
#ifndef _GLIBCXX17_INLINE
# if __cplusplus >= 201703L
# define _GLIBCXX17_INLINE inline
@@ -64,7 +64,9 @@
#endif
#if __cplusplus >= 202002L
# include <compare>
-#define __cpp_lib_constexpr_vector 201907L
+# ifdef __cpp_constexpr_dynamic_alloc
+# define __cpp_lib_constexpr_vector 201907L
+# endif
#endif
#include <debug/assertions.h>
@@ -229,7 +231,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
_S_on_dealloc(_M_impl);
}
- _GLIBCXX20_CONSTEXPR
+ _GLIBCXX_CONSTEXPR_DTOR
~_Reinit()
{
// Mark unused capacity as invalid after reallocation.
@@ -254,7 +256,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
: _M_impl(__impl), _M_n(__n)
{ _S_grow(_M_impl, __n); }
- _GLIBCXX20_CONSTEXPR
+ _GLIBCXX_CONSTEXPR_DTOR
~_Grow() { if (_M_n) _S_shrink(_M_impl, _M_n); }
_GLIBCXX20_CONSTEXPR
@@ -360,7 +362,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
{ }
#endif
- _GLIBCXX20_CONSTEXPR
+ _GLIBCXX_CONSTEXPR_DTOR
~_Vector_base() _GLIBCXX_NOEXCEPT
{
_M_deallocate(_M_impl._M_start,
@@ -724,7 +726,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* not touched in any way. Managing the pointer is the user's
* responsibility.
*/
- _GLIBCXX20_CONSTEXPR
+ _GLIBCXX_CONSTEXPR_DTOR
~vector() _GLIBCXX_NOEXCEPT
{
std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish,
@@ -1831,7 +1833,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
std::forward<_Args>(__args)...);
}
- _GLIBCXX20_CONSTEXPR
+ _GLIBCXX_CONSTEXPR_DTOR
~_Temporary_value()
{ _Alloc_traits::destroy(_M_this->_M_impl, _M_ptr()); }
@@ -384,9 +384,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
#endif
/// Destructor, invokes the deleter if the stored pointer is not null.
-#if __cplusplus > 202002L && __cpp_constexpr_dynamic_alloc
- constexpr
-#endif
+ _GLIBCXX23_CONSTEXPR_DTOR
~unique_ptr() noexcept
{
static_assert(__is_invocable<deleter_type&, pointer>::value,
@@ -659,9 +657,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ }
/// Destructor, invokes the deleter if the stored pointer is not null.
-#if __cplusplus > 202002L && __cpp_constexpr_dynamic_alloc
- constexpr
-#endif
+ _GLIBCXX23_CONSTEXPR_DTOR
~unique_ptr()
{
auto& __ptr = _M_t._M_ptr();
@@ -248,7 +248,7 @@
#define __cpp_lib_constexpr_memory 201811L
#define __cpp_lib_constexpr_numeric 201911L
#ifdef __cpp_lib_is_constant_evaluated
-# if _GLIBCXX_USE_CXX11_ABI
+# if _GLIBCXX_USE_CXX11_ABI && __cpp_constexpr_dynamic_alloc
# define __cpp_lib_constexpr_string 201907L
# else
# define __cpp_lib_constexpr_string 201811L
@@ -257,7 +257,9 @@
#define __cpp_lib_constexpr_string_view 201811L
#define __cpp_lib_constexpr_tuple 201811L
#define __cpp_lib_constexpr_utility 201811L
-#define __cpp_lib_constexpr_vector 201907L
+#if __cpp_constexpr_dynamic_alloc
+# define __cpp_lib_constexpr_vector 201907L
+#endif
#define __cpp_lib_erase_if 202002L
#define __cpp_lib_generic_unordered_lookup 201811L
#define __cpp_lib_interpolate 201902L