forked from OSchip/llvm-project
[libc++] Use std::addressof in std::function::target
This guards against hostile overloads of operator&. Thanks to Peter Dimov for the report in https://github.com/boostorg/lambda/issues/24. Differential Revision: https://reviews.llvm.org/D116380
This commit is contained in:
parent
0b09313cd5
commit
e24ddb6027
|
@ -16,6 +16,7 @@
|
|||
#include <__functional/invoke.h>
|
||||
#include <__functional/unary_function.h>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__memory/addressof.h>
|
||||
#include <__memory/allocator_traits.h>
|
||||
#include <__memory/compressed_pair.h>
|
||||
#include <__memory/shared_ptr.h>
|
||||
|
@ -360,7 +361,7 @@ const void*
|
|||
__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::target(const type_info& __ti) const _NOEXCEPT
|
||||
{
|
||||
if (__ti == typeid(_Fp))
|
||||
return &__f_.__target();
|
||||
return _VSTD::addressof(__f_.__target());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -1392,7 +1393,7 @@ const void*
|
|||
__func<_Fp, _Alloc, _Rp()>::target(const type_info& __ti) const
|
||||
{
|
||||
if (__ti == typeid(_Fp))
|
||||
return &__f_.first();
|
||||
return _VSTD::addressof(__f_.first());
|
||||
return (const void*)0;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// <functional>
|
||||
|
||||
// class function<R(ArgTypes...)>
|
||||
|
||||
// This test runs in C++03, but we have deprecated using std::function in C++03.
|
||||
// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS
|
||||
|
||||
// Make sure we can use std::function with a type that has a hostile overload
|
||||
// of operator&().
|
||||
|
||||
#include <functional>
|
||||
#include <cassert>
|
||||
|
||||
#include "operator_hijacker.h"
|
||||
|
||||
struct TrapAddressof : operator_hijacker {
|
||||
int operator()() const { return 1; }
|
||||
};
|
||||
|
||||
int main(int, char**) {
|
||||
std::function<int()> f = TrapAddressof();
|
||||
assert(f() == 1);
|
||||
return 0;
|
||||
}
|
|
@ -27,8 +27,14 @@
|
|||
|
||||
struct Incomplete;
|
||||
template<class T> struct Holder { T t; };
|
||||
|
||||
typedef Holder<Incomplete> *Ptr;
|
||||
|
||||
template<class T>
|
||||
struct Callable {
|
||||
void operator()() const { }
|
||||
};
|
||||
|
||||
Ptr no_args() { return nullptr; }
|
||||
Ptr one_arg(Ptr p) { return p; }
|
||||
Ptr two_args(Ptr p, Ptr) { return p; }
|
||||
|
@ -37,11 +43,11 @@ Ptr four_args(Ptr p, Ptr, Ptr, Ptr) { return p; }
|
|||
|
||||
void one_arg_void(Ptr) { }
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
int main(int, char**) {
|
||||
Ptr x = nullptr;
|
||||
std::function<Ptr()> f(no_args); f();
|
||||
std::function<Ptr(Ptr)> g(one_arg); g(x);
|
||||
std::function<void(Ptr)> h(one_arg_void); h(x);
|
||||
std::function<void()> i(Callable<Holder<Incomplete>>{});
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue