[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 git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@330885 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// <functional>
|
||||
|
||||
// class function<R(ArgTypes...)>
|
||||
|
||||
// function& operator=(function &&);
|
||||
|
||||
#include <functional>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
|
||||
struct A
|
||||
{
|
||||
static std::function<void()> global;
|
||||
static bool cancel;
|
||||
|
||||
~A() {
|
||||
DoNotOptimize(cancel);
|
||||
if (cancel)
|
||||
global = std::function<void()>(nullptr);
|
||||
}
|
||||
void operator()() {}
|
||||
};
|
||||
|
||||
std::function<void()> A::global;
|
||||
bool A::cancel = false;
|
||||
|
||||
int main()
|
||||
{
|
||||
A::global = A();
|
||||
assert(A::global.target<A>());
|
||||
|
||||
// Check that we don't recurse in A::~A().
|
||||
A::cancel = true;
|
||||
A::global = std::function<void()>(nullptr);
|
||||
assert(!A::global.target<A>());
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// <functional>
|
||||
|
||||
// class function<R(ArgTypes...)>
|
||||
|
||||
// function& operator=(nullptr_t);
|
||||
|
||||
#include <functional>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
|
||||
struct A
|
||||
{
|
||||
static std::function<void()> global;
|
||||
static bool cancel;
|
||||
|
||||
~A() {
|
||||
DoNotOptimize(cancel);
|
||||
if (cancel)
|
||||
global = nullptr;
|
||||
}
|
||||
void operator()() {}
|
||||
};
|
||||
|
||||
std::function<void()> A::global;
|
||||
bool A::cancel = false;
|
||||
|
||||
int main()
|
||||
{
|
||||
A::global = A();
|
||||
assert(A::global.target<A>());
|
||||
|
||||
// Check that we don't recurse in A::~A().
|
||||
A::cancel = true;
|
||||
A::global = nullptr;
|
||||
assert(!A::global.target<A>());
|
||||
}
|
||||
Reference in New Issue
Block a user