| 613 | } |
| 614 | |
| 615 | spv_result_t ValidateVariablePointer(ValidationState_t& _, |
| 616 | const Instruction* inst, |
| 617 | spv::StorageClass storage_class, |
| 618 | const Instruction& pointee) { |
| 619 | if ((_.addressing_model() == spv::AddressingModel::Logical || |
| 620 | _.addressing_model() == spv::AddressingModel::PhysicalStorageBuffer64) && |
| 621 | !_.options()->relax_logical_pointer) { |
| 622 | spv_result_t error = SPV_SUCCESS; |
| 623 | bool contains_logical_pointer = _.ContainsType( |
| 624 | pointee.id(), |
| 625 | [&_, inst, &error](const Instruction* type) { |
| 626 | if (type->opcode() == spv::Op::OpTypePointer || |
| 627 | type->opcode() == spv::Op::OpTypeUntypedPointerKHR) { |
| 628 | const auto sc = type->GetOperandAs<spv::StorageClass>(1u); |
| 629 | if (sc != spv::StorageClass::PhysicalStorageBuffer) { |
| 630 | if (sc != spv::StorageClass::StorageBuffer && |
| 631 | sc != spv::StorageClass::Workgroup) { |
| 632 | error = |
| 633 | _.diag(SPV_ERROR_INVALID_ID, inst) |
| 634 | << "In Logical addressing, variables can only allocate a " |
| 635 | "pointer to the StorageBuffer or Workgroup storage " |
| 636 | "classes"; |
| 637 | } else if (!_.HasCapability( |
| 638 | spv::Capability::VariablePointersStorageBuffer) && |
| 639 | sc == spv::StorageClass::StorageBuffer) { |
| 640 | error = |
| 641 | _.diag(SPV_ERROR_INVALID_ID, inst) |
| 642 | << "In Logical addressing, variables can only allocate a " |
| 643 | "storage buffer pointer if the " |
| 644 | "VariablePointersStorageBuffer capability is declared"; |
| 645 | } else if (!_.HasCapability(spv::Capability::VariablePointers) && |
| 646 | sc == spv::StorageClass::Workgroup) { |
| 647 | error = |
| 648 | _.diag(SPV_ERROR_INVALID_ID, inst) |
| 649 | << "In Logical addressing, variables can only allocate a " |
| 650 | "workgroup pointer if the VariablePointers capability " |
| 651 | "is " |
| 652 | "declared"; |
| 653 | } |
| 654 | return true; |
| 655 | } |
| 656 | } |
| 657 | return false; |
| 658 | }, |
| 659 | /* traverse_all_types = */ false); |
| 660 | |
| 661 | if (error != SPV_SUCCESS) return error; |
| 662 | |
| 663 | if (contains_logical_pointer) { |
| 664 | if (storage_class != spv::StorageClass::Function && |
| 665 | storage_class != spv::StorageClass::Private) { |
| 666 | return _.diag(SPV_ERROR_INVALID_ID, inst) |
| 667 | << "In Logical addressing with variable pointers, variables " |
| 668 | << "that allocate pointers must be in Function or Private " |
| 669 | << "storage classes"; |
| 670 | } |
| 671 | } |
| 672 | } |
no test coverage detected