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