diff --git a/source/slang/slang-check-overload.cpp b/source/slang/slang-check-overload.cpp index 8d76d25548c..7a89f2e23f7 100644 --- a/source/slang/slang-check-overload.cpp +++ b/source/slang/slang-check-overload.cpp @@ -1328,6 +1328,20 @@ int SemanticsVisitor::CompareLookupResultItems( bool rightIsExtension = false; bool leftIsFreeFormExtension = false; bool rightIsFreeFormExtension = false; + bool leftIsExtern = left.declRef.getDecl()->hasModifier(); + bool rigthIsExtern = right.declRef.getDecl()->hasModifier(); + + // If both left and right are extern, then they are equal. + // If only one of them is extern, then the other one is preferred. + // If neither is extern, then we continue with the rest of the checks. + if (leftIsExtern) + { + return (rigthIsExtern ? 0 : 1); + } + if (rigthIsExtern) + { + return (leftIsExtern ? -1 : 0); + } // Prefer declarations that are not in free-form generic extensions, i.e. // `extension T { /* declaration here should have lower precedence. */ } diff --git a/tests/library/ambiguous-extern-export-entry.slang b/tests/library/ambiguous-extern-export-entry.slang new file mode 100644 index 00000000000..afa0ed8c9e8 --- /dev/null +++ b/tests/library/ambiguous-extern-export-entry.slang @@ -0,0 +1,32 @@ +//TEST(compute):COMPARE_COMPUTE_EX(filecheck-buffer=BUFFER):-slang -compute -shaderobj +//TEST(compute):COMPARE_COMPUTE_EX(filecheck-buffer=BUFFER):-slang -compute -dx12 -shaderobj +//TEST(compute, vulkan):COMPARE_COMPUTE_EX(filecheck-buffer=BUFFER):-vk -compute -shaderobj +//TEST(compute):COMPARE_COMPUTE_EX(filecheck-buffer=BUFFER):-cpu -compute -shaderobj + +import "ambiguous-extern-export-lib1.slang"; +import "ambiguous-extern-export-lib2.slang"; + +export static const int call_data_len = 6; +export static const int call_group_vector[call_data_len] = {1,2,3,4,5,6}; + +//TEST_INPUT:ubuffer(data=[0 0 0 0 0 0], stride=4):out,name=outputBuffer +RWStructuredBuffer outputBuffer; + +[shader("compute")] +[numthreads(1, 1, 1)] +void computeMain() +{ + initCallId1(); + initCallId2(); + + for (int i = 0; i < call_data_len; i++) + { + outputBuffer[i] = call_id_1[i] + call_id_2[i]; + } + // BUFFER: 2 + // BUFFER-NEXT: 4 + // BUFFER-NEXT: 6 + // BUFFER-NEXT: 8 + // BUFFER-NEXT: A + // BUFFER-NEXT: C +} diff --git a/tests/library/ambiguous-extern-export-lib1.slang b/tests/library/ambiguous-extern-export-lib1.slang new file mode 100644 index 00000000000..17dc0734c0a --- /dev/null +++ b/tests/library/ambiguous-extern-export-lib1.slang @@ -0,0 +1,13 @@ +module "ambiguous-extern-export-lib1.slang"; + +public extern static const int call_data_len; +public extern static const int[call_data_len] call_group_vector; +public static int[call_data_len] call_id_1 = {}; + +public void initCallId1() +{ + for (int i = 0; i < call_data_len; i++) + { + call_id_1[i] = call_group_vector[i]; + } +} diff --git a/tests/library/ambiguous-extern-export-lib2.slang b/tests/library/ambiguous-extern-export-lib2.slang new file mode 100644 index 00000000000..08d01fb0412 --- /dev/null +++ b/tests/library/ambiguous-extern-export-lib2.slang @@ -0,0 +1,15 @@ + +module "ambiguous-extern-export-lib2.slang"; + +public extern static const int call_data_len; +public extern static const int[call_data_len] call_group_vector; + +public static int[call_data_len] call_id_2 = {}; + +public void initCallId2() +{ + for (int i = 0; i < call_data_len; i++) + { + call_id_2[i] = call_group_vector[i]; + } +}