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

Function ValidateArrayLength

source/val/validate_memory.cpp:2315–2399  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

2313}
2314
2315spv_result_t ValidateArrayLength(ValidationState_t& state,
2316 const Instruction* inst) {
2317 const spv::Op opcode = inst->opcode();
2318
2319 // Result type must be a 32- or 64-bit unsigned int.
2320 // 64-bit requires CapabilityShader64BitIndexingEXT or a pipeline/shader
2321 // flag and is validated in VVL.
2322 const uint32_t result_type_id = inst->type_id();
2323 if (!state.IsIntScalarTypeWithSignedness(result_type_id, 0)) {
2324 return state.diag(SPV_ERROR_INVALID_ID, inst)
2325 << "The Result Type of Op" << spvOpcodeString(opcode) << " <id> "
2326 << state.getIdName(inst->id())
2327 << " must be OpTypeInt with width 32 or 64 and signedness 0.";
2328 }
2329 const uint32_t result_type_width = state.GetBitWidth(inst->type_id());
2330 if (result_type_width != 32 && result_type_width != 64) {
2331 return state.diag(SPV_ERROR_INVALID_ID, inst)
2332 << "The Result Type of Op" << spvOpcodeString(opcode) << " <id> "
2333 << state.getIdName(inst->id())
2334 << " must be OpTypeInt with width 32 or 64 and signedness 0.";
2335 }
2336
2337 const bool untyped = inst->opcode() == spv::Op::OpUntypedArrayLengthKHR;
2338 auto pointer_ty_id = state.GetOperandTypeId(inst, (untyped ? 3 : 2));
2339 auto pointer_ty = state.FindDef(pointer_ty_id);
2340 if (untyped) {
2341 if (!pointer_ty ||
2342 pointer_ty->opcode() != spv::Op::OpTypeUntypedPointerKHR) {
2343 return state.diag(SPV_ERROR_INVALID_ID, inst)
2344 << "Pointer must be an untyped pointer object";
2345 }
2346 } else if (pointer_ty->opcode() != spv::Op::OpTypePointer) {
2347 return state.diag(SPV_ERROR_INVALID_ID, inst)
2348 << "The Structure's type in Op" << spvOpcodeString(opcode)
2349 << " <id> " << state.getIdName(inst->id())
2350 << " must be a pointer to an OpTypeStruct.";
2351 }
2352
2353 Instruction* structure_type = nullptr;
2354 if (untyped) {
2355 structure_type = state.FindDef(inst->GetOperandAs<uint32_t>(2));
2356 } else {
2357 structure_type = state.FindDef(pointer_ty->GetOperandAs<uint32_t>(2));
2358 }
2359
2360 if (structure_type->opcode() != spv::Op::OpTypeStruct) {
2361 return state.diag(SPV_ERROR_INVALID_ID, inst)
2362 << "The Structure's type in Op" << spvOpcodeString(opcode)
2363 << " <id> " << state.getIdName(inst->id())
2364 << " must be a pointer to an OpTypeStruct.";
2365 }
2366
2367 auto num_of_members = structure_type->operands().size() - 1;
2368 auto last_member =
2369 state.FindDef(structure_type->GetOperandAs<uint32_t>(num_of_members));
2370 if (last_member->opcode() != spv::Op::OpTypeRuntimeArray) {
2371 return state.diag(SPV_ERROR_INVALID_ID, inst)
2372 << "The Structure's last member in Op" << spvOpcodeString(opcode)

Callers 1

MemoryPassFunction · 0.85

Calls 15

spvOpcodeStringFunction · 0.85
spvIsVulkanEnvFunction · 0.85
diagMethod · 0.80
getIdNameMethod · 0.80
GetBitWidthMethod · 0.80
GetOperandTypeIdMethod · 0.80
FindDefMethod · 0.80
operandsMethod · 0.80
VkErrorIDMethod · 0.80
opcodeMethod · 0.45
type_idMethod · 0.45

Tested by

no test coverage detected