| 701 | } |
| 702 | |
| 703 | uint32_t FuzzerPass::FindOrCreateLocalVariable( |
| 704 | uint32_t pointer_type_id, uint32_t function_id, |
| 705 | bool pointee_value_is_irrelevant) { |
| 706 | auto pointer_type = GetIRContext()->get_type_mgr()->GetType(pointer_type_id); |
| 707 | // No unused variables in release mode. |
| 708 | (void)pointer_type; |
| 709 | assert(pointer_type && pointer_type->AsPointer() && |
| 710 | pointer_type->AsPointer()->storage_class() == |
| 711 | spv::StorageClass::Function && |
| 712 | "The pointer_type_id must refer to a defined pointer type with " |
| 713 | "storage class Function"); |
| 714 | auto function = fuzzerutil::FindFunction(GetIRContext(), function_id); |
| 715 | assert(function && "The function must be defined."); |
| 716 | |
| 717 | // First we try to find a suitable existing variable. |
| 718 | // All of the local variable declarations are located in the first block. |
| 719 | for (auto& instruction : *function->begin()) { |
| 720 | if (instruction.opcode() != spv::Op::OpVariable) { |
| 721 | continue; |
| 722 | } |
| 723 | // The existing OpVariable must have type |pointer_type_id|. |
| 724 | if (instruction.type_id() != pointer_type_id) { |
| 725 | continue; |
| 726 | } |
| 727 | // Check if the found variable is marked with PointeeValueIsIrrelevant |
| 728 | // according to |pointee_value_is_irrelevant|. |
| 729 | if (GetTransformationContext()->GetFactManager()->PointeeValueIsIrrelevant( |
| 730 | instruction.result_id()) != pointee_value_is_irrelevant) { |
| 731 | continue; |
| 732 | } |
| 733 | return instruction.result_id(); |
| 734 | } |
| 735 | |
| 736 | // No such variable was found. Apply a transformation to get one. |
| 737 | uint32_t pointee_type_id = fuzzerutil::GetPointeeTypeIdFromPointerType( |
| 738 | GetIRContext(), pointer_type_id); |
| 739 | uint32_t result_id = GetFuzzerContext()->GetFreshId(); |
| 740 | ApplyTransformation(TransformationAddLocalVariable( |
| 741 | result_id, pointer_type_id, function_id, |
| 742 | FindOrCreateZeroConstant(pointee_type_id, pointee_value_is_irrelevant), |
| 743 | pointee_value_is_irrelevant)); |
| 744 | return result_id; |
| 745 | } |
| 746 | |
| 747 | uint32_t FuzzerPass::FindOrCreateGlobalVariable( |
| 748 | uint32_t pointer_type_id, bool pointee_value_is_irrelevant) { |
nothing calls this directly
no test coverage detected