diff options
Diffstat (limited to 'source')
| -rw-r--r-- | source/slang/slang-diagnostic-defs.h | 2 | ||||
| -rw-r--r-- | source/slang/slang-ir-legalize-types.cpp | 54 | ||||
| -rw-r--r-- | source/slang/slang-legalize-types.cpp | 58 | ||||
| -rw-r--r-- | source/slang/slang-legalize-types.h | 5 |
4 files changed, 100 insertions, 19 deletions
diff --git a/source/slang/slang-diagnostic-defs.h b/source/slang/slang-diagnostic-defs.h index acb9beb94..4f72332ef 100644 --- a/source/slang/slang-diagnostic-defs.h +++ b/source/slang/slang-diagnostic-defs.h @@ -2551,6 +2551,8 @@ DIAGNOSTIC( attemptToQuerySizeOfUnsizedArray, "cannot obtain the size of an unsized array.") +DIAGNOSTIC(56003, Fatal, useOfUninitializedOpaqueHandle, "use of uninitialized opaque handle '$0'.") + // Metal DIAGNOSTIC( 56100, diff --git a/source/slang/slang-ir-legalize-types.cpp b/source/slang/slang-ir-legalize-types.cpp index a3e47fd55..172171912 100644 --- a/source/slang/slang-ir-legalize-types.cpp +++ b/source/slang/slang-ir-legalize-types.cpp @@ -91,7 +91,10 @@ LegalVal LegalVal::wrappedBuffer(LegalVal const& baseVal, LegalElementWrapping c // -IRTypeLegalizationContext::IRTypeLegalizationContext(TargetProgram* target, IRModule* inModule) +IRTypeLegalizationContext::IRTypeLegalizationContext( + TargetProgram* target, + IRModule* inModule, + DiagnosticSink* sink) { targetProgram = target; @@ -100,6 +103,8 @@ IRTypeLegalizationContext::IRTypeLegalizationContext(TargetProgram* target, IRMo builderStorage = IRBuilder(inModule); builder = &builderStorage; + + m_sink = sink; } static void registerLegalizedValue( @@ -2046,6 +2051,23 @@ static LegalVal coerceToLegalType(IRTypeLegalizationContext* context, LegalType } } +static LegalVal legalizeUndefined(IRTypeLegalizationContext* context, IRInst* inst) +{ + List<IRType*> opaqueTypes; + if (isOpaqueType(inst->getFullType(), opaqueTypes)) + { + auto opaqueType = opaqueTypes[0]; + auto containerType = opaqueTypes.getCount() > 1 ? opaqueTypes[1] : opaqueType; + SourceLoc loc = findBestSourceLocFromUses(inst); + + if (!loc.isValid()) + loc = getDiagnosticPos(containerType); + + context->m_sink->diagnose(loc, Diagnostics::useOfUninitializedOpaqueHandle, opaqueType); + } + return LegalVal(); +} + static LegalVal legalizeInst( IRTypeLegalizationContext* context, IRInst* inst, @@ -2122,7 +2144,7 @@ static LegalVal legalizeInst( result = legalizePrintf(context, args); break; case kIROp_undefined: - return LegalVal(); + return legalizeUndefined(context, inst); case kIROp_GpuForeach: // This case should only happen when compiling for a target that does not support // GpuForeach @@ -4015,8 +4037,8 @@ static void legalizeTypes(IRTypeLegalizationContext* context) // struct IRResourceTypeLegalizationContext : IRTypeLegalizationContext { - IRResourceTypeLegalizationContext(TargetProgram* target, IRModule* module) - : IRTypeLegalizationContext(target, module) + IRResourceTypeLegalizationContext(TargetProgram* target, IRModule* module, DiagnosticSink* sink) + : IRTypeLegalizationContext(target, module, sink) { } @@ -4046,8 +4068,11 @@ struct IRResourceTypeLegalizationContext : IRTypeLegalizationContext // struct IRExistentialTypeLegalizationContext : IRTypeLegalizationContext { - IRExistentialTypeLegalizationContext(TargetProgram* target, IRModule* module) - : IRTypeLegalizationContext(target, module) + IRExistentialTypeLegalizationContext( + TargetProgram* target, + IRModule* module, + DiagnosticSink* sink) + : IRTypeLegalizationContext(target, module, sink) { } @@ -4087,8 +4112,8 @@ struct IRExistentialTypeLegalizationContext : IRTypeLegalizationContext // a public function signature. struct IREmptyTypeLegalizationContext : IRTypeLegalizationContext { - IREmptyTypeLegalizationContext(TargetProgram* target, IRModule* module) - : IRTypeLegalizationContext(target, module) + IREmptyTypeLegalizationContext(TargetProgram* target, IRModule* module, DiagnosticSink* sink) + : IRTypeLegalizationContext(target, module, sink) { } @@ -4129,9 +4154,7 @@ void legalizeResourceTypes(TargetProgram* target, IRModule* module, DiagnosticSi { SLANG_PROFILE; - SLANG_UNUSED(sink); - - IRResourceTypeLegalizationContext context(target, module); + IRResourceTypeLegalizationContext context(target, module, sink); legalizeTypes(&context); } @@ -4139,18 +4162,13 @@ void legalizeExistentialTypeLayout(TargetProgram* target, IRModule* module, Diag { SLANG_PROFILE; - SLANG_UNUSED(module); - SLANG_UNUSED(sink); - - IRExistentialTypeLegalizationContext context(target, module); + IRExistentialTypeLegalizationContext context(target, module, sink); legalizeTypes(&context); } void legalizeEmptyTypes(TargetProgram* target, IRModule* module, DiagnosticSink* sink) { - SLANG_UNUSED(sink); - - IREmptyTypeLegalizationContext context(target, module); + IREmptyTypeLegalizationContext context(target, module, sink); legalizeTypes(&context); } diff --git a/source/slang/slang-legalize-types.cpp b/source/slang/slang-legalize-types.cpp index 7695ba385..7d107bbce 100644 --- a/source/slang/slang-legalize-types.cpp +++ b/source/slang/slang-legalize-types.cpp @@ -198,6 +198,64 @@ bool isResourceType(IRType* type) return false; } +bool isOpaqueType(IRType* type, List<IRType*>& opaqueTypes) +{ + if (isResourceType(type)) + { + opaqueTypes.add(type); + return true; + } + + if (auto structType = as<IRStructType>(type)) + { + for (auto field : structType->getFields()) + { + if (isOpaqueType(field->getFieldType(), opaqueTypes)) + { + opaqueTypes.add(type); + return true; + } + } + } + + if (auto arrayType = as<IRArrayTypeBase>(type)) + { + if (isOpaqueType(arrayType->getElementType(), opaqueTypes)) + { + opaqueTypes.add(type); + return true; + } + } + + if (auto tupleType = as<IRTupleTypeBase>(type)) + { + for (UInt i = 0; i < tupleType->getOperandCount(); i++) + { + if (auto elementType = as<IRType>(tupleType->getOperand(i))) + { + if (isOpaqueType(elementType, opaqueTypes)) + { + opaqueTypes.add(type); + return true; + } + } + } + } + + return false; +} + +SourceLoc findBestSourceLocFromUses(IRInst* inst) +{ + for (auto use = inst->firstUse; use; use = use->nextUse) + { + auto user = use->getUser(); + if (user->sourceLoc.isValid()) + return user->sourceLoc; + } + + return inst->sourceLoc; +} // 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 eaee373b2..17498ce08 100644 --- a/source/slang/slang-legalize-types.h +++ b/source/slang/slang-legalize-types.h @@ -592,8 +592,9 @@ struct IRTypeLegalizationContext IRBuilder* builder; TargetProgram* targetProgram; IRBuilder builderStorage; + DiagnosticSink* m_sink; - IRTypeLegalizationContext(TargetProgram* target, IRModule* inModule); + IRTypeLegalizationContext(TargetProgram* target, IRModule* inModule, DiagnosticSink* sink); // When inserting new globals, put them before this one. IRInst* insertBeforeGlobal = nullptr; @@ -702,7 +703,9 @@ void legalizeEmptyTypes(TargetProgram* target, IRModule* module, DiagnosticSink* bool isResourceType(IRType* type); +bool isOpaqueType(IRType* type, List<IRType*>& opaqueTypes); +SourceLoc findBestSourceLocFromUses(IRInst* inst); } // namespace Slang #endif |
