mirror of
https://github.com/KhronosGroup/SPIRV-Tools
synced 2024-12-24 00:40:14 +00:00
Add some missing switch validation (#4507)
Fixes #4506 * Add validation of selector and default operands
This commit is contained in:
parent
92868b8f3f
commit
c16224c684
@ -199,6 +199,18 @@ spv_result_t ValidateSwitch(ValidationState_t& _, const Instruction* inst) {
|
||||
// At least two operands (selector, default), any more than that are
|
||||
// literal/target.
|
||||
|
||||
const auto sel_type_id = _.GetOperandTypeId(inst, 0);
|
||||
if (!_.IsIntScalarType(sel_type_id)) {
|
||||
return _.diag(SPV_ERROR_INVALID_ID, inst)
|
||||
<< "Selector type must be OpTypeInt";
|
||||
}
|
||||
|
||||
const auto default_label = _.FindDef(inst->GetOperandAs<uint32_t>(1));
|
||||
if (default_label->opcode() != SpvOpLabel) {
|
||||
return _.diag(SPV_ERROR_INVALID_ID, inst)
|
||||
<< "Default must be an OpLabel instruction";
|
||||
}
|
||||
|
||||
// target operands must be OpLabel
|
||||
for (size_t i = 2; i < num_operands; i += 2) {
|
||||
// literal, id
|
||||
|
@ -4399,6 +4399,56 @@ OpFunctionEnd
|
||||
"1[%BAD], but not via a structured exit"));
|
||||
}
|
||||
|
||||
TEST_F(ValidateCFG, SwitchSelectorNotAnInt) {
|
||||
const std::string spirv = R"(
|
||||
OpCapability Shader
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint GLCompute %main "main"
|
||||
OpExecutionMode %main LocalSize 1 1 1
|
||||
%void = OpTypeVoid
|
||||
%float = OpTypeFloat 32
|
||||
%float_1 = OpConstant %float 1
|
||||
%void_fn = OpTypeFunction %void
|
||||
%main = OpFunction %void None %void_fn
|
||||
%entry = OpLabel
|
||||
OpSelectionMerge %default None
|
||||
OpSwitch %float_1 %default
|
||||
%default = OpLabel
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
)";
|
||||
|
||||
CompileSuccessfully(spirv);
|
||||
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
|
||||
EXPECT_THAT(getDiagnosticString(),
|
||||
HasSubstr("Selector type must be OpTypeInt"));
|
||||
}
|
||||
|
||||
TEST_F(ValidateCFG, SwitchDefaultNotALabel) {
|
||||
const std::string spirv = R"(
|
||||
OpCapability Shader
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint GLCompute %main "main"
|
||||
OpExecutionMode %main LocalSize 1 1 1
|
||||
%void = OpTypeVoid
|
||||
%int = OpTypeInt 32 0
|
||||
%int_1 = OpConstant %int 1
|
||||
%void_fn = OpTypeFunction %void
|
||||
%main = OpFunction %void None %void_fn
|
||||
%entry = OpLabel
|
||||
OpSelectionMerge %default None
|
||||
OpSwitch %int_1 %int_1
|
||||
%default = OpLabel
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
)";
|
||||
|
||||
CompileSuccessfully(spirv);
|
||||
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
|
||||
EXPECT_THAT(getDiagnosticString(),
|
||||
HasSubstr("Default must be an OpLabel instruction"));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace val
|
||||
} // namespace spvtools
|
||||
|
Loading…
Reference in New Issue
Block a user