Fix infinite loop in GetBlockDepth (#4519)

Fixes #4515

* Sets block depth to 0 if it encountered multiple times and leaves
  finding the real error for other code
This commit is contained in:
alan-baker 2021-09-10 23:27:14 -04:00 committed by GitHub
parent 013b1f3d6d
commit 912460e46a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 36 additions and 0 deletions

View File

@ -308,6 +308,9 @@ int Function::GetBlockDepth(BasicBlock* bb) {
if (block_depth_.find(bb) != block_depth_.end()) {
return block_depth_[bb];
}
// Avoid recursion. Something is wrong if the same block is encountered
// multiple times.
block_depth_[bb] = 0;
BasicBlock* bb_dom = bb->immediate_dominator();
if (!bb_dom || bb == bb_dom) {

View File

@ -4449,6 +4449,39 @@ OpFunctionEnd
HasSubstr("Default must be an OpLabel instruction"));
}
TEST_F(ValidateCFG, BlockDepthRecursion) {
const std::string text = R"(
OpCapability Shader
OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %main "main"
%void = OpTypeVoid
%bool = OpTypeBool
%undef = OpUndef %bool
%void_fn = OpTypeFunction %void
%main = OpFunction %void None %void_fn
%1 = OpLabel
OpBranch %2
%2 = OpLabel
OpLoopMerge %3 %4 None
OpBranchConditional %undef %3 %4
%4 = OpLabel
OpBranch %2
%3 = OpLabel
OpBranch %5
%5 = OpLabel
OpSelectionMerge %2 None
OpBranchConditional %undef %6 %7
%6 = OpLabel
OpReturn
%7 = OpLabel
OpReturn
OpFunctionEnd
)";
CompileSuccessfully(text);
EXPECT_EQ(SPV_ERROR_INVALID_CFG, ValidateInstructions());
}
} // namespace
} // namespace val
} // namespace spvtools