From 282da4ac94d60d3244f4d72085e66fb82cf5abd8 Mon Sep 17 00:00:00 2001 From: ArielG-NV <159081215+ArielG-NV@users.noreply.github.com> Date: Tue, 16 Apr 2024 22:01:06 -0400 Subject: Fix for unscoped enums circular reference causing an error, #3959 (#3962) --- source/slang/slang-check-decl.cpp | 11 ++++++-- source/slang/slang-lookup.cpp | 4 +-- .../enums/unscoped-enum-explicit-type.slang | 32 ++++++++++++++++++++++ 3 files changed, 43 insertions(+), 4 deletions(-) create mode 100644 tests/language-feature/enums/unscoped-enum-explicit-type.slang diff --git a/source/slang/slang-check-decl.cpp b/source/slang/slang-check-decl.cpp index d35502235..131d30d98 100644 --- a/source/slang/slang-check-decl.cpp +++ b/source/slang/slang-check-decl.cpp @@ -2380,8 +2380,15 @@ namespace Slang { // check the type being inherited from auto base = inheritanceDecl->base; - CheckConstraintSubType(base); - base = TranslateTypeNode(base); + Decl* toExclude = nullptr; + Decl* parent = getParentDecl(inheritanceDecl); + // We exclude in the case that a circular reference is possible. This is when a parent is a transparent decl. + // If we just blanket "block" all ensure's of a parent a generic may fail when trying to fetch a parent + if (parent->findModifier()) + toExclude = parent; + SemanticsDeclVisitorBase baseVistor(this->withDeclToExcludeFromLookup(toExclude)); + baseVistor.CheckConstraintSubType(base); + base = baseVistor.TranslateTypeNode(base); inheritanceDecl->base = base; // Note: we do not check whether the type being inherited from diff --git a/source/slang/slang-lookup.cpp b/source/slang/slang-lookup.cpp index 2be9d29e8..9c8b2fa0b 100644 --- a/source/slang/slang-lookup.cpp +++ b/source/slang/slang-lookup.cpp @@ -224,13 +224,13 @@ static void _lookUpDirectAndTransparentMembers( } } - // TODO(tfoley): should we look up in the transparent decls - // if we already has a hit in the current container? for(auto transparentInfo : containerDecl->getTransparentMembers()) { // The reference to the transparent member should use the same // path as we used in referring to its parent. DeclRef transparentMemberDeclRef = astBuilder->getMemberDeclRef(parentDeclRef, transparentInfo.decl); + if (transparentMemberDeclRef.getDecl() == request.declToExclude) + continue; // We need to leave a breadcrumb so that we know that the result // of lookup involves a member lookup step here diff --git a/tests/language-feature/enums/unscoped-enum-explicit-type.slang b/tests/language-feature/enums/unscoped-enum-explicit-type.slang new file mode 100644 index 000000000..aefbf8449 --- /dev/null +++ b/tests/language-feature/enums/unscoped-enum-explicit-type.slang @@ -0,0 +1,32 @@ +//TEST(compute):COMPARE_COMPUTE(filecheck-buffer=CHECK): -shaderobj + +//TEST_INPUT:ubuffer(data=[0 0], stride=4):out,name=outputBuffer +RWStructuredBuffer outputBuffer; + +[UnscopedEnum] +enum unscopedEnum : uint32_t +{ + kEnumVal1 = 5, + kEnumVal2 = 6, +}; + +struct structWithEnumVal +{ + unscopedEnum val; +}; + +void takeInToWriteFruit(unscopedEnum inData, structWithEnumVal inData2) +{ + outputBuffer[0] = inData; + outputBuffer[1] = inData2.val; +} + +[numthreads(1,1,1)] +void computeMain() +{ + // CHECK: 5 + // CHECK: 6 + structWithEnumVal enumVal; + enumVal.val = kEnumVal2; + takeInToWriteFruit(kEnumVal1, enumVal); +} \ No newline at end of file -- cgit v1.2.3