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

Function ValidatePtrAccessChain

source/val/validate_memory.cpp:2235–2313  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

2233}
2234
2235spv_result_t ValidatePtrAccessChain(ValidationState_t& _,
2236 const Instruction* inst) {
2237 // Need to call first, will make sure Base is a valid ID
2238 if (auto error = ValidateAccessChain(_, inst)) return error;
2239
2240 const bool untyped_pointer = spvOpcodeGeneratesUntypedPointer(inst->opcode());
2241
2242 const auto base_idx = untyped_pointer ? 3 : 2;
2243 const auto base = _.FindDef(inst->GetOperandAs<uint32_t>(base_idx));
2244 const auto base_type = _.FindDef(base->type_id());
2245 const auto base_type_storage_class =
2246 base_type->GetOperandAs<spv::StorageClass>(1);
2247
2248 const auto element_idx = untyped_pointer ? 4 : 3;
2249 const auto element = _.FindDef(inst->GetOperandAs<uint32_t>(element_idx));
2250 const auto element_type = _.FindDef(element->type_id());
2251 if (!element_type || element_type->opcode() != spv::Op::OpTypeInt) {
2252 return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Element must be an integer";
2253 }
2254 uint64_t element_val = 0;
2255 if (_.EvalConstantValUint64(element->id(), &element_val)) {
2256 if (element_val != 0) {
2257 const auto interp_type =
2258 untyped_pointer ? _.FindDef(inst->GetOperandAs<uint32_t>(2))
2259 : _.FindDef(base_type->GetOperandAs<uint32_t>(2));
2260 if (interp_type->opcode() == spv::Op::OpTypeStruct &&
2261 (_.HasDecoration(interp_type->id(), spv::Decoration::Block) ||
2262 _.HasDecoration(interp_type->id(), spv::Decoration::BufferBlock))) {
2263 return _.diag(SPV_ERROR_INVALID_DATA, inst)
2264 << "Element must be 0 if the interpretation type is a Block- or "
2265 "BufferBlock-decorated structure";
2266 }
2267 }
2268 }
2269
2270 if (_.HasCapability(spv::Capability::Shader) &&
2271 (base_type_storage_class == spv::StorageClass::Uniform ||
2272 base_type_storage_class == spv::StorageClass::StorageBuffer ||
2273 base_type_storage_class == spv::StorageClass::PhysicalStorageBuffer ||
2274 base_type_storage_class == spv::StorageClass::PushConstant ||
2275 (_.HasCapability(spv::Capability::WorkgroupMemoryExplicitLayoutKHR) &&
2276 base_type_storage_class == spv::StorageClass::Workgroup)) &&
2277 (!_.HasDecoration(base_type->id(), spv::Decoration::ArrayStride) &&
2278 !_.HasDecoration(base_type->id(), spv::Decoration::ArrayStrideIdEXT))) {
2279 return _.diag(SPV_ERROR_INVALID_DATA, inst)
2280 << "OpPtrAccessChain must have a Base whose type is decorated "
2281 "with ArrayStride or ArrayStrideIdEXT";
2282 }
2283
2284 if (spvIsVulkanEnv(_.context()->target_env)) {
2285 const auto untyped_cap =
2286 untyped_pointer && _.HasCapability(spv::Capability::UntypedPointersKHR);
2287 if (base_type_storage_class == spv::StorageClass::Workgroup) {
2288 if (!_.HasCapability(spv::Capability::VariablePointers) && !untyped_cap) {
2289 return _.diag(SPV_ERROR_INVALID_DATA, inst)
2290 << _.VkErrorID(7651)
2291 << "OpPtrAccessChain Base operand pointing to Workgroup "
2292 "storage class must use VariablePointers capability";

Callers 1

MemoryPassFunction · 0.85

Calls 13

ValidateAccessChainFunction · 0.85
spvIsVulkanEnvFunction · 0.85
FindDefMethod · 0.80
diagMethod · 0.80
EvalConstantValUint64Method · 0.80
VkErrorIDMethod · 0.80
opcodeMethod · 0.45
type_idMethod · 0.45
idMethod · 0.45
HasDecorationMethod · 0.45
HasCapabilityMethod · 0.45

Tested by

no test coverage detected