MCPcopy Create free account
hub / github.com/KhronosGroup/SPIRV-Tools / ValidateMemberDecorate

Function ValidateMemberDecorate

source/val/validate_annotation.cpp:420–495  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

418}
419
420spv_result_t ValidateMemberDecorate(ValidationState_t& _,
421 const Instruction* inst) {
422 const auto struct_type_id = inst->GetOperandAs<uint32_t>(0);
423 const auto struct_type = _.FindDef(struct_type_id);
424 const bool is_mem_dec_id_inst =
425 (inst->opcode() == spv::Op::OpMemberDecorateIdEXT);
426 if (!struct_type || spv::Op::OpTypeStruct != struct_type->opcode()) {
427 return _.diag(SPV_ERROR_INVALID_ID, inst)
428 << (is_mem_dec_id_inst ? "OpMemberDecorateIdEXT"
429 : "OpMemberDecorate")
430 << " Structure type <id> " << _.getIdName(struct_type_id)
431 << " is not a struct type.";
432 }
433 const auto member = inst->GetOperandAs<uint32_t>(1);
434 const auto member_count =
435 static_cast<uint32_t>(struct_type->words().size() - 2);
436 if (member_count <= member) {
437 return _.diag(SPV_ERROR_INVALID_ID, inst)
438 << "Index " << member << " provided in "
439 << (is_mem_dec_id_inst ? "OpMemberDecorateIdEXT"
440 : "OpMemberDecorate")
441 << " for struct <id> " << _.getIdName(struct_type_id)
442 << " is out of bounds. The structure has " << member_count
443 << " members. Largest valid index is " << member_count - 1 << ".";
444 }
445
446 const auto decoration = inst->GetOperandAs<spv::Decoration>(2);
447 if (is_mem_dec_id_inst) {
448 if (decoration != spv::Decoration::OffsetIdEXT) {
449 if (decoration == spv::Decoration::ArrayStrideIdEXT) {
450 return _.diag(SPV_ERROR_INVALID_ID, inst)
451 << "ArrayStrideIdEXT could only be directly applied"
452 << " to array type using OpDecorateId.";
453 } else {
454 return _.diag(SPV_ERROR_INVALID_ID, inst)
455 << "Decoration operand could only be OffsetIdEXT.";
456 }
457 }
458
459 const auto is_descriptor_type = [&_](const Instruction* type_inst) {
460 return _.IsDescriptorType(type_inst->opcode());
461 };
462
463 // recursively scans the struct to find if anything has a descriptor type,
464 // must be at least 1
465 if (decoration == spv::Decoration::OffsetIdEXT) {
466 const uint32_t operand_id = inst->GetOperandAs<uint32_t>(3);
467 if (!_.IsIntScalarType(_.GetTypeId(operand_id), 32)) {
468 return _.diag(SPV_ERROR_INVALID_ID, inst)
469 << "OffsetIdEXT extra operand must be a 32-bit int scalar type.";
470 }
471 if (!_.ContainsType(struct_type_id, is_descriptor_type, true)) {
472 return _.diag(SPV_ERROR_INVALID_ID, inst)
473 << "OffsetIdEXT decoration in MemberDecorateIdEXT must only be "
474 "applied to members of structs where the struct contains "
475 "descriptor types.";
476 }
477 }

Callers 1

AnnotationPassFunction · 0.85

Calls 12

IsNotMemberDecorationFunction · 0.85
FindDefMethod · 0.80
diagMethod · 0.80
getIdNameMethod · 0.80
IsDescriptorTypeMethod · 0.80
IsIntScalarTypeMethod · 0.80
GetTypeIdMethod · 0.80
ContainsTypeMethod · 0.80
operandsMethod · 0.80
SpvDecorationStringMethod · 0.80
opcodeMethod · 0.45
sizeMethod · 0.45

Tested by

no test coverage detected