| 1595 | } |
| 1596 | |
| 1597 | spv_result_t ValidateCopyMemory(ValidationState_t& _, const Instruction* inst) { |
| 1598 | const auto target_index = 0; |
| 1599 | const auto target_id = inst->GetOperandAs<uint32_t>(target_index); |
| 1600 | const auto target = _.FindDef(target_id); |
| 1601 | if (!target) { |
| 1602 | return _.diag(SPV_ERROR_INVALID_ID, inst) |
| 1603 | << "Target operand <id> " << _.getIdName(target_id) |
| 1604 | << " is not defined."; |
| 1605 | } |
| 1606 | |
| 1607 | const auto source_index = 1; |
| 1608 | const auto source_id = inst->GetOperandAs<uint32_t>(source_index); |
| 1609 | const auto source = _.FindDef(source_id); |
| 1610 | if (!source) { |
| 1611 | return _.diag(SPV_ERROR_INVALID_ID, inst) |
| 1612 | << "Source operand <id> " << _.getIdName(source_id) |
| 1613 | << " is not defined."; |
| 1614 | } |
| 1615 | |
| 1616 | const auto target_pointer_type = _.FindDef(target->type_id()); |
| 1617 | if (!target_pointer_type || |
| 1618 | (target_pointer_type->opcode() != spv::Op::OpTypePointer && |
| 1619 | target_pointer_type->opcode() != spv::Op::OpTypeUntypedPointerKHR)) { |
| 1620 | return _.diag(SPV_ERROR_INVALID_ID, inst) |
| 1621 | << "Target operand <id> " << _.getIdName(target_id) |
| 1622 | << " is not a pointer."; |
| 1623 | } |
| 1624 | |
| 1625 | const auto source_pointer_type = _.FindDef(source->type_id()); |
| 1626 | if (!source_pointer_type || |
| 1627 | (source_pointer_type->opcode() != spv::Op::OpTypePointer && |
| 1628 | source_pointer_type->opcode() != spv::Op::OpTypeUntypedPointerKHR)) { |
| 1629 | return _.diag(SPV_ERROR_INVALID_ID, inst) |
| 1630 | << "Source operand <id> " << _.getIdName(source_id) |
| 1631 | << " is not a pointer."; |
| 1632 | } |
| 1633 | |
| 1634 | if (inst->opcode() == spv::Op::OpCopyMemory) { |
| 1635 | const bool target_typed = |
| 1636 | target_pointer_type->opcode() == spv::Op::OpTypePointer; |
| 1637 | const bool source_typed = |
| 1638 | source_pointer_type->opcode() == spv::Op::OpTypePointer; |
| 1639 | Instruction* target_type = nullptr; |
| 1640 | Instruction* source_type = nullptr; |
| 1641 | if (target_typed) { |
| 1642 | target_type = _.FindDef(target_pointer_type->GetOperandAs<uint32_t>(2)); |
| 1643 | |
| 1644 | if (!target_type || target_type->opcode() == spv::Op::OpTypeVoid) { |
| 1645 | return _.diag(SPV_ERROR_INVALID_ID, inst) |
| 1646 | << "Target operand <id> " << _.getIdName(target_id) |
| 1647 | << " cannot be a void pointer."; |
| 1648 | } |
| 1649 | } |
| 1650 | |
| 1651 | if (source_typed) { |
| 1652 | source_type = _.FindDef(source_pointer_type->GetOperandAs<uint32_t>(2)); |
| 1653 | if (!source_type || source_type->opcode() == spv::Op::OpTypeVoid) { |
| 1654 | return _.diag(SPV_ERROR_INVALID_ID, inst) |
no test coverage detected