Skip to content

[release/9.0-staging] Fix missing release semantics in VolatilePtr#124119

Open
github-actions[bot] wants to merge 1 commit intorelease/9.0-stagingfrom
backport/pr-124070-to-release/9.0-staging
Open

[release/9.0-staging] Fix missing release semantics in VolatilePtr#124119
github-actions[bot] wants to merge 1 commit intorelease/9.0-stagingfrom
backport/pr-124070-to-release/9.0-staging

Conversation

@github-actions
Copy link
Contributor

@github-actions github-actions bot commented Feb 7, 2026

Related issue: #124071
Main PR: 124096

Risk: Low, purely adds a barrier which is the intended semantics of the class.

Testing: manual disassembly inspection verified that affected callsite now have appropriate barriers.

Impact: Detected as a non-deterministic lock free race that resulted in crashes in the Roslyn language server for internal customers. Mostly happens with really complex solutions that have a lot of threads accessing GC Statics.

VolatilePtr inherits from Volatile<P>, which defines operator= to call VolatileStore() with platform scpecific release semantics. However, VolatilePtr did not declare its own operator=, so the compiler-generated copy/move assignment operator hid the base class operator= and performed plain stores instead, bypassing memory barriers entirely.

Fix by adding a using declaration to bring Volatile<P>::operator= into scope, and an explicit copy assignment operator (which the using declaration cannot suppress the compiler from generating).

VolatilePtr inherits from Volatile<P>, which defines operator=(P val)
to call VolatileStore() with release semantics (stlr on ARM64). However,
VolatilePtr did not declare its own operator=, so the compiler-generated
copy/move assignment operator hid the base class operator= and performed
plain stores (str) instead, bypassing the memory barrier entirely.

This affected all VolatilePtr assignments including DeadlockAwareLock's
m_pHoldingThread and Thread's m_pBlockingLock fields, which were being
written without release semantics despite being read with acquire
semantics (ldapr) on the other side.

Fix by adding a using declaration to bring Volatile<P>::operator= into
scope, and an explicit copy assignment operator (which the using
declaration cannot suppress the compiler from generating).
@github-actions github-actions bot added the needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners label Feb 7, 2026
@hoyosjs hoyosjs enabled auto-merge (squash) February 7, 2026 02:45
@teo-tsirpanis teo-tsirpanis added area-VM-coreclr and removed needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners labels Feb 7, 2026
@dotnet-policy-service
Copy link
Contributor

Tagging subscribers to this area: @agocke
See info in area-owners.md if you want to be subscribed.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants