Validate variable initializer type (#2668)
Fixes #249
* The pointed to type of Result Type must match the initializer type
* Had to update some opt tests to be valid
diff --git a/source/val/validate_memory.cpp b/source/val/validate_memory.cpp
index e141309..af6b5c2 100644
--- a/source/val/validate_memory.cpp
+++ b/source/val/validate_memory.cpp
@@ -422,6 +422,11 @@
<< "OpVariable Initializer <id> '" << _.getIdName(initializer_id)
<< "' is not a constant or module-scope variable.";
}
+ if (initializer->type_id() != result_type->GetOperandAs<uint32_t>(2u)) {
+ return _.diag(SPV_ERROR_INVALID_ID, inst)
+ << "Initializer type must match the type pointed to by the Result "
+ "Type";
+ }
}
const auto storage_class =
diff --git a/test/opt/aggressive_dead_code_elim_test.cpp b/test/opt/aggressive_dead_code_elim_test.cpp
index ae98b93..4f89487 100644
--- a/test/opt/aggressive_dead_code_elim_test.cpp
+++ b/test/opt/aggressive_dead_code_elim_test.cpp
@@ -3811,7 +3811,7 @@
%6 = OpTypeFunction %void
%float = OpTypeFloat 32
%_ptr_Private_float = OpTypePointer Private %float
-%initializer = OpVariable %_ptr_Private_float Private
+%initializer = OpConstant %float 0
%live = OpVariable %_ptr_Private_float Private %initializer
%_ptr_Output_float = OpTypePointer Output %float
%output = OpVariable %_ptr_Output_float Output
diff --git a/test/opt/dead_variable_elim_test.cpp b/test/opt/dead_variable_elim_test.cpp
index fca13a8..a55ee62 100644
--- a/test/opt/dead_variable_elim_test.cpp
+++ b/test/opt/dead_variable_elim_test.cpp
@@ -217,7 +217,7 @@
%6 = OpTypeFunction %void
%float = OpTypeFloat 32
%_ptr_Private_float = OpTypePointer Private %float
-%initializer = OpVariable %_ptr_Private_float Private
+%initializer = OpConstant %float 0
%live = OpVariable %_ptr_Private_float Private %initializer
%main = OpFunction %void None %6
%9 = OpLabel
diff --git a/test/val/val_memory_test.cpp b/test/val/val_memory_test.cpp
index 490ffa8..f105822 100644
--- a/test/val/val_memory_test.cpp
+++ b/test/val/val_memory_test.cpp
@@ -3543,6 +3543,29 @@
INSTANTIATE_TEST_SUITE_P(PointerComparisons, ValidatePointerComparisons,
Values("OpPtrEqual", "OpPtrNotEqual", "OpPtrDiff"));
+TEST_F(ValidateMemory, VariableInitializerWrongType) {
+ const std::string spirv = R"(
+OpCapability Shader
+OpCapability Linkage
+OpCapability VariablePointersStorageBuffer
+OpMemoryModel Logical GLSL450
+%void = OpTypeVoid
+%int = OpTypeInt 32 0
+%float = OpTypeFloat 32
+%ptr_wg_int = OpTypePointer Workgroup %int
+%ptr_wg_float = OpTypePointer Workgroup %int
+%wg_var = OpVariable %ptr_wg_int Workgroup
+%ptr_private_wg_float = OpTypePointer Private %ptr_wg_float
+%priv_var = OpVariable %ptr_private_wg_float Private %wg_var
+)";
+
+ CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
+ EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Initializer type must match the type pointed to by "
+ "the Result Type"));
+}
+
} // namespace
} // namespace val
} // namespace spvtools