diff options
| author | jsmall-nvidia <jsmall@nvidia.com> | 2022-04-26 10:10:17 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-04-26 10:10:17 -0400 |
| commit | 66ad0072821b58318c6dc5d2d64c966e312951dd (patch) | |
| tree | 1d28f0dcf23ca9ac40f4fdd0b92eb5a55b170df1 | |
| parent | b69b0e43e27ec94c0397774db804b4077b062b21 (diff) | |
Overloaded name lookup fix (#2199)
* #include an absolute path didn't work - because paths were taken to always be relative.
* Fix for overloaded name lookup.
* Small improvements.
| -rw-r--r-- | source/slang/slang-lookup.cpp | 36 | ||||
| -rw-r--r-- | tests/bugs/operator-overload.slang | 31 | ||||
| -rw-r--r-- | tests/bugs/operator-overload.slang.expected.txt | 4 | ||||
| -rw-r--r-- | tests/bugs/shadowed-lookup.slang | 23 | ||||
| -rw-r--r-- | tests/bugs/shadowed-lookup.slang.expected.txt | 0 | ||||
| -rw-r--r-- | tests/current-bugs/mul-crash.slang | 27 | ||||
| -rw-r--r-- | tests/experiments/generic/operator-overload.slang | 39 |
7 files changed, 92 insertions, 68 deletions
diff --git a/source/slang/slang-lookup.cpp b/source/slang/slang-lookup.cpp index e3093a3db..a77478ccb 100644 --- a/source/slang/slang-lookup.cpp +++ b/source/slang/slang-lookup.cpp @@ -752,6 +752,31 @@ static void _lookUpMembersInValue( return _lookUpMembersInType(astBuilder, name, valueType, request, ioResult, breadcrumbs); } +// True if the declaration is of an overloadable variety +// (ie can have multiple definitions with the same name) +// +// For example functions are overloadable, but variables are (typically) not. +static bool _isDeclOverloadable(Decl* decl) +{ + // If it's a generic strip off, to get to inner decl type + while (auto genericDecl = as<GenericDecl>(decl)) + { + decl = genericDecl->inner; + } + + // TODO(JS): Do we need to special case around ConstructorDecl? or AccessorDecl? + // It seems not as they are both function-like and potentially overloadable + + // If it's callable, it's a function-like and so overloadable + if (auto callableDecl = as<CallableDecl>(decl)) + { + SLANG_UNUSED(callableDecl); + return true; + } + + return false; +} + static void _lookUpInScopes( ASTBuilder* astBuilder, Name* name, @@ -912,9 +937,16 @@ static void _lookUpInScopes( if (result.isValid()) { - // If we've found a result in this scope, then there + // If it's overloaded or the decl we have is of an overloadable type then we just keep going + if (result.isOverloaded() || + _isDeclOverloadable(result.item.declRef.getDecl())) + { + continue; + } + + // If we've found a result in this scope (and it's not overloadable), then there // is no reason to look further up (for now). - return; + break; } } diff --git a/tests/bugs/operator-overload.slang b/tests/bugs/operator-overload.slang new file mode 100644 index 000000000..b70b9b987 --- /dev/null +++ b/tests/bugs/operator-overload.slang @@ -0,0 +1,31 @@ +//TEST(compute):COMPARE_COMPUTE_EX:-slang -compute -shaderobj + +// Tests operator overloading works in user space. + +//TEST_INPUT:ubuffer(data=[0 0 0 0], stride=4):out,name outputBuffer +RWStructuredBuffer<int> outputBuffer; + +struct Vec2d +{ + float x, y; +}; + +Vec2d operator+(Vec2d a, Vec2d b) +{ + return {a.x + b.x, a.y + b.y}; +} + +[numthreads(4, 1, 1)] +void computeMain(uint3 dispatchThreadID : SV_DispatchThreadID) +{ + int index = dispatchThreadID.x; + + Vec2d a = { 1, -index + 3 }; + Vec2d b = { index - 4, index * index }; + + Vec2d c = a + b; + + int r = int(c.x + c.y); + + outputBuffer[dispatchThreadID.x] = int(r); +}
\ No newline at end of file diff --git a/tests/bugs/operator-overload.slang.expected.txt b/tests/bugs/operator-overload.slang.expected.txt new file mode 100644 index 000000000..c9fa0697e --- /dev/null +++ b/tests/bugs/operator-overload.slang.expected.txt @@ -0,0 +1,4 @@ +0 +1 +4 +9 diff --git a/tests/bugs/shadowed-lookup.slang b/tests/bugs/shadowed-lookup.slang new file mode 100644 index 000000000..ed4ab7893 --- /dev/null +++ b/tests/bugs/shadowed-lookup.slang @@ -0,0 +1,23 @@ +//TEST:COMPARE_COMPUTE_EX: -slang -compute + +RWStructuredBuffer<float> outputBuffer; + +struct SomeType +{ + float2x2 v; +}; + +float mul(SomeType a, float2 v) { return mul(a.v, v).x; } + +[numthreads(4, 1, 1)] +void computeMain(uint3 dispatchThreadID : SV_DispatchThreadID) +{ + uint tid = dispatchThreadID.x; + + float inVal = float(tid); + + float2 v = float2(inVal, inVal + 2); + SomeType t = { inVal + 1, 0, 1, 0 }; + + outputBuffer[tid] = mul(t, v).x; +}
\ No newline at end of file diff --git a/tests/bugs/shadowed-lookup.slang.expected.txt b/tests/bugs/shadowed-lookup.slang.expected.txt new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/tests/bugs/shadowed-lookup.slang.expected.txt diff --git a/tests/current-bugs/mul-crash.slang b/tests/current-bugs/mul-crash.slang deleted file mode 100644 index a5ee7e62c..000000000 --- a/tests/current-bugs/mul-crash.slang +++ /dev/null @@ -1,27 +0,0 @@ -//DISABLE_TEST:SIMPLE: -target hlsl -entry computeMain -stage compute - -// This test crashes when enabled, with a stack overrun. The crash happens when lowering into IR. -// NOTE! That the code has a bug in that the mul function calls itself - so would exhaust the stack *when run*. -// This exhausts the stack when compiling which shouldn't happen. - -RWStructuredBuffer<float> outputBuffer; - -struct SomeType -{ - float2x2 v; -}; - -float mul(SomeType a, float2 v) { return mul(a, v).x; } - -[numthreads(4, 1, 1)] -void computeMain(uint3 dispatchThreadID : SV_DispatchThreadID) -{ - uint tid = dispatchThreadID.x; - - float inVal = float(tid); - - float2 v = float2(inVal, inVal + 2); - SomeType t = { inVal + 1, 0, 1, 0 }; - - outputBuffer[tid] = mul(t, v).x; -}
\ No newline at end of file diff --git a/tests/experiments/generic/operator-overload.slang b/tests/experiments/generic/operator-overload.slang deleted file mode 100644 index 590322171..000000000 --- a/tests/experiments/generic/operator-overload.slang +++ /dev/null @@ -1,39 +0,0 @@ -//DISABLE_TEST(compute):COMPARE_COMPUTE_EX:-slang -compute -shaderobj - -/* Test here is test out operator overloading. This may not be a feature -that works in user code (it is used within the stdlib). - -This produces: -.slang(10): error 30019: expected an expression of type 'Vec2d', got 'double' - return {a.x + b.x, a.y + b.y}; - -Moreover... - -.slang(18): error 30019: expected an expression of type 'Vec2d', got 'int' - int a = 10 + 11; - -It's as if only this operator+ impl can now be seen. -*/ - -//TEST_INPUT:ubuffer(data=[0 0 0 0], stride=4):out,name outputBuffer -RWStructuredBuffer<int> outputBuffer; - -struct Vec2d -{ - double x, y; -}; - -Vec2d operator+(Vec2d a, Vec2d b) -{ - return {a.x + b.x, a.y + b.y}; -} - -[numthreads(4, 1, 1)] -void computeMain(uint3 dispatchThreadID : SV_DispatchThreadID) -{ - int index = dispatchThreadID.x; - - int a = 10 + 11; - - outputBuffer[dispatchThreadID.x] = int(v); -}
\ No newline at end of file |
