Skip to content

ネイティブ整数の定数を無効な型として断つ - #253

Merged
routersys merged 3 commits into
mainfrom
dev/ComputeWeave.NativeIntegerConstants
Sep 15, 2026
Merged

routersys merged 3 commits into
mainfrom
dev/ComputeWeave.NativeIntegerConstants

Conversation

@routersys

@routersys routersys commented Sep 15, 2026 •

Copy link
Copy Markdown
Owner

Summary / 概要

nint と nuint の定数を、型集合の外の型として断ちます。PR #248 は long と ulong の定数を、値が64ビットの整数であることで見分けて断ちました。ネイティブ整数の定数は C# が値を32ビットの範囲に限るため32ビットの整数として箱詰めされ、値だけを見る判定は int の定数と見分けられず、桁をそのまま #define へ書き出していました。シェーダーはそれを32ビットで計算し、C# は x64 の工程で64ビットで計算するので、32ビットを越える結果が食い違います。

定数に HLSL のリテラルが在るかを決める関数が、値に加えて定数の型を受け取るようにし、ネイティブ整数の型なら値を見ずにリテラル無しと答えます。定数を定義へ書き出す補助メソッドは、これまでどおりリテラルの無い定数の型を追跡します。報告は局所変数と long の定数と同じ CMPW0050、Direct2D 側は CMPWD2D0041 です。これで定数の型の族は閉じます。bool、char、8ビットと16ビットの整数、int、uint、float、double、decimal は書き出し、long、ulong、nint、nuint、文字列は断ちます。

Linked issue / 関連する課題

Closes #251

Kind / 種別

  • Bug fix / 不具合修正
  • Behavior change with no API change / API変更を伴わない挙動の変更
  • Analyzer or generator / アナライザーまたはジェネレーター

Behavior change / 挙動の変更

nint か nuint の定数を持つシェーダーは、ビルドが止まるようになります。既定の重大度はエラーです。次の表は、土台の main(c050699d)とこの枝で計算側の生成器を直に動かして測ったものです。名前とメンバーアクセスの2行は足した回帰試験が固定しています。

書いた式 変更前 変更後
シェーダー自身の const nint を名前で読む 診断なし CMPW0050
別の型の const nuint をメンバーアクセスで読む 診断なし CMPW0050
静的フィールドの初期化子の中の const nint 診断なし CMPW0050
(float)Own 診断なし CMPW0050
右辺に置いた const nint CMPW0125 CMPW0125 と CMPW0050
nint の局所変数 CMPW0050 変わらない

装置では、const nint Own = 5 と int.MaxValue の和と積、const nuint と uint.MaxValue の和を実機と WARP で読みました。C# の値は 2147483648、10737418240、4294967296、装置の値は -2147483648、2147483648、4 で、装置の3つは32ビットで折り返した整数を単精度へ丸めたものです。

このリポジトリのシェーダーには nint と nuint の定数がありません。const nint と const nuint の宣言は足した試験の雛形の中だけです。変わる経路はその型の定数だけなので、生成物は変わりません。

公開 API は変わりません。

Verification / 検証

dotnet build tests/<suite>/<suite>.csproj -c Release -p:Platform=x64
dotnet tests/<suite>/bin/x64/Release/net10.0/<suite>.dll

生成器の2本を枝の先端 577ee38f でビルドし直して走らせました。判定は失敗した試験の名前で行い、失敗は0件です。

スイート 合計 失敗 省略
ComputeWeave.Tests.SourceGenerators 569 0 0
ComputeWeave.D2D1.Tests.SourceGenerators 235 0 0

土台の値は c050699d の CI と PR #248 の手元の値で、567 と 234 です。増えた2件と1件が足した回帰試験です。他のスイートはこの変更が触れるコードを通らず、CI が回します。

変異

実装をコミットしてから、型の判定を定数の型では決して真にならない述語へ替える変異を当て、足した試験だけを両方の生成器で回しました。判定を外す形は到達しない符号の警告で建たないので、この形にしています。計算側は nint と nuint の2行が落ち、Direct2D 側は nint の1行が落ち、long の行と断たない側の行は落ちません。対照は変異なしで失敗0件です。

Adapter and driver tested / 試したアダプターとドライバー: Intel(R) Iris(R) Xe Graphics, 32.0.101.7085、および WARP

なぜ型で見分けるのか

PR #248 は値の種類で見分けました。64ビットの整数は値がそう箱詰めされるからです。ネイティブ整数の定数は値が int と同じ形で箱詰めされるので、値では見分けられません。C# の定数式が nint を32ビットの範囲に限ることを確かめたうえで、この1つだけは定数の型で見分けます。どの定数にリテラルが在るかの判断を1つの関数に置いたままにするため、その関数へ型を渡す形にし、呼ぶ側に条件を足す形は採りませんでした。判定を型へ全部寄せる形は退けました。8ビットと16ビットの整数の定数は型が集合の外でも C# が演算のたびに int へ広げるので値は同じで、char の定数は int へ、decimal の定数は浮動小数点の綴りへ書き出す既存の扱いがあり、型だけで見ると受け入れている定数まで断ってしまうためです。

測っていないこと

Direct2D 側の装置での値は読んでいません。利用者のシェーダーにこの形がどれだけ在るかは分かりません。

走らせていないスイート

生成器の2本以外は手元で走らせていません。この変更が触れるのは定数のフィールドの型の判定1つで、リポジトリのシェーダーにその型の定数は無く、CI が8本を回します。

