Check forward reference in OpTypeArray. (#2307)
In a recent PR, we allowed a forward reference for the element type in
an array declaration. However, we do not have other check to make sure
the forward reference is a pointer type first reference in
OpTypeForawrdPointer. We add that check.
Fixes https://crbug.com/920074.
diff --git a/source/val/validate_datarules.cpp b/source/val/validate_datarules.cpp
index 129b6bb..826eb8d 100644
--- a/source/val/validate_datarules.cpp
+++ b/source/val/validate_datarules.cpp
@@ -214,6 +214,21 @@
return SPV_SUCCESS;
}
+// Validates that any undefined type of the array is a forward pointer.
+// It is valid to declare a forward pointer, and use its <id> as the element
+// type of the array.
+spv_result_t ValidateArray(ValidationState_t& _, const Instruction* inst) {
+ auto element_type_id = inst->GetOperandAs<const uint32_t>(1);
+ auto element_type_instruction = _.FindDef(element_type_id);
+ if (element_type_instruction == nullptr &&
+ !_.IsForwardPointer(element_type_id)) {
+ return _.diag(SPV_ERROR_INVALID_ID, inst)
+ << "Forward reference operands in an OpTypeArray must first be "
+ "declared using OpTypeForwardPointer.";
+ }
+ return SPV_SUCCESS;
+}
+
} // namespace
// Validates that Data Rules are followed according to the specifications.
@@ -256,6 +271,10 @@
if (auto error = ValidateStruct(_, inst)) return error;
break;
}
+ case SpvOpTypeArray: {
+ if (auto error = ValidateArray(_, inst)) return error;
+ break;
+ }
// TODO(ehsan): add more data rules validation here.
default: { break; }
}
diff --git a/test/val/val_data_test.cpp b/test/val/val_data_test.cpp
index 0aded92..d9413bc 100644
--- a/test/val/val_data_test.cpp
+++ b/test/val/val_data_test.cpp
@@ -934,6 +934,23 @@
"OpTypeStruct %_runtimearr_uint %uint\n"));
}
+TEST_F(ValidateData, invalid_forward_reference_in_array) {
+ std::string str = R"(
+ OpCapability Shader
+ OpCapability Linkage
+ OpMemoryModel Logical GLSL450
+ %uint = OpTypeInt 32 0
+%uint_1 = OpConstant %uint 1
+%_arr_3_uint_1 = OpTypeArray %_arr_3_uint_1 %uint_1
+)";
+
+ CompileSuccessfully(str.c_str(), SPV_ENV_UNIVERSAL_1_3);
+ ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Forward reference operands in an OpTypeArray must "
+ "first be declared using OpTypeForwardPointer."));
+}
+
} // namespace
} // namespace val
} // namespace spvtools