diff options
| author | kaizhangNV <149626564+kaizhangNV@users.noreply.github.com> | 2025-06-13 11:09:03 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-06-13 09:09:03 -0700 |
| commit | 497033d937792e0008d70dfba3676de06ef9eb15 (patch) | |
| tree | 020488ece48972176a58fc89638f0adee0d5537b | |
| parent | ad6478f1346d3f004d88ce8c7e38479520bb6656 (diff) | |
Fix issue that struct with member is not its Differential type (#7434)
Close #6176.
If the struct has a `no_diff` member, it should not be its Differential
type. We miss this check.
| -rw-r--r-- | source/slang/slang-check-expr.cpp | 8 | ||||
| -rw-r--r-- | tests/autodiff/differential-type-syntheize-diagnostics.slang | 30 |
2 files changed, 35 insertions, 3 deletions
diff --git a/source/slang/slang-check-expr.cpp b/source/slang/slang-check-expr.cpp index 43987132e..9f5c1dc2e 100644 --- a/source/slang/slang-check-expr.cpp +++ b/source/slang/slang-check-expr.cpp @@ -1293,15 +1293,17 @@ Type* SemanticsVisitor::tryGetDifferentialType(ASTBuilder* builder, Type* type) bool SemanticsVisitor::canStructBeUsedAsSelfDifferentialType(AggTypeDecl* aggTypeDecl) { - // A struct can be used as its own differential type if all its members are differentiable - // and their differential types are the same as the original types. + // A struct can be used as its own differential type if all its members are differentiable, and + // none of the member is decorated with "no_diff", and their differential types are the same as + // the original types. // bool canBeUsed = true; for (auto varDecl : aggTypeDecl->getDirectMemberDeclsOfType<VarDecl>()) { // Try to get the differential type of the member. Type* diffType = tryGetDifferentialType(getASTBuilder(), varDecl->getType()); - if (!diffType || !diffType->equals(varDecl->getType())) + if (!diffType || !diffType->equals(varDecl->getType()) || + varDecl->findModifier<NoDiffModifier>()) { canBeUsed = false; break; diff --git a/tests/autodiff/differential-type-syntheize-diagnostics.slang b/tests/autodiff/differential-type-syntheize-diagnostics.slang new file mode 100644 index 000000000..f8663a5a1 --- /dev/null +++ b/tests/autodiff/differential-type-syntheize-diagnostics.slang @@ -0,0 +1,30 @@ +//DIAGNOSTIC_TEST:SIMPLE(filecheck=CHECK): + +struct PartlyDiffable : IDifferentiable +{ + no_diff float noDiffMember; + float diffMember; +} + +float func(PartlyDiffable.Differential x) +{ + // CHECK: ([[# @LINE+1]]): error 30027: 'noDiffMember' is not a member of 'PartlyDiffable.Differential'. + return x.noDiffMember; +} + +float func1(PartlyDiffable.Differential x) +{ + // CHECK-NOT: ([[# @LINE+1]]): error 30027: 'diffMember. + return x.diffMember; +} + +RWStructuredBuffer<float> out; + +[shader("compute")] +void compute() +{ + // CHECK: ([[# @LINE+1]]): error 39999: no overload for 'Differential' applicable to arguments of type (float, float) + var diff = PartlyDiffable.Differential(1.0f, 2.0f); + out[0] = func(diff); + out[1] = func1(diff); +} |
