diff --git a/libcxx/include/__functional/function.h b/libcxx/include/__functional/function.h --- a/libcxx/include/__functional/function.h +++ b/libcxx/include/__functional/function.h @@ -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 @@ __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 @@ __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; } diff --git a/libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.func/addressof.pass.cpp b/libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.func/addressof.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.func/addressof.pass.cpp @@ -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 +// +//===----------------------------------------------------------------------===// + +// + +// class function + +// 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 +#include + +#include "operator_hijacker.h" + +struct TrapAddressof : operator_hijacker { + int operator()() const { return 1; } +}; + +int main(int, char**) { + std::function f = TrapAddressof(); + assert(f() == 1); + return 0; +} diff --git a/libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.func/robust_against_adl.pass.cpp b/libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.func/robust_against_adl.pass.cpp --- a/libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.func/robust_against_adl.pass.cpp +++ b/libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.func/robust_against_adl.pass.cpp @@ -27,8 +27,14 @@ struct Incomplete; template struct Holder { T t; }; + typedef Holder *Ptr; +template +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 @@ void one_arg_void(Ptr) { } -int main(int, char**) -{ +int main(int, char**) { Ptr x = nullptr; std::function f(no_args); f(); std::function g(one_arg); g(x); std::function h(one_arg_void); h(x); + std::function i(Callable>{}); return 0; }