Skip to content

64ビット整数のリテラルと定数を無効な型として断つ - #248

Merged
routersys merged 5 commits into
mainfrom
dev/ComputeWeave.SixtyFourBitConstants
Sep 15, 2026
Merged

routersys merged 5 commits into
mainfrom
dev/ComputeWeave.SixtyFourBitConstants

Conversation

@routersys

@routersys routersys commented Sep 15, 2026 •

Copy link
Copy Markdown
Owner

Summary / 概要

64ビット整数のリテラルと定数を、型集合の外の型として断ちます。long と ulong のリテラルは接尾辞のまま、定数は桁だけで生成 HLSL へ出ており、同梱のシェーダーコンパイラはそれを32ビットの値として読んでいました。負のリテラルを左辺に置いた符号なしとの比較は符号なしで解かれ、32ビットを越える値は切り詰められ、生成器の診断もシェーダーコンパイラの誤りも出ません。被演算子の広がりを断つ CMPW0125 は左辺の変換だけを読むので、変換を伴わないリテラルと定数を左辺に置いた形は素通りしていました。

判定は型で行います。リテラルの型が型集合の外にあるとき、また定数の値を HLSL のリテラルとして書き出せないとき、その型を発見された型として追跡します。long の局所変数と明示的な変換が既に CMPW0050 で断られているのと同じ経路なので、新しい診断は足していません。定数を定義へ書き出す3箇所は1つの補助メソッドへ集め、書き出せない値をその失敗の経路で断ちます。文字列の定数はこれまで識別子のまま残され、シェーダーコンパイラが生成物の行を名指して落ちていましたが、同じ経路で断られるようになります。

Linked issue / 関連する課題

Closes #242

Kind / 種別

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

Behavior change / 挙動の変更

64ビット整数のリテラルか定数、または文字列の定数を持つシェーダーは、ビルドが止まるようになります。既定の重大度はエラーです。次の表は、土台の main(887d5851)とこの枝で計算側の生成器を直に動かして測ったものです。式のうちリテラルと定数以外の値は定数バッファから読んでいます。

書いた式 変更前 変更後
5L < this.unsigned 診断なし CMPW0050
(float)(5UL + this.unsigned) 診断なし CMPW0050
シェーダー自身の const long を名前で読む 診断なし CMPW0050
別の型の const long をメンバーアクセスで読む 診断なし CMPW0050
静的フィールドの初期化子の中の const long 診断なし CMPW0050
const long に単項の負号を付ける 診断なし CMPW0050
long.MaxValue 診断なし CMPW0050
条件演算子の腕に置いた const long 診断なし CMPW0050
const string どうしの比較 CMPW0046 CMPW0050
const string と文字列リテラルの比較 CMPW0036 CMPW0036 と CMPW0050
(float)1.5m CMPW0046 CMPW0050
右辺に置いた 5L と const long CMPW0125 CMPW0125 と CMPW0050
(long)this.signed を左辺に置いた演算 CMPW0125 と CMPW0050 変わらない
long の局所変数 CMPW0050 変わらない
const int、const uint、const short、const byte、const decimal、int のリテラル、int.MaxValue 診断なし 変わらない

Direct2D の生成器では同じ経路が CMPWD2D0041 を報告します。リテラルと定数を1つずつ試験にしてあります。

このリポジトリのシェーダーにはこの形が1つもありません。土台と ca8735fc で11のプロジェクトをビルドし直し、生成器が書くファイルを突き合わせました。

突き合わせ 件数
両方に在って同じ 1078
両方に在って違う 2
片方にしか無い 0

違う2件は ShaderWithOverriddenOptions と ShaderWithOverriddenProfileAndOptions で、同じコミットを2回ビルドしても動く DXBC の検査値です。

公開 API は変わりません。触れたのは共有の書き換え器の internal な型だけで、記述子と README は動いていません。

Verification / 検証

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

9本をビルド済みの dll から走らせました。判定は失敗した試験の名前で行い、失敗は0件です。生成器の2スイートは cd6b8ab6 で、他の7本は文字列の定数の試験を書き直す前の ca8735fc で走らせています。その後の2コミットは広がりの報告の注記の1文と台帳の引用で、生成器の符号は変わりません。枝の最後のコミット bf32530e の CI は4本とも通っています。

スイート 合計 失敗 省略
ComputeWeave.Tests 4189 0 52
ComputeWeave.Tests.SourceGenerators 567 0 0
ComputeWeave.Tests.Internals 1085 0 0
ComputeWeave.Tests.DeviceLost 43 0 0
ComputeWeave.D2D1.Tests 204 0 1
ComputeWeave.D2D1.Tests.SourceGenerators 234 0 0
ComputeWeave.D2D1.Tests.AssemblyLevelAttributes 4 0 0
ComputeWeave.Tests.DebugLayer 14 0 0

ComputeWeave.Tests.GlobalStatements は終了状態0です。土台側の値は 2026-09-13 に ab003f50 で測った記録で、そこから 887d5851 までの13コミットは src と tests を触っていません。生成器の2本は 557 と 232 で、増えた10件と2件が足した回帰試験です。他の7本は同じ値です。

ComputeWeave.Tests は1度目に Transition_ReadWriteTexture3D の2変種が 75 MB の確保の E_OUTOFMEMORY で落ちました。並列のビルドで機械のメモリが尽きていたときの回で、所要も 352 秒と長く、同じ dll を単独で走らせ直した2度目が上の値です。

変異

