Quuxplusone updated this revision to Diff 156210.
Quuxplusone edited the summary of this revision.
Quuxplusone added a comment.

Remove some incorrect `noexcept` from `<experimental/memory_resource>`.

I noticed this because the calls to `__clang_call_terminate` showed up on 
Godbolt. But the pessimization is still there even without these `noexcept`! 
Basically the flow is this:

  std::pmr::vector::~vector (noexcept(true))
  - polymorphic_allocator::destroy (noexcept(X) but inlineable)
    - ~T (noexcept(true))
  - polymorphic_allocator::deallocate (noexcept(X) but inlineable)
    - memory_resource::deallocate (noexcept(false) and not inlineable)

where "X" is "true" before this patch and "false" afterward.

Even for `monotonic_buffer_resource`, we can't conclude that deallocation will 
never throw, because deallocation *might* involve the upstream resource, which 
we don't know anything about.


Repository:
  rCXX libc++

https://reviews.llvm.org/D47344

Files:
  include/experimental/memory_resource
  src/experimental/memory_resource.cpp

Index: src/experimental/memory_resource.cpp
===================================================================
--- src/experimental/memory_resource.cpp
+++ src/experimental/memory_resource.cpp
@@ -8,6 +8,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "experimental/memory_resource"
+#include "memory"
 
 #ifndef _LIBCPP_HAS_NO_ATOMIC_HEADER
 #include "atomic"
@@ -23,38 +24,47 @@
 
 // new_delete_resource()
 
+#ifdef _LIBCPP_HAS_NO_ALIGNED_ALLOCATION
+static bool is_aligned_to(void *ptr, size_t align)
+{
+    void *p2 = ptr;
+    size_t space = 1;
+    void *result = _VSTD::align(align, 1, p2, space);
+    return (result == ptr);
+}
+#endif
+
 class _LIBCPP_TYPE_VIS __new_delete_memory_resource_imp
     : public memory_resource
 {
-public:
-    ~__new_delete_memory_resource_imp() = default;
-
-protected:
-    virtual void* do_allocate(size_t __size, size_t __align)
-        { return _VSTD::__libcpp_allocate(__size, __align); /* FIXME */}
+    void *do_allocate(size_t bytes, size_t align) override
+    {
+        void *result = _VSTD::__libcpp_allocate(bytes, align);
+#ifdef _LIBCPP_HAS_NO_ALIGNED_ALLOCATION
+        if (!is_aligned_to(result, align)) {
+            _VSTD::__libcpp_deallocate(result, align);
+            __throw_bad_alloc();
+        }
+#endif
+        return result;
+    }
 
-    virtual void do_deallocate(void * __p, size_t, size_t __align)
-        { _VSTD::__libcpp_deallocate(__p, __align); /* FIXME */ }
+    void do_deallocate(void *p, size_t, size_t align) override
+        { _VSTD::__libcpp_deallocate(p, align); }
 
-    virtual bool do_is_equal(memory_resource const & __other) const _NOEXCEPT
-        { return &__other == this; }
+    bool do_is_equal(const memory_resource& other) const _NOEXCEPT override
+        { return &other == this; }
 };
 
 // null_memory_resource()
 
 class _LIBCPP_TYPE_VIS __null_memory_resource_imp
     : public memory_resource
 {
-public:
-    ~__null_memory_resource_imp() = default;
-
-protected:
-    virtual void* do_allocate(size_t, size_t) {
-        __throw_bad_alloc();
-    }
-    virtual void do_deallocate(void *, size_t, size_t) {}
-    virtual bool do_is_equal(memory_resource const & __other) const _NOEXCEPT
-    { return &__other == this; }
+    void *do_allocate(size_t, size_t) override { __throw_bad_alloc(); }
+    void do_deallocate(void *, size_t, size_t) override {}
+    bool do_is_equal(const memory_resource& other) const _NOEXCEPT override
+        { return &other == this; }
 };
 
 namespace {
Index: include/experimental/memory_resource
===================================================================
--- include/experimental/memory_resource
+++ include/experimental/memory_resource
@@ -195,7 +195,7 @@
     }
 
     _LIBCPP_INLINE_VISIBILITY
-    void deallocate(_ValueType * __p, size_t __n) _NOEXCEPT {
+    void deallocate(_ValueType * __p, size_t __n) {
         _LIBCPP_ASSERT(__n <= __max_size(),
                        "deallocate called for size which exceeds max_size()");
         __res_->deallocate(__p, __n * sizeof(_ValueType), alignof(_ValueType));
@@ -265,7 +265,7 @@
 
     template <class _Tp>
     _LIBCPP_INLINE_VISIBILITY
-    void destroy(_Tp * __p) _NOEXCEPT
+    void destroy(_Tp * __p)
         { __p->~_Tp(); }
 
     _LIBCPP_INLINE_VISIBILITY
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to