summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/slang/slang-diagnostic-defs.h2
-rw-r--r--source/slang/slang-ir-legalize-types.cpp54
-rw-r--r--source/slang/slang-legalize-types.cpp58
-rw-r--r--source/slang/slang-legalize-types.h5
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