diff options
| author | Tim Foley <tfoleyNV@users.noreply.github.com> | 2020-12-02 14:12:51 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-12-02 14:12:51 -0800 |
| commit | ad5dda9261bae63e32bcb914b109fcb5c92faf25 (patch) | |
| tree | 97ffa786c6fc03586c112745a12f6373dde252d1 | |
| parent | ae222bf4fa131b8b86dd0662b32214eb161ace1a (diff) | |
Fix [mutating] generic methods (#1618)
Slang generates code that turns the implicit `this` parameter of a method into an explicit parameter. The logic that decides whether that parameter should be `inout` is a bit involved, and there was a bug where a generic method would lead to the use of an `in` modifier (the default) and override the `inout` modifier that was requested by the method itself.
This change fixes the logic to treat generic declarations in the parent chain of a leaf method as having no bearing on whether an implicit `this` parameter should be `inout` or not.
A test case is included that breaks with the old behavior, and demonstrates that a generic `[mutating]` method can now work correctly.
| -rw-r--r-- | source/slang/slang-lower-to-ir.cpp | 8 | ||||
| -rw-r--r-- | tests/bugs/mutating/mutating-generic-method.slang | 50 | ||||
| -rw-r--r-- | tests/bugs/mutating/mutating-generic-method.slang.expected.txt | 4 |
3 files changed, 62 insertions, 0 deletions
diff --git a/source/slang/slang-lower-to-ir.cpp b/source/slang/slang-lower-to-ir.cpp index fefec805c..b2a7529c5 100644 --- a/source/slang/slang-lower-to-ir.cpp +++ b/source/slang/slang-lower-to-ir.cpp @@ -2231,6 +2231,14 @@ ParameterDirection getThisParamDirection(Decl* parentDecl, ParameterDirection de return defaultDirection; } + // A parent generic declaration should not change the + // mutating-ness of the inner declaration. + // + if( as<GenericDecl>(parentDecl) ) + { + return defaultDirection; + } + // For now we make any `this` parameter default to `in`. // return kParameterDirection_In; diff --git a/tests/bugs/mutating/mutating-generic-method.slang b/tests/bugs/mutating/mutating-generic-method.slang new file mode 100644 index 000000000..18f4d315b --- /dev/null +++ b/tests/bugs/mutating/mutating-generic-method.slang @@ -0,0 +1,50 @@ +//TEST(compute):COMPARE_COMPUTE_EX:-slang -compute +//TEST(compute,vulkan):COMPARE_COMPUTE_EX:-vk -slang -compute + +// Confirm that a generic method marked `[mutating]` +// produces an `inout` parameter for `this`. + +interface IGenerator +{ + [mutating] int generate(); +} + +struct SimpleGenerator : IGenerator +{ + int state = 0; + + [mutating] int generate() { return state++; } +} + + +struct Reducer +{ + int state = 0; + [mutating] void update<S : IGenerator>(inout S g) + { + state = (state << 8) | state; + state = state + g.generate(); + } +} + +int test(int val) +{ + SimpleGenerator g = { 0 }; + Reducer r = { val+1 }; + + r.update(g); + r.update(g); + + return r.state; +} + +//TEST_INPUT:ubuffer(data=[0 0 0 0], stride=4):out +RWStructuredBuffer<int> outputBuffer; + +[numthreads(4, 1, 1)] +void computeMain(uint3 dispatchThreadID : SV_DispatchThreadID) +{ + int tid = dispatchThreadID.x; + int val = test(tid); + outputBuffer[tid] = val; +}
\ No newline at end of file diff --git a/tests/bugs/mutating/mutating-generic-method.slang.expected.txt b/tests/bugs/mutating/mutating-generic-method.slang.expected.txt new file mode 100644 index 000000000..5ac358274 --- /dev/null +++ b/tests/bugs/mutating/mutating-generic-method.slang.expected.txt @@ -0,0 +1,4 @@ +10102 +20203 +30304 +40405 |
