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

Function ValidateAccessChain

source/val/validate_memory.cpp:1847–2113  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1845}
1846
1847spv_result_t ValidateAccessChain(ValidationState_t& _,
1848 const Instruction* inst) {
1849 const spv::Op opcode = inst->opcode();
1850 const bool untyped_pointer = spvOpcodeGeneratesUntypedPointer(inst->opcode());
1851
1852 // The result type must be OpTypePointer for regular access chains and an
1853 // OpTypeUntypedPointerKHR for untyped access chains.
1854 auto result_type = _.FindDef(inst->type_id());
1855 if (untyped_pointer) {
1856 if (!result_type ||
1857 spv::Op::OpTypeUntypedPointerKHR != result_type->opcode()) {
1858 return _.diag(SPV_ERROR_INVALID_ID, inst)
1859 << "The Result Type of Op" << spvOpcodeString(opcode) << " <id> "
1860 << _.getIdName(inst->id())
1861 << " must be OpTypeUntypedPointerKHR. Found Op"
1862 << spvOpcodeString(result_type->opcode()) << ".";
1863 }
1864 } else {
1865 if (!result_type || spv::Op::OpTypePointer != result_type->opcode()) {
1866 return _.diag(SPV_ERROR_INVALID_ID, inst)
1867 << "The Result Type of Op" << spvOpcodeString(opcode) << " <id> "
1868 << _.getIdName(inst->id()) << " must be OpTypePointer. Found Op"
1869 << spvOpcodeString(result_type->opcode()) << ".";
1870 }
1871 }
1872
1873 if (untyped_pointer) {
1874 // Base type must be a non-pointer type.
1875 const auto base_type = _.FindDef(inst->GetOperandAs<uint32_t>(2));
1876 if (!base_type || !spvOpcodeGeneratesType(base_type->opcode()) ||
1877 base_type->opcode() == spv::Op::OpTypePointer ||
1878 base_type->opcode() == spv::Op::OpTypeUntypedPointerKHR) {
1879 return _.diag(SPV_ERROR_INVALID_ID, inst)
1880 << "Base type must be a non-pointer type";
1881 }
1882
1883 const auto ContainsBlock = [&_](const Instruction* type_inst) {
1884 if (type_inst->opcode() == spv::Op::OpTypeStruct) {
1885 if (_.HasDecoration(type_inst->id(), spv::Decoration::Block) ||
1886 _.HasDecoration(type_inst->id(), spv::Decoration::BufferBlock)) {
1887 return true;
1888 }
1889 }
1890 return false;
1891 };
1892
1893 // Block (and BufferBlock) arrays cannot be reinterpreted via untyped access
1894 // chains.
1895 const bool base_type_block_array =
1896 base_type->opcode() == spv::Op::OpTypeArray &&
1897 _.ContainsType(base_type->id(), ContainsBlock,
1898 /* traverse_all_types = */ false);
1899
1900 const auto base_index = untyped_pointer ? 3 : 2;
1901 const auto base_id = inst->GetOperandAs<uint32_t>(base_index);
1902 auto base = _.FindDef(base_id);
1903 // Strictly speaking this misses trivial access chains and function
1904 // parameter chasing, but that would be a significant complication in the

Callers 2

ValidatePtrAccessChainFunction · 0.85
MemoryPassFunction · 0.85

Calls 15

spvOpcodeStringFunction · 0.85
spvOpcodeGeneratesTypeFunction · 0.85
FindDefMethod · 0.80
diagMethod · 0.80
getIdNameMethod · 0.80
ContainsTypeMethod · 0.80
operandsMethod · 0.80
wordMethod · 0.80
optionsMethod · 0.80
addressing_modelMethod · 0.80
EvalConstantValInt64Method · 0.80

Tested by

no test coverage detected