Fix dereference of possibly nullptr
authorAlan Baker <alanbaker@google.com>
Tue, 30 Jan 2018 15:15:43 +0000 (10:15 -0500)
committerAlan Baker <alanbaker@google.com>
Tue, 30 Jan 2018 15:15:43 +0000 (10:15 -0500)
* If the dead branch elim is performed on a module without structured
control flow, the OpSelectionMerge may not be present
 * Add a check for pointer validity before dereferencing
* Added a test to catch the bug

source/opt/dead_branch_elim_pass.cpp
test/opt/dead_branch_elim_test.cpp

index bdbf385..482d440 100644 (file)
@@ -153,7 +153,7 @@ bool DeadBranchElimPass::MarkLiveBlocks(
       AddBranch(live_lab_id, block);
       context()->KillInst(terminator);
       ir::Instruction* mergeInst = block->GetMergeInst();
-      if (mergeInst->opcode() == SpvOpSelectionMerge) {
+      if (mergeInst && mergeInst->opcode() == SpvOpSelectionMerge) {
         context()->KillInst(mergeInst);
       }
       stack.push_back(GetParentBlock(live_lab_id));
index bb165ae..11265ff 100644 (file)
@@ -1907,6 +1907,32 @@ TEST_F(DeadBranchElimTest, UnreachableContinuePhiInMerge) {
 
   SinglePassRunAndMatch<opt::DeadBranchElimPass>(text, true);
 }
+
+TEST_F(DeadBranchElimTest, NonStructuredIf) {
+  const std::string text = R"(
+; CHECK-NOT: OpBranchConditional
+OpCapability Kernel
+OpCapability Linkage
+OpMemoryModel Logical OpenCL
+OpDecorate %func LinkageAttributes "func" Export
+%void = OpTypeVoid
+%bool = OpTypeBool
+%true = OpConstantTrue %bool
+%functy = OpTypeFunction %void
+%func = OpFunction %void None %functy
+%entry = OpLabel
+OpBranchConditional %true %then %else
+%then = OpLabel
+OpBranch %final
+%else = OpLabel
+OpBranch %final
+%final = OpLabel
+OpReturn
+OpFunctionEnd
+)";
+
+  SinglePassRunAndMatch<opt::DeadBranchElimPass>(text, true);
+}
 #endif
 
 // TODO(greg-lunarg): Add tests to verify handling of these cases: