Skip to content

fix: narrow the symmetric-transfer workaround to MSVC < 19.50, exclud… - #427

Open
mvandeberg wants to merge 1 commit into
cppalliance:developfrom
mvandeberg:fix/msvc-symmetric-transfer-gate
Open

mvandeberg wants to merge 1 commit into
cppalliance:developfrom
mvandeberg:fix/msvc-symmetric-transfer-gate

Conversation

@mvandeberg

Copy link
Copy Markdown
Contributor

…e Clang

detail::symmetric_transfer substituted h.resume() on the current stack for any compiler defining _MSC_VER, trading O(1) tail-calls for O(n) stack growth. That over-matched on two axes.

MSVC 19.34 through 19.44 place await_suspend's hidden return slot on the coroutine frame, at __coro_frame_ptr$ + 0xC0, so an await_suspend that destroys its own frame and then transfers leaves the write and read-back of the returned handle pointing at freed memory. MSVC 19.50 makes that slot an rsp-relative stack temporary which outlives the frame, so the workaround no longer applies.

clang-cl and clang++ targeting Windows define _MSC_VER for ABI compatibility but emit a correct tail-call, so they never needed the workaround. A version-only gate would not exclude them, since Clang continues to emulate a sub-1950 _MSC_VER.

The gate becomes:

BOOST_CAPY_WORKAROUND(_MSC_VER, < 1950) && !defined(__clang__)

Adds a regression test for the shape when_all_runner and when_any_runner use in final_suspend: destroy the frame inside await_suspend, then transfer through symmetric_transfer. Frames are allocated with VirtualAlloc/mmap and unmapped on destroy so that any post-destroy access faults. A poisoning allocator cannot detect this case, because routing the return through symmetric_transfer moves the compiler's write into the frame slot to after destroy, which repairs the poison and hides the defect.

Adds MSVC 14.51 (VS 2026) to the CI matrix on windows-2025-vs2026, which is the only configuration that exercises the newly enabled tail-call path. It builds with Ninja because the CMake that cmake-workflow selects on that image predates the Visual Studio 18 2026 generator. is_latest moves from 14.44 to 14.51, taking the MSVC CMake and ASan variants with it; Visual Studio generator coverage remains on 14.34.

Includes detail/config.hpp explicitly rather than relying on it arriving through ex/io_env.hpp.

Refs #378

…e Clang

detail::symmetric_transfer substituted h.resume() on the current stack
for any compiler defining _MSC_VER, trading O(1) tail-calls for O(n)
stack growth. That over-matched on two axes.

MSVC 19.34 through 19.44 place await_suspend's hidden return slot on
the coroutine frame, at __coro_frame_ptr$ + 0xC0, so an await_suspend
that destroys its own frame and then transfers leaves the write and
read-back of the returned handle pointing at freed memory. MSVC 19.50
makes that slot an rsp-relative stack temporary which outlives the
frame, so the workaround no longer applies.

clang-cl and clang++ targeting Windows define _MSC_VER for ABI
compatibility but emit a correct tail-call, so they never needed the
workaround. A version-only gate would not exclude them, since Clang
continues to emulate a sub-1950 _MSC_VER.

The gate becomes:

    BOOST_CAPY_WORKAROUND(_MSC_VER, < 1950) && !defined(__clang__)

Adds a regression test for the shape when_all_runner and
when_any_runner use in final_suspend: destroy the frame inside
await_suspend, then transfer through symmetric_transfer. Frames are
allocated with VirtualAlloc/mmap and unmapped on destroy so that any
post-destroy access faults. A poisoning allocator cannot detect this
case, because routing the return through symmetric_transfer moves the
compiler's write into the frame slot to after destroy, which repairs
the poison and hides the defect.

Adds MSVC 14.51 (VS 2026) to the CI matrix on windows-2025-vs2026,
which is the only configuration that exercises the newly enabled
tail-call path. It builds with Ninja because the CMake that
cmake-workflow selects on that image predates the Visual Studio 18
2026 generator. is_latest moves from 14.44 to 14.51, taking the MSVC
CMake and ASan variants with it; Visual Studio generator coverage
remains on 14.34.

Includes detail/config.hpp explicitly rather than relying on it
arriving through ex/io_env.hpp.

Refs cppalliance#378
@cppalliance-bot

Copy link
Copy Markdown

An automated preview of the documentation is available at https://427.capy.prtest3.cppalliance.org/index.html

If more commits are pushed to the pull request, the docs will rebuild at the same URL.

2026-09-22 17:09:48 UTC

@cppalliance-bot

Copy link
Copy Markdown

GCOVR code coverage report https://427.capy.prtest3.cppalliance.org/gcovr/index.html
LCOV code coverage report https://427.capy.prtest3.cppalliance.org/genhtml/index.html
Coverage Diff Report https://427.capy.prtest3.cppalliance.org/diff-report/index.html

Build time: 2026-09-22 17:16:17 UTC

@codecov

codecov Bot commented Sep 22, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 98.09%. Comparing base (ca59f94) to head (2ba099a).

Additional details and impacted files

Impacted file tree graph

@@           Coverage Diff            @@
##           develop     #427   +/-   ##
========================================
  Coverage    98.09%   98.09%           
========================================
  Files          130      130           
  Lines         6289     6289           
========================================
  Hits          6169     6169           
  Misses         120      120           
Flag Coverage Δ
linux 98.08% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
include/boost/capy/detail/await_suspend_helper.hpp 100.00% <ø> (ø)

... and 1 file with indirect coverage changes


Continue to review full report in Codecov by Harness.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update ca59f94...2ba099a. Read the comment docs.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Backlog

Development

Successfully merging this pull request may close these issues.

2 participants