実装をコミットしてから3通りに壊し、足した試験だけを両方の生成器で回しました。対照は変異なしで失敗0件です。

壊した箇所 計算で落ちた試験 Direct2D で落ちた試験
定数の値の判定から long と ulong を外す 定数の3行(名前、メンバーアクセス、初期化子) 定数の1行
リテラルの型を追跡しなくする リテラルの2行 リテラルの1行
補助メソッドの失敗の経路で型を追跡しなくする 定数の3行と文字列の1行 定数の1行

断たない側の4行はどの変異でも落ちません。断ちすぎる向きの変異は行っていません。判定は型集合の有無をそのまま読んでおり、逆へ倒すと型集合の中の型を持つリテラル全部が断たれ、既存の試験が軒並み落ちるためです。

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

なぜ型の追跡で断つのか

書き出す側が知らない型を、書き出す側で見分ける形にしました。long の局所変数と明示的な変換は、型を追跡する既存の経路が CMPW0050 で断っています。リテラルと定数は型の追跡を通らないので、その2箇所だけが型集合の外の型を持ち込めていました。追跡へ載せると、局所変数、変換、リテラル、定数のどれから入っても同じ判定に届きます。

CMPW0125 の判定を右辺へ広げる形は退けました。その報告は被演算子の変換を読むもので、リテラルと定数は変換を持ちません。左辺に置かれた 5L と const long を捉えるには変換ではなく型を読む判定が要り、それを演算の側に置くと、演算の中に現れない long の定数を取り落とします。問題を所有しているのは型の側です。

新しい診断は足しませんでした。long の局所変数を書いた著者が今日受け取るのと同じ報告を、リテラルと定数を書いた著者も受け取ります。識別子を計算側と Direct2D 側に1つずつ増やすと README の6箇所と解析器のリリース記録の2箇所が動き、既存の報告と意味が重なります。

文字列の定数は同じ補助メソッドの失敗の経路に入るので、そのまま断つ形にしました。TryGetConstantLiteral が偽を返す値は、どの型であれ HLSL の定義へ書き出せないので、分ける理由がありません。

decimal の定数は触っていません。浮動小数点の綴りへ書き出す既存の扱いが在り、その値は C# と同じです。decimal のリテラルは型集合の外なので追跡へ載りますが、(float)1.5m の形はこれまでもシェーダーコンパイラが落としており、届く診断が生成物の行から著者の型へ移るだけです。

(long) の明示的な変換を伴う演算は、これまでどおり CMPW0050 と CMPW0125 の両方を受けます。1つの原因に2つの報告が並ぶ形ですが、この変更が新しく作ったものではなく、変換の側の既存の形です。

測っていないこと

Direct2D 側で FXC が L の接尾辞をどう読むかは確かめていません。ulong は DXC の DXIL までで、装置では読んでいません。Direct2D 側の文字列の定数は試していません。利用者のシェーダーにこの形がどれだけ在るかは分かりません。

走らせていないスイート

ComputeWeave.Tests.NativeLibrariesResolver だけ走らせていません。出荷経路のワークフローが回すもので、この変更が触れるファイルを取り込みません。

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 / 査読者への注記

コミットは5つです。断りを足すもの、試験を足すもの、台帳の行を足すもの、広がりの報告の注記へ左辺のリテラルと定数の扱いを足すもの、台帳の行にそのコミットを引くものの順です。

3箇所にあった定数の書き出しの4行を1つの補助メソッドへ集めたのは、書き出せない値の扱いを3箇所へ書かないためです。集めた補助メソッドの成功の経路は元の4行と同じ文で、生成物は変わりません。

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

PR #243 の枝とは HlslSourceRewriter.cs の VisitIdentifierName で衝突します。PR #243 は定数の条件を1つの if へ戻して初期化子の環の報告を歩きへ置き換え、この PR は同じ if の中で補助メソッドを呼ぶためです。解決は、その if の最後の条件を TryGetConstantLiteral の呼び出しから TryRewriteConstantReference(operation.Field, out IdentifierNameSyntax? constantName) へ替え、本体を return constantName; の1行にする形です。PR #243 の最後のコミットへこの枝を併合してそのように解いた木で、生成器の2スイートは 587 件と 236 件で失敗0件、警告0で建ちました。先に入った方の後に、残った方が main を取り込んで同じ形に解きます。

@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

github-actions Bot commented Sep 15, 2026 •

Copy link
Copy Markdown

PRレビュー / PR review

変更 7 ファイル、コミット 5 件。 / 7 files, 5 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.Diagnostics.cs
    • src/ComputeWeave.SourceGeneration.Hlsl/SyntaxRewriters/HlslSourceRewriter.cs
    • src/ComputeWeave.SourceGeneration.Hlsl/SyntaxRewriters/ShaderSourceRewriter.cs
    • src/ComputeWeave.SourceGeneration.Hlsl/SyntaxRewriters/StaticFieldRewriter.cs
  • 記述子と診断 / descriptors and diagnostics
    • src/ComputeWeave.SourceGeneration.Hlsl/SyntaxRewriters/HlslSourceRewriter.Diagnostics.cs

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

公開APIまたは生成される記述子を変えた場合は、該当部分の互換性、生成の決定性、基準データの検査を走らせてください。
For public API or generated descriptor changes, run the compatibility, deterministic-generation or golden-data checks of the affected subsystem.

確認できた点 / 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.

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] long のリテラルか定数を左辺に置いた演算が、CMPW0125 で断たれず 32 ビットで計算される

1 participant