[libcxx-commits] [libcxx] b271b44 - [libc++] Guard call_once against operator hijacking. (#128054)
via libcxx-commits
libcxx-commits at lists.llvm.org
Tue Mar 18 10:06:28 PDT 2025
Author: Mark de Wever
Date: 2025-03-18T18:06:24+01:00
New Revision: b271b44158804256a982fe8b2c5edbdba3a0bf15
URL: https://github.com/llvm/llvm-project/commit/b271b44158804256a982fe8b2c5edbdba3a0bf15
DIFF: https://github.com/llvm/llvm-project/commit/b271b44158804256a982fe8b2c5edbdba3a0bf15.diff
LOG: [libc++] Guard call_once against operator hijacking. (#128054)
Added:
Modified:
libcxx/include/__mutex/once_flag.h
libcxx/test/std/thread/thread.mutex/thread.once/thread.once.callonce/call_once.pass.cpp
libcxx/test/support/operator_hijacker.h
Removed:
################################################################################
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 <class _Callable>
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 <class _Callable>
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<const _Callable> __p(__func);
- std::__call_once(__flag.__state_, &__p, &__call_once_proxy<const _Callable>);
+ std::__call_once(__flag.__state_, std::addressof(__p), std::addressof(__call_once_proxy<const _Callable>));
}
}
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
+
// <mutex>
// 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 <typename T>
friend void operator&(T&&) = delete;
More information about the libcxx-commits
mailing list