https://gcc.gnu.org/g:89552346e3cef8ef32e2ebe643bb96d085447e68
commit r16-5642-g89552346e3cef8ef32e2ebe643bb96d085447e68 Author: Jonathan Wakely <[email protected]> Date: Wed Nov 26 14:44:03 2025 +0000 libstdc++: Fix std::counting_semaphore<> default max value My recent (uncommitted) changes to support a 64-bit __platform_wait_t for FreeBSD and Darwin revealed a problem in std::counting_semaphore. When the default template argument is used and __platform_wait_t is a 64-bit type, the numeric_limits<__platform_wait_t>::max() value doesn't fit in ptrdiff_t and so we get ptrdiff_t(-1), which fails a static_assert in the class body. The solution is to cap the value to PTRDIFF_MAX instead of allowing it to go negative. libstdc++-v3/ChangeLog: * include/bits/semaphore_base.h (__platform_semaphore::_S_max): Limit to PTRDIFF_MAX to avoid negative values. * testsuite/30_threads/semaphore/least_max_value.cc: New test. Reviewed-by: Tomasz KamiĆski <[email protected]> Diff: --- libstdc++-v3/include/bits/semaphore_base.h | 14 ++++++++++++-- .../testsuite/30_threads/semaphore/least_max_value.cc | 9 +++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/libstdc++-v3/include/bits/semaphore_base.h b/libstdc++-v3/include/bits/semaphore_base.h index 82871ce3518b..cb815d340aca 100644 --- a/libstdc++-v3/include/bits/semaphore_base.h +++ b/libstdc++-v3/include/bits/semaphore_base.h @@ -173,8 +173,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { using __count_type = __detail::__platform_wait_t; - static constexpr ptrdiff_t _S_max - = _Binary ? 1 : __gnu_cxx::__int_traits<__count_type>::__max; + static consteval ptrdiff_t + _S_calc_max() + { + if (_Binary) + return 1; + else if ((ptrdiff_t)__gnu_cxx::__int_traits<__count_type>::__max < 0) + return __gnu_cxx::__int_traits<ptrdiff_t>::__max; + else + return __gnu_cxx::__int_traits<__count_type>::__max; + } + + static constexpr ptrdiff_t _S_max = _S_calc_max(); constexpr explicit __platform_semaphore_impl(__count_type __count) noexcept diff --git a/libstdc++-v3/testsuite/30_threads/semaphore/least_max_value.cc b/libstdc++-v3/testsuite/30_threads/semaphore/least_max_value.cc new file mode 100644 index 000000000000..67fa1258b7f0 --- /dev/null +++ b/libstdc++-v3/testsuite/30_threads/semaphore/least_max_value.cc @@ -0,0 +1,9 @@ +// { dg-do compile { target c++20 } } +// { dg-require-effective-target gthreads { target { ! *-*-linux* } } } +// { dg-require-effective-target hosted } + +#include <semaphore> + +std::counting_semaphore<> sem(0); +std::counting_semaphore<> sem2(2); +std::counting_semaphore sem3(3);
