| 291 | } |
| 292 | |
| 293 | Fuzzer::Result Fuzzer::Run(uint32_t num_of_transformations_to_apply) { |
| 294 | assert(is_valid_ && "The module was invalidated during the previous fuzzing"); |
| 295 | |
| 296 | const auto initial_num_of_transformations = |
| 297 | static_cast<uint32_t>(transformation_sequence_out_.transformation_size()); |
| 298 | |
| 299 | auto status = Status::kComplete; |
| 300 | do { |
| 301 | if (!ApplyPassAndCheckValidity( |
| 302 | repeated_pass_manager_->ChoosePass(transformation_sequence_out_))) { |
| 303 | status = Status::kFuzzerPassLedToInvalidModule; |
| 304 | break; |
| 305 | } |
| 306 | |
| 307 | // Check that the module is small enough. |
| 308 | if (ir_context_->module()->id_bound() >= |
| 309 | fuzzer_context_->GetIdBoundLimit()) { |
| 310 | status = Status::kModuleTooBig; |
| 311 | break; |
| 312 | } |
| 313 | |
| 314 | auto transformations_applied_so_far = static_cast<uint32_t>( |
| 315 | transformation_sequence_out_.transformation_size()); |
| 316 | assert(transformations_applied_so_far >= initial_num_of_transformations && |
| 317 | "Number of transformations cannot decrease"); |
| 318 | |
| 319 | // Check if we've already applied the maximum number of transformations. |
| 320 | if (transformations_applied_so_far >= |
| 321 | fuzzer_context_->GetTransformationLimit()) { |
| 322 | status = Status::kTransformationLimitReached; |
| 323 | break; |
| 324 | } |
| 325 | |
| 326 | // Check that we've not got stuck (this can happen if the only available |
| 327 | // fuzzer passes are not able to apply any transformations, or can only |
| 328 | // apply very few transformations). |
| 329 | if (num_repeated_passes_applied_ >= |
| 330 | fuzzer_context_->GetTransformationLimit()) { |
| 331 | status = Status::kFuzzerStuck; |
| 332 | break; |
| 333 | } |
| 334 | |
| 335 | // Check whether we've exceeded the number of transformations we can apply |
| 336 | // in a single call to this method. |
| 337 | if (num_of_transformations_to_apply != 0 && |
| 338 | transformations_applied_so_far - initial_num_of_transformations >= |
| 339 | num_of_transformations_to_apply) { |
| 340 | status = Status::kComplete; |
| 341 | break; |
| 342 | } |
| 343 | |
| 344 | } while (ShouldContinueRepeatedPasses(num_of_transformations_to_apply == 0)); |
| 345 | |
| 346 | if (status != Status::kFuzzerPassLedToInvalidModule) { |
| 347 | // We apply this transformations despite the fact that we might exceed |
| 348 | // |num_of_transformations_to_apply|. This is not a problem for us since |
| 349 | // these fuzzer passes are relatively simple yet might trigger some bugs. |
| 350 | for (auto& pass : final_passes_) { |
nothing calls this directly
no test coverage detected