summaryrefslogtreecommitdiffstats
path: root/source/slang/slang-check-expr.cpp
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2024-12-30 23:48:22 -0800
committerGitHub <noreply@github.com>2024-12-30 23:48:22 -0800
commitb7eb585241b3f3519ff494004efedae680cb44b9 (patch)
tree35f419098762fdd11f0e339c04d3f678df976598 /source/slang/slang-check-expr.cpp
parent1f98bd6195b58d8f61807671cb704d42bf24c54d (diff)
Check for undefined %id in spirv_asm block. (#5966)
Diffstat (limited to 'source/slang/slang-check-expr.cpp')
-rw-r--r--source/slang/slang-check-expr.cpp62
1 files changed, 62 insertions, 0 deletions
diff --git a/source/slang/slang-check-expr.cpp b/source/slang/slang-check-expr.cpp
index 7cb0ede2d..83b668a33 100644
--- a/source/slang/slang-check-expr.cpp
+++ b/source/slang/slang-check-expr.cpp
@@ -5311,6 +5311,10 @@ Expr* SemanticsExprVisitor::visitSPIRVAsmExpr(SPIRVAsmExpr* expr)
// We will iterate over all the operands in all the insts and check
// them
bool failed = false;
+
+ // Track %id's that have been defined in this asm block.
+ HashSet<Name*> definedIds;
+
for (auto& inst : expr->insts)
{
// It's not automatically a failure to not have info, we just won't
@@ -5327,6 +5331,52 @@ Expr* SemanticsExprVisitor::visitSPIRVAsmExpr(SPIRVAsmExpr* expr)
0);
continue;
}
+ int resultIdIndex = -1;
+ if (opInfo)
+ {
+ resultIdIndex = opInfo->resultIdIndex;
+ }
+ else if (inst.opcode.flavor == SPIRVAsmOperand::TruncateMarker)
+ {
+ // If this is __truncate, register the result id in the third operand.
+ resultIdIndex = 1;
+ }
+ else
+ {
+ // If there is no opInfo, just register all Ids as defined.
+ for (auto& operand : inst.operands)
+ {
+ if (operand.flavor == SPIRVAsmOperand::Id)
+ {
+ definedIds.add(operand.token.getName());
+ }
+ }
+ }
+
+ // Register result ID.
+ if (resultIdIndex != -1)
+ {
+ if (inst.operands.getCount() <= resultIdIndex)
+ {
+ failed = true;
+ getSink()->diagnose(
+ inst.opcode.token,
+ Diagnostics::spirvInstructionWithNotEnoughOperands,
+ inst.opcode.token);
+ continue;
+ }
+ auto& resultIdOperand = inst.operands[resultIdIndex];
+
+ if (!definedIds.add(resultIdOperand.token.getName()))
+ {
+ failed = true;
+ getSink()->diagnose(
+ inst.opcode.token,
+ Diagnostics::spirvIdRedefinition,
+ inst.opcode.token);
+ continue;
+ }
+ }
const bool isLast = &inst == &expr->insts.getLast();
for (Index operandIndex = 0; operandIndex < inst.operands.getCount(); ++operandIndex)
@@ -5438,6 +5488,18 @@ Expr* SemanticsExprVisitor::visitSPIRVAsmExpr(SPIRVAsmExpr* expr)
}
operand.knownValue = builtinVarKind.value();
}
+ else if (operand.flavor == SPIRVAsmOperand::Id)
+ {
+ if (!definedIds.contains(operand.token.getName()))
+ {
+ failed = true;
+ getSink()->diagnose(
+ operand.token,
+ Diagnostics::spirvUndefinedId,
+ operand.token);
+ return;
+ }
+ }
if (operand.bitwiseOrWith.getCount() &&
operand.flavor != SPIRVAsmOperand::Literal &&
operand.flavor != SPIRVAsmOperand::NamedValue)