From 60b66c309075e91824aef69a153e304561ca6041 Mon Sep 17 00:00:00 2001 From: kaizhangNV <149626564+kaizhangNV@users.noreply.github.com> Date: Thu, 12 Jun 2025 14:59:27 -0500 Subject: Fix issue of missing scope for 'Differential' type (#7433) * Fix issue of missing scope for 'Differential' type When we synthesize the struct decl for Differential type, we should add the ownedScope for this decl, because the scope is used in lots of locations in the following synthesized processes, e.g. constructor synthesize. And that could cause surprising behavior, e.g. the 'this' expression could access the members of parent struct decl. Fix the issue by adding the scope. The containerDecl will be the Differential struct decl itself, parent scope will be the parent struct. * Add a unit-test --- source/slang/slang-check-expr.cpp | 3 +++ tests/bugs/gh-6756.slang | 31 +++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 tests/bugs/gh-6756.slang diff --git a/source/slang/slang-check-expr.cpp b/source/slang/slang-check-expr.cpp index a530eb8f0..43987132e 100644 --- a/source/slang/slang-check-expr.cpp +++ b/source/slang/slang-check-expr.cpp @@ -674,6 +674,9 @@ Expr* SemanticsVisitor::maybeUseSynthesizedDeclForLookupResult( conformanceDecl->base.type = m_astBuilder->getDiffInterfaceType(); structDecl->addMember(conformanceDecl); structDecl->parentDecl = parent; + structDecl->ownedScope = m_astBuilder->create(); + structDecl->ownedScope->containerDecl = structDecl; + structDecl->ownedScope->parent = getScope(parent); synthesizedDecl = structDecl; auto typeDef = m_astBuilder->create(); diff --git a/tests/bugs/gh-6756.slang b/tests/bugs/gh-6756.slang new file mode 100644 index 000000000..ab1e5aa98 --- /dev/null +++ b/tests/bugs/gh-6756.slang @@ -0,0 +1,31 @@ +//TEST:SIMPLE(filecheck=CHECK):-target spirv -emit-spirv-via-glsl + +// This test is to test that PartlyDiffable.Differential is synthesized +// with correct scope. If not, the constructor for it will be wrong, and +// slang will generate wrong code, the downstream compiler will fail to +// compile. + +// CHECK: OpEntryPoint Fragment + +struct PartlyDiffable : IDifferentiable +{ + int i; + float q; +} + + +func breaker(x:PartlyDiffable.Differential) { + return; +} + + +[shader("fragment")] +float4 fragment(float4 in: SV_Position) + : SV_Target +{ + if (PartlyDiffable.Differential(0).q == 0) { + return float4(0); + } else { + return float4(1); + } +} -- cgit v1.2.3