summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2022-11-29 11:44:47 -0800
committerGitHub <noreply@github.com>2022-11-29 11:44:47 -0800
commitd60c925229cf911b0363bf9d5e25a6f73c6d5737 (patch)
tree722cbb05928cb357abcaa5a483ede66fd696195a
parenta54471a1ac25cd40c2eca60d784909e566aff4aa (diff)
Bug fix: partially specialized non-static generic invoke missing `this` argument. (#2536)
* Fix non-static generic func call issue. * Add test case. * Revert unnecessary change. * Update test comment. Co-authored-by: Yong He <yhe@nvidia.com>
-rw-r--r--source/slang/slang-check-expr.cpp8
-rw-r--r--source/slang/slang-check-overload.cpp2
-rw-r--r--tests/bugs/generic-member-method.slang52
-rw-r--r--tests/bugs/generic-member-method.slang.expected.txt4
4 files changed, 65 insertions, 1 deletions
diff --git a/source/slang/slang-check-expr.cpp b/source/slang/slang-check-expr.cpp
index 2c6899269..1f0e1a2dc 100644
--- a/source/slang/slang-check-expr.cpp
+++ b/source/slang/slang-check-expr.cpp
@@ -1054,6 +1054,14 @@ namespace Slang
{
return overloadedExpr2->base;
}
+ else if (auto genApp = as<GenericAppExpr>(expr))
+ {
+ return GetBaseExpr(genApp->functionExpr);
+ }
+ else if (auto partiallyApplied = as<PartiallyAppliedGenericExpr>(expr))
+ {
+ return GetBaseExpr(partiallyApplied->originalExpr);
+ }
return nullptr;
}
diff --git a/source/slang/slang-check-overload.cpp b/source/slang/slang-check-overload.cpp
index 3867dda03..911587fd5 100644
--- a/source/slang/slang-check-overload.cpp
+++ b/source/slang/slang-check-overload.cpp
@@ -729,7 +729,7 @@ namespace Slang
{
auto expr = m_astBuilder->create<PartiallyAppliedGenericExpr>();
expr->loc = context.loc;
- expr->originalExpr = originalAppExpr;
+ expr->originalExpr = baseExpr;
expr->baseGenericDeclRef = as<DeclRefExpr>(baseExpr)->declRef.as<GenericDecl>();
expr->substWithKnownGenericArgs = (GenericSubstitution*)candidate.subst;
return expr;
diff --git a/tests/bugs/generic-member-method.slang b/tests/bugs/generic-member-method.slang
new file mode 100644
index 000000000..06e80cd0c
--- /dev/null
+++ b/tests/bugs/generic-member-method.slang
@@ -0,0 +1,52 @@
+// Test calling a generic member method with partially specified generic arguments.
+
+//TEST(compute):COMPARE_COMPUTE_EX:-slang -compute -shaderobj
+//TEST(compute,vulkan):COMPARE_COMPUTE_EX:-vk -slang -compute -shaderobj
+
+//TEST_INPUT:ubuffer(data=[0 0 0 0], stride=4):out,name outputBuffer
+RWStructuredBuffer<int> outputBuffer;
+
+interface INothing
+{
+ int getVal();
+}
+
+struct Nothing : INothing
+{
+ int getVal() { return 0; }
+}
+
+interface IImpl
+{
+ int computeAdd<TNothing : INothing, TNothing2 : INothing>(TNothing nothingArg, TNothing2 nothing, int otherVal);
+}
+
+struct Impl : IImpl
+{
+ int thisVal;
+ __init()
+ {
+ thisVal = 1;
+ }
+ // Introduce two generic parameters so we can construct a partially specialized invoke.
+ int computeAdd<TNothing : INothing, TNothing2 : INothing>(TNothing nothingArg, TNothing2 nothing, int otherVal)
+ {
+ return thisVal + otherVal + nothingArg.getVal();
+ }
+ int doThing(int otherVal)
+ {
+ Nothing nothing;
+ // Partially specialize the invoke.
+ // This will result in construction of `PartiallySpecializedInvokeExpr`.
+ // We need to make sure the baseExpr is persisted during this step.
+ return computeAdd<Nothing>(nothing, nothing, otherVal);
+ }
+}
+
+[numthreads(1, 1, 1)]
+void computeMain(int3 dispatchThreadID: SV_DispatchThreadID)
+{
+ Impl impl;
+ Nothing nothing;
+ outputBuffer[0] = impl.doThing(2);
+} \ No newline at end of file
diff --git a/tests/bugs/generic-member-method.slang.expected.txt b/tests/bugs/generic-member-method.slang.expected.txt
new file mode 100644
index 000000000..8a673e262
--- /dev/null
+++ b/tests/bugs/generic-member-method.slang.expected.txt
@@ -0,0 +1,4 @@
+3
+0
+0
+0