| 33 | } |
| 34 | |
| 35 | bool TransformationMutatePointer::IsApplicable( |
| 36 | opt::IRContext* ir_context, |
| 37 | const TransformationContext& transformation_context) const { |
| 38 | // Check that |fresh_id| is fresh. |
| 39 | if (!fuzzerutil::IsFreshId(ir_context, message_.fresh_id())) { |
| 40 | return false; |
| 41 | } |
| 42 | |
| 43 | auto* insert_before_inst = |
| 44 | FindInstruction(message_.insert_before(), ir_context); |
| 45 | |
| 46 | // Check that |insert_before| is a valid instruction descriptor. |
| 47 | if (!insert_before_inst) { |
| 48 | return false; |
| 49 | } |
| 50 | |
| 51 | // Check that it is possible to insert OpLoad and OpStore before |
| 52 | // |insert_before_inst|. We are only using OpLoad here since the result does |
| 53 | // not depend on the opcode. |
| 54 | if (!fuzzerutil::CanInsertOpcodeBeforeInstruction(spv::Op::OpLoad, |
| 55 | insert_before_inst)) { |
| 56 | return false; |
| 57 | } |
| 58 | |
| 59 | const auto* pointer_inst = |
| 60 | ir_context->get_def_use_mgr()->GetDef(message_.pointer_id()); |
| 61 | |
| 62 | // Check that |pointer_id| is a result id of a valid pointer instruction. |
| 63 | if (!pointer_inst || !IsValidPointerInstruction(ir_context, *pointer_inst)) { |
| 64 | return false; |
| 65 | } |
| 66 | |
| 67 | // Check that the module contains an irrelevant constant that will be used to |
| 68 | // mutate |pointer_inst|. The constant is irrelevant so that the latter |
| 69 | // transformation can change its value to something more interesting. |
| 70 | auto constant_id = fuzzerutil::MaybeGetZeroConstant( |
| 71 | ir_context, transformation_context, |
| 72 | fuzzerutil::GetPointeeTypeIdFromPointerType(ir_context, |
| 73 | pointer_inst->type_id()), |
| 74 | true); |
| 75 | if (!constant_id) { |
| 76 | return false; |
| 77 | } |
| 78 | |
| 79 | assert(fuzzerutil::IdIsAvailableBeforeInstruction( |
| 80 | ir_context, insert_before_inst, constant_id) && |
| 81 | "Global constant instruction is not available before " |
| 82 | "|insert_before_inst|"); |
| 83 | |
| 84 | // Check that |pointer_inst| is available before |insert_before_inst|. |
| 85 | return fuzzerutil::IdIsAvailableBeforeInstruction( |
| 86 | ir_context, insert_before_inst, pointer_inst->result_id()); |
| 87 | } |
| 88 | |
| 89 | void TransformationMutatePointer::Apply( |
| 90 | opt::IRContext* ir_context, |
nothing calls this directly
no test coverage detected