From 912460e46ae85fc9a44e19c59447484bb6e43541 Mon Sep 17 00:00:00 2001 From: alan-baker Date: Fri, 10 Sep 2021 23:27:14 -0400 Subject: [PATCH] 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 --- source/val/function.cpp | 3 +++ test/val/val_cfg_test.cpp | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/source/val/function.cpp b/source/val/function.cpp index 249c8664f..9ad68e867 100644 --- a/source/val/function.cpp +++ b/source/val/function.cpp @@ -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) { diff --git a/test/val/val_cfg_test.cpp b/test/val/val_cfg_test.cpp index a11b625c6..dd57f0187 100644 --- a/test/val/val_cfg_test.cpp +++ b/test/val/val_cfg_test.cpp @@ -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