Returns SPV_ERROR_INVALID_CAPABILITY and emits a diagnostic if the instruction is invalid because the required capability isn't declared in the module.
| 240 | // instruction is invalid because the required capability isn't declared |
| 241 | // in the module. |
| 242 | spv_result_t CapabilityCheck(ValidationState_t& _, const Instruction* inst) { |
| 243 | const spv::Op opcode = inst->opcode(); |
| 244 | CapabilitySet opcode_caps = EnablingCapabilitiesForOp(_, opcode); |
| 245 | if (!_.HasAnyOfCapabilities(opcode_caps)) { |
| 246 | return _.diag(SPV_ERROR_INVALID_CAPABILITY, inst) |
| 247 | << "Opcode " << spvOpcodeString(opcode) |
| 248 | << " requires one of these capabilities: " << ToString(opcode_caps); |
| 249 | } |
| 250 | for (size_t i = 0; i < inst->operands().size(); ++i) { |
| 251 | const auto& operand = inst->operand(i); |
| 252 | const auto word = inst->word(operand.offset); |
| 253 | if (spvOperandIsConcreteMask(operand.type)) { |
| 254 | // Check for required capabilities for each bit position of the mask. |
| 255 | for (uint32_t mask_bit = 0x80000000; mask_bit; mask_bit >>= 1) { |
| 256 | if (word & mask_bit) { |
| 257 | spv_result_t status = |
| 258 | CheckRequiredCapabilities(_, inst, i + 1, operand, mask_bit); |
| 259 | if (status != SPV_SUCCESS) return status; |
| 260 | } |
| 261 | } |
| 262 | } else if (spvIsIdType(operand.type)) { |
| 263 | // TODO(dneto): Check the value referenced by this Id, if we can compute |
| 264 | // it. For now, just punt, to fix issue 248: |
| 265 | // https://github.com/KhronosGroup/SPIRV-Tools/issues/248 |
| 266 | } else { |
| 267 | // Check the operand word as a whole. |
| 268 | spv_result_t status = |
| 269 | CheckRequiredCapabilities(_, inst, i + 1, operand, word); |
| 270 | if (status != SPV_SUCCESS) return status; |
| 271 | } |
| 272 | } |
| 273 | return SPV_SUCCESS; |
| 274 | } |
| 275 | |
| 276 | // Checks that the instruction can be used in this target environment's base |
| 277 | // version. Assumes that CapabilityCheck has checked direct capability |
no test coverage detected