https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83658
Bug ID: 83658
Summary: any::emplace deletes invalid memory when an overloaded
operator new() throws
Product: gcc
Version: 8.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: libstdc++
Assignee: unassigned at gcc dot gnu.org
Reporter: cohenjon at google dot com
Target Milestone: ---
Note the following Wandbox: https://wandbox.org/permlink/1emVGP0a09lmd4g2 --
the std::any is still empty after new() throws and so the destructor should be
a no-op. Instead it calls delete().
__do_emplace sets the manager pointer before attempting to create a new object.
When new() throws after calling reset(), _M_ptr doesn't point to valid memory.
When, later, the destructor is called on the any, the manager pointer still is
non-null, so the destructor, via reset(), will trigger the call to
_S_manage(_Op_destroy, ...), calling delete on the invalid _M_ptr.
I believe setting the manager pointer after calling _S_create() will fix the
issue, since the manager pointer will still be null after _S_create_ propagates
the exception.