summaryrefslogtreecommitdiffstats
path: root/libcxx/include/functional
diff options
context:
space:
mode:
authorVolodymyr Sapsai <vsapsai@apple.com>2018-04-25 23:38:41 +0000
committerVolodymyr Sapsai <vsapsai@apple.com>2018-04-25 23:38:41 +0000
commitaa208791bb950bd56f85eb200c7ac08df89b5efb (patch)
tree4aaa51fba1398c820d0c4d788a2bae4d390254db /libcxx/include/functional
parent2c6430fe3c2005a60680b72a52bfb4e81ca841ee (diff)
downloadbcm5719-llvm-aa208791bb950bd56f85eb200c7ac08df89b5efb.tar.gz
bcm5719-llvm-aa208791bb950bd56f85eb200c7ac08df89b5efb.zip
[libcxx] func.wrap.func.con: Unset function before destroying anything
Be defensive against a reentrant std::function::operator=(nullptr_t), in case the held function object has a non-trivial destructor. Destroying the function object in-place can lead to the destructor being called twice. Patch by Duncan P. N. Exon Smith. C++03 support by Volodymyr Sapsai. rdar://problem/32836603 Reviewers: EricWF, mclow.lists Reviewed By: mclow.lists Subscribers: cfe-commits, arphaman Differential Revision: https://reviews.llvm.org/D34331 llvm-svn: 330885
Diffstat (limited to 'libcxx/include/functional')
-rw-r--r--libcxx/include/functional15
1 files changed, 6 insertions, 9 deletions
diff --git a/libcxx/include/functional b/libcxx/include/functional
index e45beb81801..bb0bdf151a0 100644
--- a/libcxx/include/functional
+++ b/libcxx/include/functional
@@ -1818,11 +1818,7 @@ template<class _Rp, class ..._ArgTypes>
function<_Rp(_ArgTypes...)>&
function<_Rp(_ArgTypes...)>::operator=(function&& __f) _NOEXCEPT
{
- if ((void *)__f_ == &__buf_)
- __f_->destroy();
- else if (__f_)
- __f_->destroy_deallocate();
- __f_ = 0;
+ *this = nullptr;
if (__f.__f_ == 0)
__f_ = 0;
else if ((void *)__f.__f_ == &__f.__buf_)
@@ -1842,11 +1838,12 @@ template<class _Rp, class ..._ArgTypes>
function<_Rp(_ArgTypes...)>&
function<_Rp(_ArgTypes...)>::operator=(nullptr_t) _NOEXCEPT
{
- if ((void *)__f_ == &__buf_)
- __f_->destroy();
- else if (__f_)
- __f_->destroy_deallocate();
+ __base* __t = __f_;
__f_ = 0;
+ if ((void *)__t == &__buf_)
+ __t->destroy();
+ else if (__t)
+ __t->destroy_deallocate();
return *this;
}
OpenPOWER on IntegriCloud