| 1246 | } |
| 1247 | |
| 1248 | spv_result_t ValidateLoad(ValidationState_t& _, const Instruction* inst) { |
| 1249 | const auto result_type = _.FindDef(inst->type_id()); |
| 1250 | if (!result_type) { |
| 1251 | return _.diag(SPV_ERROR_INVALID_ID, inst) |
| 1252 | << "OpLoad Result Type <id> " << _.getIdName(inst->type_id()) |
| 1253 | << " is not defined."; |
| 1254 | } |
| 1255 | |
| 1256 | const auto pointer_index = 2; |
| 1257 | const auto pointer_id = inst->GetOperandAs<uint32_t>(pointer_index); |
| 1258 | const auto pointer = _.FindDef(pointer_id); |
| 1259 | if (!pointer || |
| 1260 | ((_.addressing_model() == spv::AddressingModel::Logical) && |
| 1261 | ((!_.features().variable_pointers && |
| 1262 | !spvOpcodeReturnsLogicalPointer(pointer->opcode())) || |
| 1263 | (_.features().variable_pointers && |
| 1264 | !spvOpcodeReturnsLogicalVariablePointer(pointer->opcode()))))) { |
| 1265 | return _.diag(SPV_ERROR_INVALID_ID, inst) |
| 1266 | << "OpLoad Pointer <id> " << _.getIdName(pointer_id) |
| 1267 | << " is not a logical pointer."; |
| 1268 | } |
| 1269 | |
| 1270 | const auto pointer_type = _.FindDef(pointer->type_id()); |
| 1271 | if (!pointer_type || |
| 1272 | (pointer_type->opcode() != spv::Op::OpTypePointer && |
| 1273 | pointer_type->opcode() != spv::Op::OpTypeUntypedPointerKHR)) { |
| 1274 | return _.diag(SPV_ERROR_INVALID_ID, inst) |
| 1275 | << "OpLoad type for pointer <id> " << _.getIdName(pointer_id) |
| 1276 | << " is not a pointer type."; |
| 1277 | } |
| 1278 | |
| 1279 | if (pointer_type->opcode() == spv::Op::OpTypePointer) { |
| 1280 | const auto pointee_type = |
| 1281 | _.FindDef(pointer_type->GetOperandAs<uint32_t>(2)); |
| 1282 | if (!pointee_type || result_type->id() != pointee_type->id()) { |
| 1283 | return _.diag(SPV_ERROR_INVALID_ID, inst) |
| 1284 | << "OpLoad Result Type <id> " << _.getIdName(inst->type_id()) |
| 1285 | << " does not match Pointer <id> " << _.getIdName(pointer->id()) |
| 1286 | << "s type."; |
| 1287 | } |
| 1288 | } |
| 1289 | |
| 1290 | if (!_.options()->before_hlsl_legalization && |
| 1291 | _.ContainsRuntimeArray(inst->type_id())) { |
| 1292 | return _.diag(SPV_ERROR_INVALID_ID, inst) |
| 1293 | << "Cannot load a runtime-sized array"; |
| 1294 | } |
| 1295 | |
| 1296 | if (auto error = CheckMemoryAccess(_, inst, 3)) return error; |
| 1297 | |
| 1298 | if (_.HasCapability(spv::Capability::Shader) && |
| 1299 | _.ContainsLimitedUseIntOrFloatType(inst->type_id()) && |
| 1300 | result_type->opcode() != spv::Op::OpTypePointer) { |
| 1301 | if (result_type->opcode() != spv::Op::OpTypeInt && |
| 1302 | result_type->opcode() != spv::Op::OpTypeFloat && |
| 1303 | result_type->opcode() != spv::Op::OpTypeVector && |
| 1304 | result_type->opcode() != spv::Op::OpTypeMatrix) { |
| 1305 | return _.diag(SPV_ERROR_INVALID_ID, inst) |
no test coverage detected