---
generated: true
model: claude-sonnet-4-6
generated_at: 2026-06-02T10:01:20+00:00
source_commit: 57fb63455095efe1465661001ad147b24b968932
watched_paths_digest: 9b1c120ce0d9f89af6b4fb7ff5937edda019eca39c0b99831438b60820b1acb0
source_doc: docs/language-reference/basics-memory-model-special-topics.md
source_doc_digest: f18114811b5683431ac90c437af4aa94d61306d086fa73babe1f4c6c2ea781ed
warning: "Auto-generated. May drift from source. Do not edit by hand."
---

# Tests for conformance/basics-memory-model-special-topics

## Intent

Tests verify the normative claims in the **language reference** at
[`docs/language-reference/basics-memory-model-special-topics.md`](../../../../language-reference/basics-memory-model-special-topics.md).
The doc covers two topics: (1) how `in`/`out`/`inout` parameter directions govern
access semantics during a function call, and (2) how binding the same underlying memory
to multiple resource handles creates aliases that can produce data races.

Coverage strategy is **emission-first**: HLSL and SPIRV tests pin the compiler's
observable behaviour for parameter passing (HLSL: `inout` keyword on signatures;
SPIRV: Function-pointer passing for `out`/`inout`) and the aliased-resource binding
shapes. The one normative "is UB" claim with a compiler-observable signal — passing
the same variable to two `out`/`inout` parameters — is verified via a DIAGNOSTIC_TEST
that pins diagnostic W30051. Pure runtime data-race semantics (C6, C9, C10) have no
emission-observable signal and are recorded in `## Untested claims`.

## Claims

### Section 1: Function Parameters with in/out/inout Modifiers

- **C1**: `in` is the default parameter direction.
- **C2**: The function may read the argument passed to the `in`-parameter any number of times during the function call.
- **C3**: The function may write the argument passed to the `out`-parameter any number of times during the function call.
- **C4**: The function may read and write the argument passed to the `inout`-parameter any number of times during the function call.
- **C5**: Even if the function does nothing with the parameter, the argument passed to an `in`/`out`/`inout`-parameter may still be accessed during a function call.
- **C6**: The data race rules apply to arguments passed to functions: if the same variable is passed to an `out`/`inout` parameter in another thread, a data race occurs unless one function call completes before the other.
- **C7**: It is undefined behavior to pass the same variable as an argument to two parameters of a function if at least one parameter is `out`/`inout`.

### Section 2: Memory Aliasing via Binding

- **C8**: If the same underlying memory is bound to multiple resources such as `ConstantBuffer<T>`, `RWStructuredBuffer<T>`, or `Texture2D<T>`, it is aliased.
- **C9**: Aliased memory access is considered overlapping for data race analysis if the accesses to the underlying memory overlap.
- **C10**: A data race can occur even when two concurrent memory accesses use different buffer handles, when one or both accesses modify overlapping underlying memory and the accesses are non-atomic without established happens-before relationships.
- **C11**: The client API may impose additional restrictions on aliased memory.

## Functional coverage

