[libcxx-commits] [libcxx] d092c91 - [libc++] Fix constexpr dynamic allocation on GCC 10
Louis Dionne via libcxx-commits
libcxx-commits at lists.llvm.org
Mon Sep 28 14:44:40 PDT 2020
Author: Louis Dionne
Date: 2020-09-28T17:44:31-04:00
New Revision: d092c912885cc152bef27019525b8fd0761aaaa2
URL: https://github.com/llvm/llvm-project/commit/d092c912885cc152bef27019525b8fd0761aaaa2
DIFF: https://github.com/llvm/llvm-project/commit/d092c912885cc152bef27019525b8fd0761aaaa2.diff
LOG: [libc++] Fix constexpr dynamic allocation on GCC 10
We're technically not allowed by the Standard to call ::operator new in
constexpr functions like __libcpp_allocate. Clang doesn't seem to complain
about it, but GCC does.
Added:
Modified:
libcxx/include/memory
libcxx/include/new
libcxx/test/std/utilities/memory/specialized.algorithms/specialized.construct/construct_at.pass.cpp
libcxx/test/std/utilities/memory/specialized.algorithms/specialized.destroy/destroy_at.pass.cpp
Removed:
################################################################################
diff --git a/libcxx/include/memory b/libcxx/include/memory
index 112ee9d4462c..67a6ddde8fc8 100644
--- a/libcxx/include/memory
+++ b/libcxx/include/memory
@@ -1678,12 +1678,20 @@ public:
if (__n > allocator_traits<allocator>::max_size(*this))
__throw_length_error("allocator<T>::allocate(size_t n)"
" 'n' exceeds maximum supported size");
- return static_cast<_Tp*>(_VSTD::__libcpp_allocate(__n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp)));
+ if (__libcpp_is_constant_evaluated()) {
+ return static_cast<_Tp*>(::operator new(__n * sizeof(_Tp)));
+ } else {
+ return static_cast<_Tp*>(_VSTD::__libcpp_allocate(__n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp)));
+ }
}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
void deallocate(_Tp* __p, size_t __n) _NOEXCEPT {
- _VSTD::__libcpp_deallocate((void*)__p, __n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp));
+ if (__libcpp_is_constant_evaluated()) {
+ ::operator delete(__p);
+ } else {
+ _VSTD::__libcpp_deallocate((void*)__p, __n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp));
+ }
}
// C++20 Removed members
@@ -1751,12 +1759,20 @@ public:
if (__n > allocator_traits<allocator>::max_size(*this))
__throw_length_error("allocator<const T>::allocate(size_t n)"
" 'n' exceeds maximum supported size");
- return static_cast<const _Tp*>(_VSTD::__libcpp_allocate(__n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp)));
+ if (__libcpp_is_constant_evaluated()) {
+ return static_cast<const _Tp*>(::operator new(__n * sizeof(_Tp)));
+ } else {
+ return static_cast<const _Tp*>(_VSTD::__libcpp_allocate(__n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp)));
+ }
}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
void deallocate(const _Tp* __p, size_t __n) {
- _VSTD::__libcpp_deallocate((void*) const_cast<_Tp *>(__p), __n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp));
+ if (__libcpp_is_constant_evaluated()) {
+ ::operator delete(const_cast<_Tp*>(__p));
+ } else {
+ _VSTD::__libcpp_deallocate((void*) const_cast<_Tp *>(__p), __n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp));
+ }
}
// C++20 Removed members
diff --git a/libcxx/include/new b/libcxx/include/new
index 7db26b399229..dbfdab9abe4d 100644
--- a/libcxx/include/new
+++ b/libcxx/include/new
@@ -234,7 +234,7 @@ _LIBCPP_CONSTEXPR inline _LIBCPP_INLINE_VISIBILITY bool __is_overaligned_for_new
#endif
}
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+inline _LIBCPP_INLINE_VISIBILITY
void *__libcpp_allocate(size_t __size, size_t __align) {
#ifndef _LIBCPP_HAS_NO_ALIGNED_ALLOCATION
if (__is_overaligned_for_new(__align)) {
@@ -257,7 +257,6 @@ void *__libcpp_allocate(size_t __size, size_t __align) {
struct _DeallocateCaller {
template <class _A1, class _A2>
- _LIBCPP_CONSTEXPR_AFTER_CXX17
static inline void __do_call(void *__ptr, _A1 __a1, _A2 __a2) {
#if defined(_LIBCPP_HAS_NO_BUILTIN_OPERATOR_NEW_DELETE) || \
defined(_LIBCPP_HAS_NO_BUILTIN_OVERLOADED_OPERATOR_NEW_DELETE)
@@ -268,7 +267,6 @@ struct _DeallocateCaller {
}
template <class _A1>
- _LIBCPP_CONSTEXPR_AFTER_CXX17
static inline void __do_call(void *__ptr, _A1 __a1) {
#if defined(_LIBCPP_HAS_NO_BUILTIN_OPERATOR_NEW_DELETE) || \
defined(_LIBCPP_HAS_NO_BUILTIN_OVERLOADED_OPERATOR_NEW_DELETE)
@@ -278,7 +276,6 @@ struct _DeallocateCaller {
#endif
}
- _LIBCPP_CONSTEXPR_AFTER_CXX17
static inline void __do_call(void *__ptr) {
#ifdef _LIBCPP_HAS_NO_BUILTIN_OPERATOR_NEW_DELETE
return ::operator delete(__ptr);
@@ -287,7 +284,6 @@ struct _DeallocateCaller {
#endif
}
- _LIBCPP_CONSTEXPR_AFTER_CXX17
static inline void __do_deallocate_handle_size(void *__ptr, size_t __size) {
#ifdef _LIBCPP_HAS_NO_SIZED_DEALLOCATION
((void)__size);
@@ -298,7 +294,6 @@ struct _DeallocateCaller {
}
#ifndef _LIBCPP_HAS_NO_ALIGNED_ALLOCATION
- _LIBCPP_CONSTEXPR_AFTER_CXX17
static inline void __do_deallocate_handle_size(void *__ptr, size_t __size, align_val_t __align) {
#ifdef _LIBCPP_HAS_NO_SIZED_DEALLOCATION
((void)__size);
@@ -309,7 +304,7 @@ struct _DeallocateCaller {
}
#endif
- static inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+ static inline _LIBCPP_INLINE_VISIBILITY
void __do_deallocate_handle_size_align(void *__ptr, size_t __size, size_t __align) {
#if defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION)
((void)__align);
@@ -324,7 +319,7 @@ struct _DeallocateCaller {
#endif
}
- static inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+ static inline _LIBCPP_INLINE_VISIBILITY
void __do_deallocate_handle_align(void *__ptr, size_t __align) {
#if defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION)
((void)__align);
@@ -340,7 +335,7 @@ struct _DeallocateCaller {
}
};
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+inline _LIBCPP_INLINE_VISIBILITY
void __libcpp_deallocate(void* __ptr, size_t __size, size_t __align) {
_DeallocateCaller::__do_deallocate_handle_size_align(__ptr, __size, __align);
}
diff --git a/libcxx/test/std/utilities/memory/specialized.algorithms/specialized.construct/construct_at.pass.cpp b/libcxx/test/std/utilities/memory/specialized.algorithms/specialized.construct/construct_at.pass.cpp
index ac0c8a138115..9568b9c01bd3 100644
--- a/libcxx/test/std/utilities/memory/specialized.algorithms/specialized.construct/construct_at.pass.cpp
+++ b/libcxx/test/std/utilities/memory/specialized.algorithms/specialized.construct/construct_at.pass.cpp
@@ -8,6 +8,9 @@
// UNSUPPORTED: c++03, c++11, c++14, c++17
+// Investigation needed
+// UNSUPPORTED: gcc
+
// <memory>
// template <class T, class ...Args>
@@ -39,17 +42,24 @@ struct Counted {
constexpr bool test()
{
{
- int ints[1] = {0};
- int* res = std::construct_at(&ints[0], 42);
- assert(res == &ints[0]);
+ int i = 99;
+ int* res = std::construct_at(&i);
+ assert(res == &i);
+ assert(*res == 0);
+ }
+
+ {
+ int i = 0;
+ int* res = std::construct_at(&i, 42);
+ assert(res == &i);
assert(*res == 42);
}
{
- Foo foos[1] = {};
+ Foo foo = {};
int count = 0;
- Foo* res = std::construct_at(&foos[0], 42, 'x', 123.89, &count);
- assert(res == &foos[0]);
+ Foo* res = std::construct_at(&foo, 42, 'x', 123.89, &count);
+ assert(res == &foo);
assert(*res == Foo(42, 'x', 123.89));
assert(count == 1);
}
diff --git a/libcxx/test/std/utilities/memory/specialized.algorithms/specialized.destroy/destroy_at.pass.cpp b/libcxx/test/std/utilities/memory/specialized.algorithms/specialized.destroy/destroy_at.pass.cpp
index d3d1bac1376e..4db01cb95336 100644
--- a/libcxx/test/std/utilities/memory/specialized.algorithms/specialized.destroy/destroy_at.pass.cpp
+++ b/libcxx/test/std/utilities/memory/specialized.algorithms/specialized.destroy/destroy_at.pass.cpp
@@ -34,6 +34,7 @@ struct VirtualCounted {
struct DerivedCounted : VirtualCounted {
TEST_CONSTEXPR DerivedCounted(int* counter) : VirtualCounted(counter) { }
+ TEST_CONSTEXPR_CXX20 ~DerivedCounted() override { }
friend void operator&(DerivedCounted) = delete;
};
More information about the libcxx-commits
mailing list