From 673f0c40d1aee257e09f8fef87b6ae3a31103470 Mon Sep 17 00:00:00 2001 From: Eric Niebler Date: Mon, 23 Feb 2026 09:17:09 -0800 Subject: [PATCH 1/3] add some c++23 jobs to the CI job matrix --- .github/workflows/ci.cpu.yml | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/.github/workflows/ci.cpu.yml b/.github/workflows/ci.cpu.yml index 919df2a27..b796eb809 100644 --- a/.github/workflows/ci.cpu.yml +++ b/.github/workflows/ci.cpu.yml @@ -19,15 +19,17 @@ jobs: fail-fast: false matrix: include: - - { name: "CPU (clang 16, Debug)", build: "Debug", tag: llvm16-cuda12.9, cxxflags: "-stdlib=libc++" } - - { name: "CPU (clang 16, Release)", build: "Release", tag: llvm16-cuda12.9, cxxflags: "-stdlib=libc++" } - - { name: "CPU (clang 16, Release, ASAN)", build: "Release", tag: llvm16-cuda12.9, cxxflags: "-stdlib=libc++ -fsanitize=address -fsanitize-ignorelist=/home/coder/stdexec/sanitizer-ignorelist.txt" } - - { name: "CPU (gcc 11, Debug)", build: "Debug", tag: gcc11-cuda12.9, cxxflags: "", } - - { name: "CPU (gcc 11, Release)", build: "Release", tag: gcc11-cuda12.9, cxxflags: "", } - - { name: "CPU (gcc 11, Release, ASAN)", build: "Release", tag: gcc11-cuda12.9, cxxflags: "-fsanitize=address" } - - { name: "CPU (gcc 12, Release, TSAN)", build: "Release", tag: gcc12-cuda12.9, cxxflags: "-fsanitize=thread" } - - { name: "CPU (gcc 13, Debug)", build: "Release", tag: gcc13-cuda12.9, cxxflags: "", } - - { name: "CPU (gcc 14, Release, LEAK)", build: "Release", tag: gcc14-cuda12.9, cxxflags: "-fsanitize=leak", } + - { name: "CPU (clang 16, Debug)", build: "Debug", tag: llvm16-cuda12.9, cxxstd: "20", cxxflags: "-stdlib=libc++" } + - { name: "CPU (clang 16, Debug, c++23)", build: "Debug", tag: llvm16-cuda12.9, cxxstd: "23", cxxflags: "-stdlib=libc++" } + - { name: "CPU (clang 16, Release)", build: "Release", tag: llvm16-cuda12.9, cxxstd: "20", cxxflags: "-stdlib=libc++" } + - { name: "CPU (clang 16, Release, ASAN)", build: "Release", tag: llvm16-cuda12.9, cxxstd: "20", cxxflags: "-stdlib=libc++ -fsanitize=address -fsanitize-ignorelist=/home/coder/stdexec/sanitizer-ignorelist.txt" } + - { name: "CPU (gcc 11, Debug)", build: "Debug", tag: gcc11-cuda12.9, cxxstd: "20", cxxflags: "", } + - { name: "CPU (gcc 11, Release)", build: "Release", tag: gcc11-cuda12.9, cxxstd: "20", cxxflags: "", } + - { name: "CPU (gcc 11, Release, ASAN)", build: "Release", tag: gcc11-cuda12.9, cxxstd: "20", cxxflags: "-fsanitize=address" } + - { name: "CPU (gcc 12, Release, TSAN)", build: "Release", tag: gcc12-cuda12.9, cxxstd: "20", cxxflags: "-fsanitize=thread" } + - { name: "CPU (gcc 13, Debug)", build: "Release", tag: gcc13-cuda12.9, cxxstd: "20", cxxflags: "", } + - { name: "CPU (gcc 14, Release, LEAK)", build: "Release", tag: gcc14-cuda12.9, cxxstd: "20", cxxflags: "-fsanitize=leak", } + - { name: "CPU (gcc 14, Release, c++23)", build: "Release", tag: gcc14-cuda12.9, cxxstd: "23", cxxflags: "", } container: options: -u root image: rapidsai/devcontainers:26.02-cpp-${{ matrix.tag }} @@ -100,6 +102,8 @@ jobs: -DSTDEXEC_ENABLE_TBB:BOOL=${{ !contains(matrix.cxxflags, '-fsanitize') }} \ -DSTDEXEC_ENABLE_ASIO:BOOL=TRUE \ -DSTDEXEC_ASIO_IMPLEMENTATION:STRING=boost \ + -DCMAKE_CXX_STANDARD=${{ matrix.cxxstd }} \ + -DCMAKE_CXX_EXTENSIONS=OFF \ ; # Compile From a1e946d3b5e6c16ed8d9e5e782a3e5d5ebb1ed2d Mon Sep 17 00:00:00 2001 From: Eric Niebler Date: Mon, 23 Feb 2026 09:43:35 -0800 Subject: [PATCH 2/3] fix some c++23 issues with clang --- include/exec/linux/io_uring_context.hpp | 11 +++++++---- include/stdexec/__detail/__any.hpp | 8 ++++++-- include/stdexec/__detail/__config.hpp | 2 +- include/stdexec/__detail/__utility.hpp | 7 +++++++ 4 files changed, 21 insertions(+), 7 deletions(-) diff --git a/include/exec/linux/io_uring_context.hpp b/include/exec/linux/io_uring_context.hpp index ed026f5b1..4a514d002 100644 --- a/include/exec/linux/io_uring_context.hpp +++ b/include/exec/linux/io_uring_context.hpp @@ -22,6 +22,7 @@ # include # include "../../stdexec/__detail/__atomic.hpp" +# include "../../stdexec/__detail/__utility.hpp" # include "../../stdexec/execution.hpp" # include "../timed_scheduler.hpp" @@ -1109,7 +1110,9 @@ namespace experimental::execution auto secs = std::chrono::duration_cast(dur); dur -= secs; secs = (std::max) (secs, std::chrono::seconds{0}); - dur = std::clamp(dur, std::chrono::nanoseconds{0}, std::chrono::nanoseconds{999'999'999}); + dur = STDEXEC::__clamp(dur, + std::chrono::nanoseconds{0}, + std::chrono::nanoseconds{999'999'999}); return __kernel_timespec{secs.count(), dur.count()}; } # else @@ -1125,9 +1128,9 @@ namespace experimental::execution __nsec = std::chrono::nanoseconds{__timerspec.it_value.tv_nsec} + __nsec; auto __sec = std::chrono::duration_cast(__nsec); __nsec -= __sec; - __nsec = std::clamp(__nsec, - std::chrono::nanoseconds{0}, - std::chrono::nanoseconds{999'999'999}); + __nsec = STDEXEC::__clamp(__nsec, + std::chrono::nanoseconds{0}, + std::chrono::nanoseconds{999'999'999}); __timerspec.it_value.tv_sec += __sec.count(); __timerspec.it_value.tv_nsec = __nsec.count(); STDEXEC_ASSERT(0 <= __timerspec.it_value.tv_nsec diff --git a/include/stdexec/__detail/__any.hpp b/include/stdexec/__detail/__any.hpp index 2475a45cd..0ffe8f3ae 100644 --- a/include/stdexec/__detail/__any.hpp +++ b/include/stdexec/__detail/__any.hpp @@ -32,6 +32,9 @@ #include #include +STDEXEC_PRAGMA_PUSH() +STDEXEC_PRAGMA_IGNORE_GNU("-Wredundant-consteval-if") + namespace STDEXEC::__any { @@ -1698,10 +1701,9 @@ namespace STDEXEC::__any if (__empty(__other)) { return; - // NOLINTNEXTLINE(bugprone-branch-clone) } else if constexpr (_Other::__root_kind == __root_kind::__reference || !__ptr_convertible) - { + { // NOLINT(bugprone-branch-clone) return __other.__slice_to_(*this); } else if (__other.__in_situ_()) @@ -2012,3 +2014,5 @@ namespace STDEXEC::__any }; } // namespace STDEXEC::__any + +STDEXEC_PRAGMA_POP() diff --git a/include/stdexec/__detail/__config.hpp b/include/stdexec/__detail/__config.hpp index f9de2c918..10be7bb89 100644 --- a/include/stdexec/__detail/__config.hpp +++ b/include/stdexec/__detail/__config.hpp @@ -612,7 +612,7 @@ namespace STDEXEC #define STDEXEC_ASSERT(_XP) \ do { \ - static_assert(noexcept(_XP)); \ + /*static_assert(noexcept(_XP));*/ \ STDEXEC_ASSERT_FN(_XP); \ } while (false) diff --git a/include/stdexec/__detail/__utility.hpp b/include/stdexec/__detail/__utility.hpp index 7fd06d5f8..5fb902963 100644 --- a/include/stdexec/__detail/__utility.hpp +++ b/include/stdexec/__detail/__utility.hpp @@ -196,6 +196,13 @@ namespace STDEXEC return static_cast<__copy_cvref_t<_Ty&&, STDEXEC_REMOVE_REFERENCE(_Uy)>>(__uy); } + template + constexpr _Ty const & __clamp(_Ty const & v, _Ty const & lo, _Ty const & hi) + { + STDEXEC_ASSERT(!(hi < lo)); + return v < lo ? lo : hi < v ? hi : v; // NOLINT(bugprone-return-const-ref-from-parameter) + } + STDEXEC_PRAGMA_PUSH() STDEXEC_PRAGMA_IGNORE_GNU("-Wold-style-cast") From b9995a331b2c97e1ec54c68839348d58239ed82a Mon Sep 17 00:00:00 2001 From: Eric Niebler Date: Mon, 23 Feb 2026 09:56:30 -0800 Subject: [PATCH 3/3] fix unused variable warnings --- include/exec/async_scope.hpp | 8 +++++--- include/stdexec/__detail/__task.hpp | 3 ++- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/include/exec/async_scope.hpp b/include/exec/async_scope.hpp index 2e3a4f47b..e8873b6a0 100644 --- a/include/exec/async_scope.hpp +++ b/include/exec/async_scope.hpp @@ -498,6 +498,7 @@ namespace experimental::execution ~__future_state_base() { + [[maybe_unused]] std::unique_lock __guard{__mutex_}; if (__step_ == __future_step::__created) { @@ -511,11 +512,12 @@ namespace experimental::execution } } - constexpr void __step_from_to_(std::unique_lock& __guard, - __future_step __from, - __future_step __to) + constexpr void __step_from_to_([[maybe_unused]] std::unique_lock& __guard, + [[maybe_unused]] __future_step __from, + __future_step __to) { STDEXEC_ASSERT(__guard.owns_lock()); + [[maybe_unused]] auto actual = std::exchange(__step_, __to); STDEXEC_ASSERT(actual == __from); } diff --git a/include/stdexec/__detail/__task.hpp b/include/stdexec/__detail/__task.hpp index f0a7b3f00..138bdf7e7 100644 --- a/include/stdexec/__detail/__task.hpp +++ b/include/stdexec/__detail/__task.hpp @@ -103,7 +103,8 @@ namespace STDEXEC // promise object. We now use that allocator to deallocate the entire block of // memory: size_t const __promise_blocks = __task::__divmod(__bytes, sizeof(__memblock)); - void* const __alloc_loc = static_cast<__memblock*>(__ptr) + __promise_blocks; + [[maybe_unused]] + void* const __alloc_loc = static_cast<__memblock*>(__ptr) + __promise_blocks; // the number of blocks needed to store an object of type __palloc_t: static constexpr size_t __alloc_blocks = __task::__divmod(sizeof(__task::__any_alloc<_PAlloc>), sizeof(__task::__memblock));