@@ -619,35 +619,54 @@ spv_result_t ValidateVariablePointer(ValidationState_t& _,
619619 if ((_.addressing_model () == spv::AddressingModel::Logical ||
620620 _.addressing_model () == spv::AddressingModel::PhysicalStorageBuffer64) &&
621621 !_.options ()->relax_logical_pointer ) {
622- if ((pointee.opcode () == spv::Op::OpTypePointer ||
623- pointee.opcode () == spv::Op::OpTypeUntypedPointerKHR)) {
624- const auto sc = pointee.GetOperandAs <spv::StorageClass>(1u );
625- if (sc != spv::StorageClass::PhysicalStorageBuffer) {
626- if (sc != spv::StorageClass::StorageBuffer &&
627- sc != spv::StorageClass::Workgroup) {
628- return _.diag (SPV_ERROR_INVALID_ID, inst)
629- << " In Logical addressing, variables can only allocate a "
630- " pointer to the StorageBuffer or Workgroup storage classes" ;
631- } else if (!_.HasCapability (
632- spv::Capability::VariablePointersStorageBuffer) &&
633- sc == spv::StorageClass::StorageBuffer) {
634- return _.diag (SPV_ERROR_INVALID_ID, inst)
635- << " In Logical addressing, variables can only allocate a "
636- " storage buffer pointer if the "
637- " VariablePointersStorageBuffer capability is declared" ;
638- } else if (!_.HasCapability (spv::Capability::VariablePointers) &&
639- sc == spv::StorageClass::Workgroup) {
640- return _.diag (SPV_ERROR_INVALID_ID, inst)
641- << " In Logical addressing, variables can only allocate a "
642- " workgroup pointer if the VariablePointers capability is "
643- " declared" ;
644- } else if (storage_class != spv::StorageClass::Function &&
645- storage_class != spv::StorageClass::Private) {
646- return _.diag (SPV_ERROR_INVALID_ID, inst)
647- << " In Logical addressing with variable pointers, variables "
648- << " that allocate pointers must be in Function or Private "
649- << " storage classes" ;
650- }
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" ;
651670 }
652671 }
653672 }
0 commit comments