diff --git a/libcxx/include/__mutex/once_flag.h b/libcxx/include/__mutex/once_flag.h index 08ff54bf99265..2b0ba7781faa4 100644 --- a/libcxx/include/__mutex/once_flag.h +++ b/libcxx/include/__mutex/once_flag.h @@ -11,6 +11,7 @@ #include <__config> #include <__functional/invoke.h> +#include <__memory/addressof.h> #include <__memory/shared_count.h> // __libcpp_acquire_load #include <__tuple/tuple_indices.h> #include <__tuple/tuple_size.h> @@ -128,7 +129,7 @@ inline _LIBCPP_HIDE_FROM_ABI void call_once(once_flag& __flag, _Callable&& __fun typedef tuple<_Callable&&, _Args&&...> _Gp; _Gp __f(std::forward<_Callable>(__func), std::forward<_Args>(__args)...); __call_once_param<_Gp> __p(__f); - std::__call_once(__flag.__state_, &__p, &__call_once_proxy<_Gp>); + std::__call_once(__flag.__state_, std::addressof(__p), std::addressof(__call_once_proxy<_Gp>)); } } @@ -138,7 +139,7 @@ template inline _LIBCPP_HIDE_FROM_ABI void call_once(once_flag& __flag, _Callable& __func) { if (__libcpp_acquire_load(&__flag.__state_) != once_flag::_Complete) { __call_once_param<_Callable> __p(__func); - std::__call_once(__flag.__state_, &__p, &__call_once_proxy<_Callable>); + std::__call_once(__flag.__state_, std::addressof(__p), std::addressof(__call_once_proxy<_Callable>)); } } @@ -146,7 +147,7 @@ template inline _LIBCPP_HIDE_FROM_ABI void call_once(once_flag& __flag, const _Callable& __func) { if (__libcpp_acquire_load(&__flag.__state_) != once_flag::_Complete) { __call_once_param __p(__func); - std::__call_once(__flag.__state_, &__p, &__call_once_proxy); + std::__call_once(__flag.__state_, std::addressof(__p), std::addressof(__call_once_proxy)); } } diff --git a/libcxx/test/std/thread/thread.mutex/thread.once/thread.once.callonce/call_once.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.once/thread.once.callonce/call_once.pass.cpp index 7708efcb54c7f..ea5b63d2804a1 100644 --- a/libcxx/test/std/thread/thread.mutex/thread.once/thread.once.callonce/call_once.pass.cpp +++ b/libcxx/test/std/thread/thread.mutex/thread.once/thread.once.callonce/call_once.pass.cpp @@ -8,6 +8,8 @@ // UNSUPPORTED: no-threads +// XFAIL: FROZEN-CXX03-HEADERS-FIXME + // // struct once_flag; @@ -21,6 +23,7 @@ #include "make_test_thread.h" #include "test_macros.h" +#include "operator_hijacker.h" typedef std::chrono::milliseconds ms; @@ -253,7 +256,19 @@ int main(int, char**) std::call_once(f2, std::move(rq)); assert(rq.rv_called == 1); } + { + std::once_flag flag; + auto f = [](const operator_hijacker&) {}; + std::call_once(flag, f, operator_hijacker{}); + } + #endif // TEST_STD_VER >= 11 - return 0; + { + std::once_flag flag; + operator_hijacker f; + std::call_once(flag, f); + } + + return 0; } diff --git a/libcxx/test/support/operator_hijacker.h b/libcxx/test/support/operator_hijacker.h index fbd8b58ab0f83..07e68a247fc1a 100644 --- a/libcxx/test/support/operator_hijacker.h +++ b/libcxx/test/support/operator_hijacker.h @@ -23,6 +23,7 @@ struct operator_hijacker { TEST_CONSTEXPR bool operator<(const operator_hijacker&) const { return true; } TEST_CONSTEXPR bool operator==(const operator_hijacker&) const { return true; } + TEST_CONSTEXPR int operator()() const { return 42; } template friend void operator&(T&&) = delete;