Disallow merge targeting block with OpLoopMerge (#2610)

Fixes #2588

* Add a check that the merge block of OpLoopMerge may not be the block
that contains the OpLoopMerge
  * add a test
This commit is contained in:
alan-baker 2019-05-22 02:02:54 -04:00 committed by David Neto
parent 60aaafbc70
commit 713da30b63
2 changed files with 33 additions and 0 deletions

View File

@ -237,6 +237,10 @@ spv_result_t ValidateLoopMerge(ValidationState_t& _, const Instruction* inst) {
return _.diag(SPV_ERROR_INVALID_ID, inst)
<< "Merge Block " << _.getIdName(merge_id) << " must be an OpLabel";
}
if (merge_id == inst->block()->id()) {
return _.diag(SPV_ERROR_INVALID_ID, inst)
<< "Merge Block may not be the block containing the OpLoopMerge\n";
}
const auto continue_id = inst->GetOperandAs<uint32_t>(1);
const auto continue_target = _.FindDef(continue_id);

View File

@ -3262,6 +3262,35 @@ OpFunctionEnd
"IterationMultiple loop control operand must be greater than zero"));
}
TEST_F(ValidateCFG, LoopMergeTargetsHeader) {
const std::string text = R"(
OpCapability Shader
OpCapability Linkage
OpMemoryModel Logical GLSL450
%void = OpTypeVoid
%bool = OpTypeBool
%undef = OpUndef %bool
%void_fn = OpTypeFunction %void
%fn = OpFunction %void None %void_fn
%entry = OpLabel
OpBranch %loop
%loop = OpLabel
OpLoopMerge %loop %continue None
OpBranch %body
%continue = OpLabel
OpBranch %loop
%body = OpLabel
OpReturn
OpFunctionEnd
)";
CompileSuccessfully(text);
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
EXPECT_THAT(
getDiagnosticString(),
HasSubstr("Merge Block may not be the block containing the OpLoopMerge"));
}
TEST_F(ValidateCFG, InvalidSelectionExit) {
const std::string text = R"(
OpCapability Shader