diff options
author | Eric Fiselier <eric@efcs.ca> | 2019-03-09 00:38:19 +0000 |
---|---|---|
committer | Eric Fiselier <eric@efcs.ca> | 2019-03-09 00:38:19 +0000 |
commit | 7ffcd984c4de54dea96049b9cb6a74c9e9b84c1e (patch) | |
tree | f005738dd727154282520d1443c442c3a62f7ca1 /libcxx/src/experimental | |
parent | c5bfa3dafb3e7ccc871734a96b7a9188868d925a (diff) | |
download | bcm5719-llvm-7ffcd984c4de54dea96049b9cb6a74c9e9b84c1e.tar.gz bcm5719-llvm-7ffcd984c4de54dea96049b9cb6a74c9e9b84c1e.zip |
LWG 2843 "Unclear behavior of std::pmr::memory_resource::do_allocate()"
Patch by Arthur O'Dwyer.
Reviewed as https://reviews.llvm.org/D47344
new_delete_resource().allocate(n, a) has basically two permissible results:
* Return an appropriately sized and aligned block.
* Throw bad_alloc.
Before this patch, libc++'s new_delete_resource would do a third and impermissible thing, which was
to return an appropriately sized but inappropriately under-aligned block. This is now fixed.
(This came up while I was stress-testing unsynchronized_pool_resource on my MacBook. If we can't
trust the default resource to return appropriately aligned blocks, pretty much everything breaks.
For similar reasons, I would strongly support just patching __libcpp_allocate directly, but I don't
care to die on that hill, so I made this patch as a <memory_resource>-specific workaround.)
llvm-svn: 355763
Diffstat (limited to 'libcxx/src/experimental')
-rw-r--r-- | libcxx/src/experimental/memory_resource.cpp | 24 |
1 files changed, 14 insertions, 10 deletions
diff --git a/libcxx/src/experimental/memory_resource.cpp b/libcxx/src/experimental/memory_resource.cpp index 977ee2b56ee..22bc12c1005 100644 --- a/libcxx/src/experimental/memory_resource.cpp +++ b/libcxx/src/experimental/memory_resource.cpp @@ -25,19 +25,23 @@ _LIBCPP_BEGIN_NAMESPACE_LFTS_PMR 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 size, size_t align) override { +#ifdef _LIBCPP_HAS_NO_ALIGNED_ALLOCATION + if (__is_overaligned_for_new(align)) + __throw_bad_alloc(); +#endif + return _VSTD::__libcpp_allocate(size, align); + } - virtual void do_deallocate(void* __p, size_t __n, size_t __align) { - _VSTD::__libcpp_deallocate(__p, __n, __align); /* FIXME */ + void do_deallocate(void *p, size_t n, size_t align) override { + _VSTD::__libcpp_deallocate(p, n, align); } - virtual bool do_is_equal(memory_resource const & __other) const _NOEXCEPT - { return &__other == this; } + bool do_is_equal(memory_resource const & other) const _NOEXCEPT override + { return &other == this; } + +public: + ~__new_delete_memory_resource_imp() override = default; }; // null_memory_resource() |