aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/val/validate_cfg.cpp2
-rw-r--r--test/val/val_cfg_test.cpp100
2 files changed, 101 insertions, 1 deletions
diff --git a/source/val/validate_cfg.cpp b/source/val/validate_cfg.cpp
index 24d24169..9ba66f42 100644
--- a/source/val/validate_cfg.cpp
+++ b/source/val/validate_cfg.cpp
@@ -560,7 +560,7 @@ spv_result_t StructuredSwitchChecks(ValidationState_t& _, Function* function,
target_block->structurally_reachable() &&
!header->structurally_dominates(*target_block)) {
return _.diag(SPV_ERROR_INVALID_CFG, header->label())
- << "Selection header " << _.getIdName(header->id())
+ << "Switch header " << _.getIdName(header->id())
<< " does not structurally dominate its case construct "
<< _.getIdName(target);
}
diff --git a/test/val/val_cfg_test.cpp b/test/val/val_cfg_test.cpp
index 561e817e..d876c488 100644
--- a/test/val/val_cfg_test.cpp
+++ b/test/val/val_cfg_test.cpp
@@ -2064,6 +2064,106 @@ OpFunctionEnd
ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
}
+TEST_F(ValidateCFG, OpSwitchTargetCannotBeOuterLoopMergeBlock) {
+ std::string text = R"(
+OpCapability Shader
+OpCapability Linkage
+OpMemoryModel Logical GLSL450
+
+%1 = OpTypeVoid
+%2 = OpTypeFunction %1
+%3 = OpTypeBool
+%4 = OpUndef %3
+%5 = OpTypeInt 32 0
+%6 = OpConstant %5 0
+
+%7 = OpFunction %1 None %2
+
+%8 = OpLabel
+OpBranch %9
+
+%9 = OpLabel
+OpLoopMerge %10 %11 None
+OpBranch %12
+
+%12 = OpLabel
+OpSelectionMerge %13 None
+OpSwitch %6 %13 0 %10 1 %14
+
+%14 = OpLabel
+OpBranch %13
+
+%13 = OpLabel
+OpBranch %11
+
+%11 = OpLabel
+OpBranch %9
+
+%10 = OpLabel
+OpReturn
+
+OpFunctionEnd
+)";
+
+ CompileSuccessfully(text);
+ ASSERT_EQ(SPV_ERROR_INVALID_CFG, ValidateInstructions());
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr(
+ "Switch header '12[%12]' does not structurally dominate its case construct '10[%10]'\n"
+ " %12 = OpLabel"));
+}
+
+TEST_F(ValidateCFG, OpSwitchTargetCannotBeOuterLoopContinueBlock) {
+ std::string text = R"(
+OpCapability Shader
+OpCapability Linkage
+OpMemoryModel Logical GLSL450
+
+%1 = OpTypeVoid
+%2 = OpTypeFunction %1
+%3 = OpTypeBool
+%4 = OpUndef %3
+%5 = OpTypeInt 32 0
+%6 = OpConstant %5 0
+
+%7 = OpFunction %1 None %2
+
+%8 = OpLabel
+OpBranch %9
+
+%9 = OpLabel
+OpLoopMerge %10 %11 None
+OpBranch %12
+
+%12 = OpLabel
+OpSelectionMerge %13 None
+OpSwitch %6 %13 0 %11 1 %14
+
+%14 = OpLabel
+OpBranch %13
+
+%13 = OpLabel
+OpBranch %11
+
+%11 = OpLabel
+OpBranch %9
+
+%10 = OpLabel
+OpReturn
+
+OpFunctionEnd
+)";
+
+ CompileSuccessfully(text);
+ ASSERT_EQ(SPV_ERROR_INVALID_CFG, ValidateInstructions());
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr(
+ "Switch header '12[%12]' does not structurally dominate its case construct '11[%11]'\n"
+ " %12 = OpLabel"));
+}
+
TEST_F(ValidateCFG, WrongOperandList) {
std::string text = R"(
OpCapability Shader