Skip to content

fix(__any_allocator): add friend declaration so the cross-specialization converting constructor compiles - #2159

Open
deretame wants to merge 2 commits into
NVIDIA:mainfrom
deretame:fix/any-allocator-msvc-friend
Open

fix(__any_allocator): add friend declaration so the cross-specialization converting constructor compiles#2159
deretame wants to merge 2 commits into
NVIDIA:mainfrom
deretame:fix/any-allocator-msvc-friend

Conversation

@deretame

@deretame deretame commented Aug 8, 2026

Copy link
Copy Markdown

Summary

stdexec::task_scheduler fails to compile when its type-erased backend takes the heap-allocation fallback path: __any_allocator<std::byte> has a converting constructor that 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) — verified with MSVC cl 19.51.36252, clang-cl 22.1.8 and GCC 13.3.

The constructor is only instantiated on the heap-allocation fallback path (operation state larger than task_scheduler's inline storage), which the upstream test matrix never exercises — e.g. stdexec::task on an asio-based scheduler (asio::post + use_sender). So the build breaks on every compiler, not just MSVC. See #2158 for the full analysis and repro.

Fix

Add an explicit friend declaration to __any_allocator (makes the cross-specialization access legal on every compiler):

template <class>
friend struct __any_allocator;

Test

Add test/stdexec/detail/test_any_allocator.cpp, which instantiates the cross-specialization converting constructor directly. The test fails on every compiler without the friend declaration (verified: MSVC C2248, Clang private-member error, GCC private-within-this-context), so it guards the fix on all platforms.

Verified locally on MSVC cl 19.51.36252:

without friend with friend
__any_allocator<int>__any_allocator<std::byte> conversion ❌ C2248 ✅ compiles
test.stdexec full build + run (*any_allocator*) ✅ 1 test case passed

clang-cl 22.1.8 also rejects the conversion without the friend declaration and compiles with it.

Fixes #2158

…ion converting constructor compiles on MSVC

__any_allocator's converting constructor reads the private member of another
specialization of the same class template, which the standard permits
([class.access], since C++17) but MSVC rejects with C2248. The conversion 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), so stdexec::task + asio + MSVC currently fails to compile.

Add an explicit friend declaration (harmless on GCC/Clang) and a regression
test that instantiates the converting constructor directly.

Fixes NVIDIA#2158
@copy-pr-bot

copy-pr-bot Bot commented Aug 8, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

…cted by GCC, Clang and MSVC alike

The converting constructor of __any_allocator reads the private member of
another specialization of the same template. That is rejected by all major
compilers (MSVC C2248; Clang/GCC 'private member' error); upstream never
noticed because the constructor is only instantiated on the heap-allocation
fallback path of task_scheduler (large operation states, e.g. asio-based
schedulers), which the upstream test matrix does not exercise. The friend
declaration makes the conversion legal on every compiler.
@deretame deretame changed the title fix(__any_allocator): make the cross-specialization converting constructor compile on MSVC fix(__any_allocator): add friend declaration so the cross-specialization converting constructor compiles Aug 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

task_scheduler fails to compile: __any_allocator cross-specialization converting constructor accesses a private member

1 participant