Handle function decls in Structured CFG analysis (#2474)
Fixes #2451
* Structured cfg analysis now handles functions with no basic blocks
* Added a test
diff --git a/source/opt/struct_cfg_analysis.cpp b/source/opt/struct_cfg_analysis.cpp
index d78ec56..dcfd4a5 100644
--- a/source/opt/struct_cfg_analysis.cpp
+++ b/source/opt/struct_cfg_analysis.cpp
@@ -19,7 +19,7 @@
namespace {
const uint32_t kMergeNodeIndex = 0;
const uint32_t kContinueNodeIndex = 1;
-}
+} // namespace
namespace spvtools {
namespace opt {
@@ -37,6 +37,8 @@
}
void StructuredCFGAnalysis::AddBlocksInFunction(Function* func) {
+ if (func->begin() == func->end()) return;
+
std::list<BasicBlock*> order;
context_->cfg()->ComputeStructuredOrder(func, &*func->begin(), &order);
diff --git a/test/opt/struct_cfg_analysis_test.cpp b/test/opt/struct_cfg_analysis_test.cpp
index 13f9022..3a980fe 100644
--- a/test/opt/struct_cfg_analysis_test.cpp
+++ b/test/opt/struct_cfg_analysis_test.cpp
@@ -461,6 +461,26 @@
}
}
+TEST_F(StructCFGAnalysisTest, EmptyFunctionTest) {
+ const std::string text = R"(
+OpCapability Shader
+OpCapability Linkage
+OpMemoryModel Logical GLSL450
+OpDecorate %func LinkageAttributes "x" Import
+%void = OpTypeVoid
+%void_fn = OpTypeFunction %void
+%func = OpFunction %void None %void_fn
+OpFunctionEnd
+)";
+
+ std::unique_ptr<IRContext> context =
+ BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
+ SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
+
+ // #2451: This segfaulted on empty functions.
+ StructuredCFGAnalysis analysis(context.get());
+}
+
} // namespace
} // namespace opt
} // namespace spvtools