summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkaizhangNV <149626564+kaizhangNV@users.noreply.github.com>2025-06-13 11:09:03 -0500
committerGitHub <noreply@github.com>2025-06-13 09:09:03 -0700
commit497033d937792e0008d70dfba3676de06ef9eb15 (patch)
tree020488ece48972176a58fc89638f0adee0d5537b
parentad6478f1346d3f004d88ce8c7e38479520bb6656 (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.cpp8
-rw-r--r--tests/autodiff/differential-type-syntheize-diagnostics.slang30
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);
+}