[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