summaryrefslogtreecommitdiffstats
path: root/source/slang
diff options
context:
space:
mode:
authorkaizhangNV <149626564+kaizhangNV@users.noreply.github.com>2025-10-02 15:23:53 -0700
committerGitHub <noreply@github.com>2025-10-02 15:23:53 -0700
commitbffac95febd7a29cfac0becfcb019cd057b53765 (patch)
tree946c6d525c82f900af9fe2985d1d38bc53f70c8a /source/slang
parentfa16aa3e93cdbca2301eceb6e47d23036315002f (diff)
Fix the missing derivative member check (#8569)
Close #8568. The root cause of this issue is that when the struct is indirectly inherited from IDifferentiable type, we will not check the reference of the DerivativeMember attribute. This PR fixes this issue by checking the DerivativeMember attribute right before synthesize the requirement methods of IDifferentiable interface.
Diffstat (limited to 'source/slang')
-rw-r--r--source/slang/slang-ast-modifier.h2
-rw-r--r--source/slang/slang-check-decl.cpp22
2 files changed, 13 insertions, 11 deletions
diff --git a/source/slang/slang-ast-modifier.h b/source/slang/slang-ast-modifier.h
index 89f7a70bb..5793167af 100644
--- a/source/slang/slang-ast-modifier.h
+++ b/source/slang/slang-ast-modifier.h
@@ -1689,7 +1689,7 @@ FIDDLE()
class DerivativeMemberAttribute : public Attribute
{
FIDDLE(...)
- FIDDLE() DeclRefExpr* memberDeclRef;
+ FIDDLE() DeclRefExpr* memberDeclRef = nullptr;
};
/// An attribute that marks an interface type as a COM interface declaration.
diff --git a/source/slang/slang-check-decl.cpp b/source/slang/slang-check-decl.cpp
index 6f2b01aa1..2afd05df2 100644
--- a/source/slang/slang-check-decl.cpp
+++ b/source/slang/slang-check-decl.cpp
@@ -7193,6 +7193,18 @@ bool SemanticsVisitor::trySynthesizeDifferentialMethodRequirementWitness(
if (!diffMemberType)
continue;
+ // Since the conformance checking happens before the decl body checking, the
+ // DerivativeMemberAttribute might not have been checked yet. So we need to make sure
+ // they are checked before we use them. `checkDerivativeMemberAttributeReferences`
+ // already handles the case that the attribute has already been checked.
+ checkDerivativeMemberAttributeReferences(varMember, derivativeAttr);
+
+ // If there is anything wrong in the checking, `checkDerivativeMemberAttributeReferences`
+ // will diagnose an error, and `derivativeAttr->memberDeclRef` will be null. We will skip
+ // the remaining synthesis to avoid crash.
+ if (!derivativeAttr->memberDeclRef)
+ continue;
+
// Pull up the derivative member name from the attribute
auto derivMemberName = derivativeAttr->memberDeclRef->declRef.getName();
@@ -8145,16 +8157,6 @@ void SemanticsVisitor::checkAggTypeConformance(AggTypeDecl* decl)
auto inheritanceDecls = decl->getMembersOfType<InheritanceDecl>().toList();
for (auto inheritanceDecl : inheritanceDecls)
{
- // Special handling for when we check for conformance against `IDifferentiable`
- // We will reference-checking for the [DerivativeMember(DiffType.member)]
- // attributes here, since they have to be performed after types can be referenced
- // and before conformance checking, where this information can be used to synthesize
- // member methods (such as `dzero`, `dadd`, etc..)
- //
- if (inheritanceDecl->getSup().type->equals(
- astBuilder->getDifferentiableInterfaceType()))
- checkDifferentiableMembersInType(decl);
-
checkConformance(type, inheritanceDecl, decl);
}