| Claim                                                                                                                                                                                                                                                                                              | Intent     | Anchor                                                                                                                                                                 | Tests                                                                                                                                                        |
| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| C1: `in` is the default direction: a plain parameter and an explicit `in` parameter emit identically (no `inout`/`out` on the HLSL signature).                                                                                                                                                     | functional | [#function-parameters-with-inout-inout-modifiers](../../../../language-reference/basics-memory-model-special-topics.md#function-parameters-with-inout-inout-modifiers) | [`in-default-direction-hlsl-emission.slang`](in-default-direction-hlsl-emission.slang)                                                                       |
| C2: `in` parameter allows any number of reads; HLSL emits the body reading the value-parameter multiple times without restriction.                                                                                                                                                                 | functional | [#function-parameters-with-inout-inout-modifiers](../../../../language-reference/basics-memory-model-special-topics.md#function-parameters-with-inout-inout-modifiers) | [`in-parameter-multiple-reads-hlsl-emission.slang`](in-parameter-multiple-reads-hlsl-emission.slang)                                                         |
| C3: `out` parameter can be written during the function call; SPIRV passes it as a `_ptr_Function_int` pointer so the callee can issue `OpStore` to it.                                                                                                                                             | functional | [#function-parameters-with-inout-inout-modifiers](../../../../language-reference/basics-memory-model-special-topics.md#function-parameters-with-inout-inout-modifiers) | [`out-parameter-spirv-emission.slang`](out-parameter-spirv-emission.slang)                                                                                   |
| C4: `inout` parameter allows multiple reads and writes; SPIRV passes it as a Function-pointer enabling multiple `OpLoad` and `OpStore` in the callee; HLSL preserves `inout` on the signature.                                                                                                     | functional | [#function-parameters-with-inout-inout-modifiers](../../../../language-reference/basics-memory-model-special-topics.md#function-parameters-with-inout-inout-modifiers) | [`inout-parameter-spirv-emission.slang`](inout-parameter-spirv-emission.slang), [`inout-parameter-hlsl-emission.slang`](inout-parameter-hlsl-emission.slang) |
| C7 (inout+inout): Passing the same variable to two `inout` parameters elicits W30051 "potentially aliased argument to 'out'/'inout'/'ref' parameter".                                                                                                                                              | negative   | [#function-parameters-with-inout-inout-modifiers](../../../../language-reference/basics-memory-model-special-topics.md#function-parameters-with-inout-inout-modifiers) | [`alias-inout-warning-diagnostic.slang`](alias-inout-warning-diagnostic.slang)                                                                               |
| C7 (in+out): Passing the same variable as both an `in` and an `out` parameter also elicits W30051; the doc condition "at least one is out/inout" covers this case.                                                                                                                                 | negative   | [#function-parameters-with-inout-inout-modifiers](../../../../language-reference/basics-memory-model-special-topics.md#function-parameters-with-inout-inout-modifiers) | [`alias-out-in-warning-diagnostic.slang`](alias-out-in-warning-diagnostic.slang)                                                                             |
| C8 (ConstantBuffer + RWStructuredBuffer): `ConstantBuffer<T>` and `RWStructuredBuffer<T>` are doc-named aliasable resource types; they compile to independent HLSL register declarations.                                                                                                          | functional | [#memory-aliasing-via-binding](../../../../language-reference/basics-memory-model-special-topics.md#memory-aliasing-via-binding)                                       | [`memory-aliasing-resources-hlsl-emission.slang`](memory-aliasing-resources-hlsl-emission.slang)                                                             |
| C8/C10 (two RWStructuredBuffers): Two `RWStructuredBuffer<int>` bindings emit as independent SPIRV StorageBuffer variables each with a distinct `Binding` decoration; the doc states concurrent non-atomic writes through different handles that alias the same underlying memory are a data race. | functional | [#memory-aliasing-via-binding](../../../../language-reference/basics-memory-model-special-topics.md#memory-aliasing-via-binding)                                       | [`memory-aliasing-two-buffers-spirv-emission.slang`](memory-aliasing-two-buffers-spirv-emission.slang)                                                       |

## Untested claims

| Claim                                                                                                                                                       | Reason         | Anchor                                                                                                                                                                 | Why untested                                                                                                                                                                                                                                          |
| ----------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| C5: Even if the function does nothing with the parameter, the argument may still be accessed during the call.                                               | (unclassified) | [#function-parameters-with-inout-inout-modifiers](../../../../language-reference/basics-memory-model-special-topics.md#function-parameters-with-inout-inout-modifiers) | This is a semantic rule about implementation freedom (the implementation may access the argument even when the body doesn't). There is no user-observable emission difference for a no-op body; the claim does not constrain what the compiler emits. |
| C6: If the same variable is passed as an `out`/`inout` argument from two concurrent threads, a data race occurs unless one call completes before the other. | gpu-other      | [#function-parameters-with-inout-inout-modifiers](../../../../language-reference/basics-memory-model-special-topics.md#function-parameters-with-inout-inout-modifiers) | Multi-threaded data race semantics require a GPU compute dispatch with concurrent thread execution; no `slang-test` directive without a GPU runner can demonstrate a race.                                                                            |
| C9: Aliased memory access is considered overlapping for data race analysis if the accesses to the underlying memory overlap.                                | gpu-other      | [#memory-aliasing-via-binding](../../../../language-reference/basics-memory-model-special-topics.md#memory-aliasing-via-binding)                                       | Definitional rule about data race analysis; observable only at runtime via concurrent GPU execution with overlapping accesses.                                                                                                                        |
| C10 (runtime race): A data race can occur even when two concurrent accesses use different buffer handles that alias the same underlying memory.             | gpu-other      | [#memory-aliasing-via-binding](../../../../language-reference/basics-memory-model-special-topics.md#memory-aliasing-via-binding)                                       | Requires a GPU compute dispatch where two threads write to non-atomically overlapping storage via distinct handles; not testable without a GPU runner.                                                                                                |
| C11: The client API may impose additional restrictions on aliased memory.                                                                                   | (unclassified) | [#memory-aliasing-via-binding](../../../../language-reference/basics-memory-model-special-topics.md#memory-aliasing-via-binding)                                       | This refers to client API behavior (Vulkan, D3D12 spec restrictions), not Slang compiler behavior; no slang-test directive can verify client API semantics.                                                                                           |

## Doc gaps observed

| Anchor                                                                                                                                                                 | Kind            | Gap                                                                                                                                                                                                                                                                                                                                                    | Suggested addition                                                                                                                                                                                                                             |
| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [#function-parameters-with-inout-inout-modifiers](../../../../language-reference/basics-memory-model-special-topics.md#function-parameters-with-inout-inout-modifiers) | missing-example | The remark describes two implementation approaches (copy-in/copy-out vs pointer-based) but the example (Example 1) only illustrates the undefined-behavior aliasing case. There is no example showing the read-back behavior of `out`/`inout` parameters after the function returns, which would help readers verify which approach their target uses. | Add a second example showing that after `addConsumeTwoValues(a, b, r)` with distinct variables, `r` holds the correct sum and `a`/`b` are marked `-1`; this concretizes the copy-in/copy-out vs pointer distinction that the remark describes. |
