| 486 | } |
| 487 | |
| 488 | std::set<RDNode> RDAnalyzer::handleMemoryCall(RDNode &Node, CallBase &CB) { |
| 489 | auto *F = CB.getCalledFunction(); |
| 490 | if (!F) |
| 491 | return {Node}; |
| 492 | |
| 493 | if (F->isDeclaration()) { |
| 494 | return handleExternalCall(Node, CB); |
| 495 | } |
| 496 | |
| 497 | auto LeafMems = Space.nextInCallee(*F, true); |
| 498 | if (LeafMems.size() == 0) |
| 499 | return {Node}; |
| 500 | |
| 501 | std::set<llvm::Value *> Cands; |
| 502 | const auto &Target = Node.getTarget(); |
| 503 | |
| 504 | if (Target.isGlobalVariable()) |
| 505 | Cands.insert(&Target.getIR()); |
| 506 | |
| 507 | // CallBase Argument size always bigger than Function parameter size |
| 508 | // because variable argument functions aceept additional arguments. |
| 509 | for (unsigned S = 0, E = F->arg_size(); S < E; ++S) { |
| 510 | auto *Arg = CB.getArgOperand(S); |
| 511 | assert(Arg && "Unexpected Program State"); |
| 512 | |
| 513 | auto *ArgType = Arg->getType(); |
| 514 | assert(ArgType && "Unexpected Program State"); |
| 515 | |
| 516 | if (!ArgType->isPointerTy() || isPropagated(Target, *Arg) == PROPTYPE_NONE) |
| 517 | continue; |
| 518 | |
| 519 | Cands.insert(F->getArg(S)); |
| 520 | } |
| 521 | |
| 522 | if (Cands.size() == 0) |
| 523 | return {Node}; |
| 524 | |
| 525 | bool NullFound = false; |
| 526 | std::set<RDNode> Continues; |
| 527 | std::set<RDNode> Result; |
| 528 | |
| 529 | for (auto LeafMem : LeafMems) { |
| 530 | if (!LeafMem) { |
| 531 | NullFound = true; |
| 532 | continue; |
| 533 | } |
| 534 | |
| 535 | std::set<RDNode> Founds; |
| 536 | for (auto Cand : Cands) { |
| 537 | RDNode NewNode(*Cand, *LeafMem, &Node); |
| 538 | for (auto &Found : traverseFunction(NewNode, *F, false, true)) { |
| 539 | if (&Found.getTarget().getIR() == Cand) { |
| 540 | NullFound = true; |
| 541 | continue; |
| 542 | } |
| 543 | Founds.insert(Found); |
| 544 | } |
| 545 | } |
nothing calls this directly
no test coverage detected