| 234 | } |
| 235 | |
| 236 | spv_result_t ValidateReturnValue(ValidationState_t& _, |
| 237 | const Instruction* inst) { |
| 238 | const auto value_id = inst->GetOperandAs<uint32_t>(0); |
| 239 | const auto value = _.FindDef(value_id); |
| 240 | if (!value || !value->type_id()) { |
| 241 | return _.diag(SPV_ERROR_INVALID_ID, inst) |
| 242 | << "OpReturnValue Value <id> " << _.getIdName(value_id) |
| 243 | << " does not represent a value."; |
| 244 | } |
| 245 | auto value_type = _.FindDef(value->type_id()); |
| 246 | if (!value_type || spv::Op::OpTypeVoid == value_type->opcode()) { |
| 247 | return _.diag(SPV_ERROR_INVALID_ID, inst) |
| 248 | << "OpReturnValue value's type <id> " |
| 249 | << _.getIdName(value->type_id()) << " is missing or void."; |
| 250 | } |
| 251 | |
| 252 | if (_.addressing_model() == spv::AddressingModel::Logical && |
| 253 | (spv::Op::OpTypePointer == value_type->opcode() || |
| 254 | spv::Op::OpTypeUntypedPointerKHR == value_type->opcode()) && |
| 255 | !_.features().variable_pointers && !_.options()->relax_logical_pointer) { |
| 256 | return _.diag(SPV_ERROR_INVALID_ID, inst) |
| 257 | << "OpReturnValue value's type <id> " |
| 258 | << _.getIdName(value->type_id()) |
| 259 | << " is a pointer, which is invalid in the Logical addressing " |
| 260 | "model."; |
| 261 | } |
| 262 | |
| 263 | const auto function = inst->function(); |
| 264 | const auto return_type = _.FindDef(function->GetResultTypeId()); |
| 265 | if (!return_type || return_type->id() != value_type->id()) { |
| 266 | return _.diag(SPV_ERROR_INVALID_ID, inst) |
| 267 | << "OpReturnValue Value <id> " << _.getIdName(value_id) |
| 268 | << "s type does not match OpFunction's return type."; |
| 269 | } |
| 270 | |
| 271 | return SPV_SUCCESS; |
| 272 | } |
| 273 | |
| 274 | uint32_t operator>>(const spv::LoopControlShift& lhs, |
| 275 | const spv::LoopControlShift& rhs) { |
no test coverage detected