Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/KhronosGroup/SPIRV-Tools.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoralan-baker <alanbaker@google.com>2022-10-24 22:16:33 +0300
committerGitHub <noreply@github.com>2022-10-24 22:16:33 +0300
commit7326b967a52aecef25b3fedaaba388d6616db93d (patch)
treee57c45ccd02c202437d59ef538460b3ee49f43fe
parent0ebf830572133cc0b95e39990ae0bb0767aa52fe (diff)
Prevent null pointer from being dereferenced (#4971)
Fixes https://crbug.com/oss-fuzz/48553 * Assign a reflexive dominator if no other dominator can be found using forward traversals * This prevents a null dereference of a pointer in the sorting of the output
-rw-r--r--source/cfa.h8
-rw-r--r--test/val/val_cfg_test.cpp27
2 files changed, 34 insertions, 1 deletions
diff --git a/source/cfa.h b/source/cfa.h
index 2743ab40c..9ae3e39a1 100644
--- a/source/cfa.h
+++ b/source/cfa.h
@@ -275,10 +275,16 @@ std::vector<std::pair<BB*, BB*>> CFA<BB>::CalculateDominators(
std::vector<std::pair<bb_ptr, bb_ptr>> out;
for (auto idom : idoms) {
+ // At this point if there is no dominator for the node, just make it
+ // reflexive.
+ auto dominator = std::get<1>(idom).dominator;
+ if (dominator == undefined_dom) {
+ dominator = std::get<1>(idom).postorder_index;
+ }
// NOTE: performing a const cast for convenient usage with
// UpdateImmediateDominators
out.push_back({const_cast<BB*>(std::get<0>(idom)),
- const_cast<BB*>(postorder[std::get<1>(idom).dominator])});
+ const_cast<BB*>(postorder[dominator])});
}
// Sort by postorder index to generate a deterministic ordering of edges.
diff --git a/test/val/val_cfg_test.cpp b/test/val/val_cfg_test.cpp
index a4d144419..c8dd4a2fd 100644
--- a/test/val/val_cfg_test.cpp
+++ b/test/val/val_cfg_test.cpp
@@ -4601,6 +4601,33 @@ OpFunctionEnd
"does not structurally dominate the back-edge block '8[%8]'"));
}
+TEST_F(ValidateCFG, BadLoop) {
+ const std::string text = R"(
+OpCapability Shader
+OpMemoryModel Logical Simple
+OpEntryPoint Fragment %2 " "
+OpExecutionMode %2 OriginUpperLeft
+OpName %49 "loop"
+%void = OpTypeVoid
+%12 = OpTypeFunction %void
+%2 = OpFunction %void None %12
+%33 = OpLabel
+OpBranch %49
+%50 = OpLabel
+OpBranch %49
+%49 = OpLabel
+OpLoopMerge %33 %50 Unroll
+OpBranch %49
+OpFunctionEnd
+)";
+
+ CompileSuccessfully(text);
+ EXPECT_EQ(SPV_ERROR_INVALID_CFG, ValidateInstructions());
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Loop header '2[%loop]' is targeted by 2 back-edge "
+ "blocks but the standard requires exactly one"));
+}
+
} // namespace
} // namespace val
} // namespace spvtools