| 65 | } |
| 66 | |
| 67 | spv_result_t ValidateConstantComposite(ValidationState_t& _, |
| 68 | const Instruction* inst) { |
| 69 | std::string opcode_name = std::string("Op") + spvOpcodeString(inst->opcode()); |
| 70 | |
| 71 | const auto result_type = _.FindDef(inst->type_id()); |
| 72 | if (!result_type || !isCompositeType(result_type)) { |
| 73 | return _.diag(SPV_ERROR_INVALID_ID, inst) |
| 74 | << opcode_name << " Result Type <id> " |
| 75 | << _.getIdName(inst->type_id()) << " is not a composite type."; |
| 76 | } |
| 77 | |
| 78 | const auto constituent_count = inst->operands().size() - 2; |
| 79 | switch (result_type->opcode()) { |
| 80 | case spv::Op::OpTypeVector: |
| 81 | case spv::Op::OpTypeVectorIdEXT: { |
| 82 | uint32_t num_result_components = _.GetDimension(result_type->id()); |
| 83 | bool comp_is_int32 = true, comp_is_const_int32 = true; |
| 84 | |
| 85 | if (result_type->opcode() == spv::Op::OpTypeVectorIdEXT) { |
| 86 | uint32_t comp_count_id = result_type->GetOperandAs<uint32_t>(2); |
| 87 | std::tie(comp_is_int32, comp_is_const_int32, num_result_components) = |
| 88 | _.EvalInt32IfConst(comp_count_id); |
| 89 | } |
| 90 | |
| 91 | if (comp_is_const_int32 && num_result_components != constituent_count) { |
| 92 | // TODO: Output ID's on diagnostic |
| 93 | return _.diag(SPV_ERROR_INVALID_ID, inst) |
| 94 | << opcode_name |
| 95 | << " Constituent <id> count does not match " |
| 96 | "Result Type <id> " |
| 97 | << _.getIdName(result_type->id()) << "s vector component count."; |
| 98 | } |
| 99 | const auto component_type = |
| 100 | _.FindDef(result_type->GetOperandAs<uint32_t>(1)); |
| 101 | if (!component_type) { |
| 102 | return _.diag(SPV_ERROR_INVALID_ID, result_type) |
| 103 | << "Component type is not defined."; |
| 104 | } |
| 105 | for (size_t constituent_index = 2; |
| 106 | constituent_index < inst->operands().size(); constituent_index++) { |
| 107 | const auto constituent_id = |
| 108 | inst->GetOperandAs<uint32_t>(constituent_index); |
| 109 | const auto constituent = _.FindDef(constituent_id); |
| 110 | const auto constituent_result_type = _.FindDef(constituent->type_id()); |
| 111 | if (!constituent_result_type || |
| 112 | component_type->id() != constituent_result_type->id()) { |
| 113 | return _.diag(SPV_ERROR_INVALID_ID, inst) |
| 114 | << opcode_name << " Constituent <id> " |
| 115 | << _.getIdName(constituent_id) |
| 116 | << "s type does not match Result Type <id> " |
| 117 | << _.getIdName(result_type->id()) << "s vector element type."; |
| 118 | } |
| 119 | } |
| 120 | } break; |
| 121 | case spv::Op::OpTypeMatrix: { |
| 122 | const auto column_count = result_type->GetOperandAs<uint32_t>(2); |
| 123 | if (column_count != constituent_count) { |
| 124 | // TODO: Output ID's on diagnostic |
no test coverage detected