Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions include/stdexec/__detail/__any_allocator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,12 @@ namespace STDEXEC

__any_allocator() = default;

// The converting constructor below accesses the private member of another
// specialization of this template, which is rejected by MSVC, Clang and
// GCC. Declare the friendship explicitly.
template <class>
friend struct __any_allocator;

template <__not_same_as<__any_allocator> _Alloc>
requires __is_not_instance_of<_Alloc, __any_allocator> && __simple_allocator<_Alloc>
__any_allocator(_Alloc __alloc) noexcept
Expand Down
1 change: 1 addition & 0 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ set(stdexec_test_sources
stdexec/algos/consumers/test_sync_wait.cpp
stdexec/algos/consumers/test_spawn.cpp
stdexec/detail/test_any.cpp
stdexec/detail/test_any_allocator.cpp
stdexec/detail/test_common_domain.cpp
stdexec/detail/test_completion_signatures.cpp
stdexec/detail/test_demangle.cpp
Expand Down
40 changes: 40 additions & 0 deletions test/stdexec/detail/test_any_allocator.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*
* Licensed under the Apache License, Version 2.0 with LLVM Exceptions (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://llvm.org/LICENSE.txt
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include <stdexec/execution.hpp>

#include <test_common/catch2.hpp>

#include <utility>

// The converting constructor __any_allocator(_Uy) reads the private member of
// another specialization of the same class template. That access is rejected by
// all major compilers (MSVC C2248, Clang and GCC report it as accessing a
// private member), so the constructor only compiles because it is never
// instantiated in the upstream test matrix. It *is* instantiated whenever
// task_scheduler's type-erased backend copies an allocator on the
// heap-allocation fallback path (e.g. with an asio-based scheduler), breaking
// the build on every compiler; the friend declaration makes the conversion
// legal. This test instantiates the constructor directly and guards the fix
// for NVIDIA/stdexec#2158.
TEST_CASE("__any_allocator cross-specialization converting constructor compiles",
"[detail][allocator]")
{
STDEXEC::__any_allocator<int> src;
STDEXEC::__any_allocator<std::byte> dst(std::move(src)); // instantiates the converting ctor
CHECK(dst.has_value() == false);
}
Loading