forked from OSchip/llvm-project
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
This commit is contained in:
parent
c5bfa3dafb
commit
7ffcd984c4
|
@ -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 */}
|
||||
|
||||
virtual void do_deallocate(void* __p, size_t __n, size_t __align) {
|
||||
_VSTD::__libcpp_deallocate(__p, __n, __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 bool do_is_equal(memory_resource const & __other) const _NOEXCEPT
|
||||
{ return &__other == this; }
|
||||
void do_deallocate(void *p, size_t n, size_t align) override {
|
||||
_VSTD::__libcpp_deallocate(p, n, align);
|
||||
}
|
||||
|
||||
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()
|
||||
|
|
|
@ -219,7 +219,7 @@
|
|||
<tr><td><a href="https://wg21.link/LWG2164">2164</a></td><td>What are the semantics of <tt>vector.emplace(vector.begin(), vector.back())</tt>?</td><td>Jacksonville</td><td></td></tr>
|
||||
<tr><td><a href="https://wg21.link/LWG2243">2243</a></td><td><tt>istream::putback</tt> problem</td><td>Jacksonville</td><td>Complete</td></tr>
|
||||
<tr><td><a href="https://wg21.link/LWG2816">2816</a></td><td><tt>resize_file</tt> has impossible postcondition</td><td>Jacksonville</td><td><i>Nothing to do</i></td></tr>
|
||||
<tr><td><a href="https://wg21.link/LWG2843">2843</a></td><td>Unclear behavior of <tt>std::pmr::memory_resource::do_allocate()</tt></td><td>Jacksonville</td><td></td></tr>
|
||||
<tr><td><a href="https://wg21.link/LWG2843">2843</a></td><td>Unclear behavior of <tt>std::pmr::memory_resource::do_allocate()</tt></td><td>Jacksonville</td><td>Complete</td></tr>
|
||||
<tr><td><a href="https://wg21.link/LWG2849">2849</a></td><td>Why does <tt>!is_regular_file(from)</tt> cause <tt>copy_file</tt> to report a "file already exists" error?</td><td>Jacksonville</td><td><i>Nothing to do</i></td></tr>
|
||||
<tr><td><a href="https://wg21.link/LWG2851">2851</a></td><td><tt>std::filesystem</tt> enum classes are now underspecified</td><td>Jacksonville</td><td><i>Nothing to do</i></td></tr>
|
||||
<tr><td><a href="https://wg21.link/LWG2946">2946</a></td><td>LWG 2758's resolution missed further corrections</td><td>Jacksonville</td><td>Complete</td></tr>
|
||||
|
|
Loading…
Reference in New Issue