sync — validation proof

Go’s own sync test suite, converted to C# by go2cs, built against the converted standard library, run under the Go-semantics test host, and compared verdict for verdict against a clean go test -json baseline of the same sources. This page is generated by the converter from that comparison — it is the evidence behind the sync row in Validated Test Packages.

Validated 2026-08-13 · converter 3e440711f

44 matched · 7 disclosed — Go 1.23.1, windows/amd64, converted package src/core/sync.

Verdicts

Test go test go2cs
TestCompareAndSwap_NonExistingKey pass pass
TestConcurrentClear pass pass
TestConcurrentRange pass pass
TestCondBroadcast pass pass
TestCondCopy pass pass
TestCondSignal pass pass
TestCondSignalGenerations pass pass
TestCondSignalStealing pass pass
TestIssue40999 pass pass
TestMapClearNoAllocations pass fail (disclosed)
TestMapMatchesDeepCopy pass pass
TestMapMatchesRWMutex pass pass
TestMapRangeNestedCall pass pass
TestMapRangeNoAllocations pass fail (disclosed)
TestMutex pass pass
TestMutexFairness pass pass
TestMutexMisuse pass pass
TestNilPool pass pass
TestNilPool/Get pass pass
TestNilPool/Put pass pass
TestOnce pass pass
TestOnceFunc pass pass
TestOnceFuncGoexit pass pass
TestOnceFuncPanic pass pass
TestOnceFuncPanicNil pass pass
TestOnceFuncPanicTraceback pass pass
TestOncePanic pass pass
TestOnceValue pass pass
TestOnceValuePanic pass pass
TestOnceValues pass pass
TestOnceValuesPanic pass pass
TestOnceXGC pass fail (disclosed)
TestOnceXGC/OnceFunc pass fail (disclosed)
TestOnceXGC/OnceValue pass fail (disclosed)
TestOnceXGC/OnceValues pass fail (disclosed)
TestParallelReaders pass pass
TestPool pass pass
TestPoolChain pass pass
TestPoolDequeue pass pass
TestPoolGC pass fail (disclosed)
TestPoolNew pass pass
TestPoolRelease pass pass
TestPoolStress pass pass
TestRLocker pass pass
TestRWMutex pass pass
TestRace pass pass
TestSemaphore pass pass
TestWaitGroup pass pass
TestWaitGroupAlign pass pass
TestWaitGroupMisuse pass pass
TestWaitGroupRace pass pass

Disclosed divergences

A disclosed divergence is a specific Go assertion the managed CLR provably cannot satisfy — not a skipped test and not a tolerance. Each one is pinned by exact failure signature in the package’s hand-owned go2cs_test_disclosures.json; a disclosed test that fails any other way is still a hard mismatch.

Test Class Pinned reason
TestMapClearNoAllocations alloc-profile want-zero AllocsPerRun assert: Map.Clear walks the read/dirty maps through the golib map enumerator, and every enumeration step materializes a managed entry object where Go’s bucket walk is allocation-free; a malloc-counting shim would fail the same assert
TestMapRangeNoAllocations alloc-profile want-zero AllocsPerRun assert: Range boxes each key and value into any for the visitor callback — a CLR heap allocation per entry that Go’s non-escaping eface avoids
TestOnceXGC aggregate no failure text of its own — the roll-up of this test’s disclosed subtests
TestOnceXGC/OnceFunc codegen-liveness The test asserts its own frame’s buf is collectible while the frame is still running. sync.OnceFunc DOES drop the wrapped function (measured: the backing array is released after the first call), but the test’s own f := fn(buf) passes the 32-byte slice header BY VALUE, so the x64 ABI makes the caller materialize an address-exposed stack temp; an address-exposed slot is not lifetime-tracked and the CLR reports it live for the whole method, pinning the array until the subtest RETURNS. Go’s per-safepoint liveness maps release the caller’s copy at its last use. Not satisfiable at any layer go2cs owns — it is the CLR’s GC-info conservatism, and it holds in fully optimized code, not just under the non-optimizing JIT.
TestOnceXGC/OnceValue codegen-liveness Same as TestOnceXGC/OnceFunc: the by-value slice argument in the test’s own body is reported live for the whole frame by the CLR’s GC info, so the finalizer cannot become due while the test is looking
TestOnceXGC/OnceValues codegen-liveness Same as TestOnceXGC/OnceFunc: the by-value slice argument in the test’s own body is reported live for the whole frame by the CLR’s GC info, so the finalizer cannot become due while the test is looking
TestPoolGC codegen-liveness Go’s own assert tolerates exactly one straggler (fin1 >= N-1, commented “1 pointer can remain on stack or elsewhere”); the managed run leaves TWO. The extra one is the discarded p.Get() result: Go drops the value immediately, while the CLR keeps the call’s result temp in the test frame’s GC-reported live set for the frame’s whole lifetime — the same frame-liveness conservatism as TestOnceXGC, here one object wide. The Pool itself releases everything it cached (98 of 100 finalize on the FIRST try, deterministically across 9 measured runs); the count is pinned exactly so any real Pool retention regression fails loud instead of hiding behind this disclosure.

Excluded declarations

Declarations filtered from both sides of the comparison, and therefore not claimed above: Benchmark, Fuzz and Example declarations the converted host does not execute, plus any test requiring a capability the managed runtime does not provide — a testing member the host has not implemented, or a platform behavior it provably cannot reproduce. Each is named with the capability it needs.