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/invoke.h>
|
||||||
#include <__functional/unary_function.h>
|
#include <__functional/unary_function.h>
|
||||||
#include <__iterator/iterator_traits.h>
|
#include <__iterator/iterator_traits.h>
|
||||||
|
#include <__memory/addressof.h>
|
||||||
#include <__memory/allocator_traits.h>
|
#include <__memory/allocator_traits.h>
|
||||||
#include <__memory/compressed_pair.h>
|
#include <__memory/compressed_pair.h>
|
||||||
#include <__memory/shared_ptr.h>
|
#include <__memory/shared_ptr.h>
|
||||||
|
@ -360,7 +361,7 @@ const void*
|
||||||
__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::target(const type_info& __ti) const _NOEXCEPT
|
__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::target(const type_info& __ti) const _NOEXCEPT
|
||||||
{
|
{
|
||||||
if (__ti == typeid(_Fp))
|
if (__ti == typeid(_Fp))
|
||||||
return &__f_.__target();
|
return _VSTD::addressof(__f_.__target());
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1392,7 +1393,7 @@ const void*
|
||||||
__func<_Fp, _Alloc, _Rp()>::target(const type_info& __ti) const
|
__func<_Fp, _Alloc, _Rp()>::target(const type_info& __ti) const
|
||||||
{
|
{
|
||||||
if (__ti == typeid(_Fp))
|
if (__ti == typeid(_Fp))
|
||||||
return &__f_.first();
|
return _VSTD::addressof(__f_.first());
|
||||||
return (const void*)0;
|
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;
|
struct Incomplete;
|
||||||
template<class T> struct Holder { T t; };
|
template<class T> struct Holder { T t; };
|
||||||
|
|
||||||
typedef Holder<Incomplete> *Ptr;
|
typedef Holder<Incomplete> *Ptr;
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
struct Callable {
|
||||||
|
void operator()() const { }
|
||||||
|
};
|
||||||
|
|
||||||
Ptr no_args() { return nullptr; }
|
Ptr no_args() { return nullptr; }
|
||||||
Ptr one_arg(Ptr p) { return p; }
|
Ptr one_arg(Ptr p) { return p; }
|
||||||
Ptr two_args(Ptr p, Ptr) { 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) { }
|
void one_arg_void(Ptr) { }
|
||||||
|
|
||||||
int main(int, char**)
|
int main(int, char**) {
|
||||||
{
|
|
||||||
Ptr x = nullptr;
|
Ptr x = nullptr;
|
||||||
std::function<Ptr()> f(no_args); f();
|
std::function<Ptr()> f(no_args); f();
|
||||||
std::function<Ptr(Ptr)> g(one_arg); g(x);
|
std::function<Ptr(Ptr)> g(one_arg); g(x);
|
||||||
std::function<void(Ptr)> h(one_arg_void); h(x);
|
std::function<void(Ptr)> h(one_arg_void); h(x);
|
||||||
|
std::function<void()> i(Callable<Holder<Incomplete>>{});
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue