summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkaizhangNV <149626564+kaizhangNV@users.noreply.github.com>2025-06-12 14:59:27 -0500
committerGitHub <noreply@github.com>2025-06-12 12:59:27 -0700
commit60b66c309075e91824aef69a153e304561ca6041 (patch)
tree982f92232cf35a6d282e6dad76a4ff321582c4bc
parent3ffeaf4c7f22bfe95702da76d710362b277e15ac (diff)
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
-rw-r--r--source/slang/slang-check-expr.cpp3
-rw-r--r--tests/bugs/gh-6756.slang31
2 files changed, 34 insertions, 0 deletions
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<Scope>();
+ structDecl->ownedScope->containerDecl = structDecl;
+ structDecl->ownedScope->parent = getScope(parent);
synthesizedDecl = structDecl;
auto typeDef = m_astBuilder->create<TypeAliasDecl>();
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);
+ }
+}