diff --git a/source/slang/slang-diagnostic-defs.h b/source/slang/slang-diagnostic-defs.h index 100f7abf3a..9d1d6e0c7d 100644 --- a/source/slang/slang-diagnostic-defs.h +++ b/source/slang/slang-diagnostic-defs.h @@ -2551,7 +2551,7 @@ DIAGNOSTIC( attemptToQuerySizeOfUnsizedArray, "cannot obtain the size of an unsized array.") -DIAGNOSTIC(56003, Error, useOfUninitializedResourceType, "use of uninitialized resource type '$0'.") +DIAGNOSTIC(56003, Error, useOfUninitializedResourceType, "use of uninitialized opaque type '$0'.") // Metal DIAGNOSTIC( diff --git a/source/slang/slang-ir-legalize-types.cpp b/source/slang/slang-ir-legalize-types.cpp index 92367b8fed..bc556a650c 100644 --- a/source/slang/slang-ir-legalize-types.cpp +++ b/source/slang/slang-ir-legalize-types.cpp @@ -2053,19 +2053,17 @@ static LegalVal coerceToLegalType(IRTypeLegalizationContext* context, LegalType static LegalVal legalizeUndefined(IRTypeLegalizationContext* context, IRInst* inst) { - if (auto structType = as(inst->getFullType())) + List opaqueTypes; + if (isOpaqueType(inst->getFullType(), opaqueTypes)) { - for (auto field : structType->getFields()) - { - if (isResourceType(field->getFieldType())) - { - context->m_sink->diagnose( - field, - Diagnostics::useOfUninitializedResourceType, - field->getFieldType()); - SLANG_ABORT_COMPILATION("use of uninitialized resource type"); - } - } + auto opaqueType = opaqueTypes[0]; + auto containerType = opaqueTypes.getCount() > 1 ? opaqueTypes[1] : opaqueType; + + context->m_sink->diagnose( + containerType, + Diagnostics::useOfUninitializedResourceType, + opaqueType); + SLANG_ABORT_COMPILATION("use of uninitialized resource type"); } return LegalVal(); } diff --git a/source/slang/slang-legalize-types.cpp b/source/slang/slang-legalize-types.cpp index 7695ba3854..8111b2dc7f 100644 --- a/source/slang/slang-legalize-types.cpp +++ b/source/slang/slang-legalize-types.cpp @@ -198,6 +198,27 @@ bool isResourceType(IRType* type) return false; } +bool isOpaqueType(IRType* type, List& opaqueTypes) +{ + if (isResourceType(type)) + { + opaqueTypes.add(type); + return true; + } + + if (auto structType = as(type)) + { + for (auto field : structType->getFields()) + { + if (isOpaqueType(field->getFieldType(), opaqueTypes)) + { + opaqueTypes.add(type); + return true; + } + } + } + return false; +} // Helper wrapper function around isResourceType that checks if the given // type is a pointer to a resource type or a physical storage buffer. bool isPointerToResourceType(IRType* type) diff --git a/source/slang/slang-legalize-types.h b/source/slang/slang-legalize-types.h index de574be0d4..87224fd339 100644 --- a/source/slang/slang-legalize-types.h +++ b/source/slang/slang-legalize-types.h @@ -703,6 +703,7 @@ void legalizeEmptyTypes(TargetProgram* target, IRModule* module, DiagnosticSink* bool isResourceType(IRType* type); +bool isOpaqueType(IRType* type, List& opaqueTypes); } // namespace Slang diff --git a/tests/diagnostics/uninitialized-resource-type.slang.expected b/tests/diagnostics/uninitialized-resource-type.slang.expected index 9ae44cdd3a..087b814d31 100644 --- a/tests/diagnostics/uninitialized-resource-type.slang.expected +++ b/tests/diagnostics/uninitialized-resource-type.slang.expected @@ -1,9 +1,9 @@ result code = -1 standard error = { -tests/diagnostics/test1.slang(31): warning 41016: use of uninitialized variable 'foo' +tests/diagnostics/uninitialized-resource-type.slang(31): warning 41016: use of uninitialized variable 'foo' const let result = process(foo); ^ -tests/diagnostics/test1.slang(5): error 56003: use of uninitialized resource type 'Texture2D'. +tests/diagnostics/uninitialized-resource-type.slang(5): error 56003: use of uninitialized opaque type 'Texture2D'. struct Foo ^~~ }