Checklist / 確認

  • The pull request is one logical change, with no unrelated refactoring or formatting. / 一つの論理的な変更にまとまっており、無関係な整理や整形を含まない。
  • Every commit builds on its own. / 各コミットが単独でビルドできる。
  • Implementation changes and their verification tests are separate commits. / 実装の変更と検証テストを別のコミットに分けた。
  • No commit already merged into the default branch or referenced by a release tag was rewritten. / 既定ブランチへ入った、またはリリースタグが指すコミットを書き換えていない。
  • The change follows the implementation pattern already established in the subsystem. / 変更は、その部分で既に確立された実装パターンに従っている。
  • Public and protected APIs carry the XML documentation the repository requires. / public と protected のAPIに、リポジトリが求めるXMLドキュメントを付けた。
  • Existing documentation comments were preserved. / 既存のドキュメントコメントを維持した。
  • No silent fallback behavior or compatibility shim was introduced. / 暗黙の代替動作や互換性のための繕いを持ち込んでいない。
  • No unrelated dependency was updated. / 無関係な依存関係を更新していない。
  • If a file inherited from upstream changed, the divergence ledger in CONTRIBUTING.md was updated, or the change was judged not to be a divergence. / 上流から受け継いだファイルを変更した場合、CONTRIBUTING.md の乖離台帳を更新したか、乖離ではないと判断した。

If this touches a guarded area / 慎重を要する箇所に触れる場合

  • Tests exercise the guarded behavior itself, and I confirmed they fail when that behavior is deliberately broken. / 試験が守るべき挙動そのものを動かしており、その挙動を意図的に壊すと落ちることを確認した。
  • For analyzer diagnostics that produce build errors, the complete solution was verified in addition to the analyzer tests. / ビルドエラーを出すアナライザー診断は、アナライザーの試験に加えて解全体を検証した。

Notes for the reviewer / 査読者への注記

コミットは3つです。断りを足すもの、試験を足すもの、台帳の行を足すものの順です。定数のリテラルを決める関数に型の引数と判定を1つ足しただけで、書き出す側の経路は変わっていません。

解全体のビルドは、この機械では資源で落ちるのでプロジェクトを1本ずつビルドしています。11のプロジェクトすべてを枝の先端でビルドし直し、警告0、誤り0でした。

@routersys routersys added bug Something isn't working / 不具合が起きている behavior change Behavior change with no API change / API変更を伴わない挙動の変更 analyzer or generator Analyzer or generator / アナライザーまたはジェネレーター labels Sep 15, 2026
@github-actions

Copy link
Copy Markdown

PRレビュー / PR review

変更 4 ファイル、コミット 3 件。 / 4 files, 3 commits.

検証の要否 / Verification required

以下を走らせ、失敗した試験の名前と失敗の様子を変更前と突き合わせてください。総数だけで判断しないでください。
Run the following and compare the names and failure modes against the same suites before your change. Do not judge by totals alone.

dotnet build ComputeWeave.sln -c Release -p:Platform=x64
dotnet test tests/ComputeWeave.Tests.SourceGenerators/ComputeWeave.Tests.SourceGenerators.csproj -c Release -p:Platform=x64
dotnet test tests/ComputeWeave.Tests.Internals/ComputeWeave.Tests.Internals.csproj -c Release -p:Platform=x64
dotnet test tests/ComputeWeave.Tests/ComputeWeave.Tests.csproj -c Release -p:Platform=x64
dotnet test tests/ComputeWeave.Tests.DeviceLost/ComputeWeave.Tests.DeviceLost.csproj -c Release -p:Platform=x64
dotnet test tests/ComputeWeave.D2D1.Tests.SourceGenerators/ComputeWeave.D2D1.Tests.SourceGenerators.csproj -c Release -p:Platform=x64
dotnet test tests/ComputeWeave.D2D1.Tests/ComputeWeave.D2D1.Tests.csproj -c Release -p:Platform=x64
dotnet test tests/ComputeWeave.D2D1.Tests.AssemblyLevelAttributes/ComputeWeave.D2D1.Tests.AssemblyLevelAttributes.csproj -c Release -p:Platform=x64

ビルドエラーを出す診断を変えた場合は、アナライザーの試験に加えて解全体の検証が要ります。
If a diagnostic that produces build errors changed, verify the complete solution as well.

慎重を要する箇所 / Guarded areas touched

  • 寿命と破棄 / lifetime and disposal
    • src/ComputeWeave.SourceGeneration.Hlsl/SyntaxRewriters/HlslSourceRewriter.cs

寿命の追跡と危険の追跡は別々の保証です。一方を保っても他方が保たれるとは限りません。
Lifetime tracking and hazard tracking are separate guarantees; preserving one does not preserve the other.

確認できた点 / Confirmed

  • 概要が書かれています。 / A summary is present.
  • 検証の結果が書かれています。 / Verification results are present.
  • 関連する課題が示されています。 / A linked issue is referenced.
  • 実装と検証テストが別のコミットに分かれています。 / Implementation and tests are in separate commits.

これは自動の確認で、査読の代わりにはなりません。指摘は判断の材料であって、従う義務はありません。
This is an automated check, not a substitute for review. Findings are input to a decision, not obligations.

@routersys
routersys force-pushed the dev/ComputeWeave.NativeIntegerConstants branch from 0f4db0e to 577ee38 Compare September 15, 2026 11:51
@routersys
routersys merged commit d6b5bab into main Sep 15, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

analyzer or generator Analyzer or generator / アナライザーまたはジェネレーター behavior change Behavior change with no API change / API変更を伴わない挙動の変更 bug Something isn't working / 不具合が起きている

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] nint と nuint の定数を左辺に置いた演算が、診断なく 32 ビットで計算される

1 participant