| 70 | } |
| 71 | |
| 72 | void FilePathAnalyzer::handleUser(StackFrame &Frame, Value &User, |
| 73 | std::stack<StackFrame> &DefUseChains, |
| 74 | std::set<Value *> &VisitedNodes) { |
| 75 | Value *Def = Frame.Value; |
| 76 | ArgFlow &DefFlow = Frame.AnalysisResult; |
| 77 | auto &A = DefFlow.getLLVMArg(); |
| 78 | |
| 79 | if (auto *SI = dyn_cast<StoreInst>(&User)) { |
| 80 | auto *Op0 = SI->getOperand(0); |
| 81 | auto *Op1 = SI->getOperand(1); |
| 82 | |
| 83 | if (VisitedNodes.find(Op1) == VisitedNodes.end()) { |
| 84 | DefUseChains.emplace(Op1, DefFlow); |
| 85 | } |
| 86 | |
| 87 | if ((VisitedNodes.find(Op0) == VisitedNodes.end()) && !isa<Constant>(Op0) && |
| 88 | !isa<GlobalValue>(Op0)) { |
| 89 | DefUseChains.emplace(Op0, DefFlow); |
| 90 | } |
| 91 | return; |
| 92 | } |
| 93 | |
| 94 | if (auto *CB = dyn_cast<CallBase>(&User)) { |
| 95 | std::set<const Function *> CFs; |
| 96 | if (Solver) { |
| 97 | CFs = Solver->getCalledFunctions(*CB); |
| 98 | } else { |
| 99 | const auto *CF = util::getCalledFunction(*CB); |
| 100 | if (CF) |
| 101 | CFs.emplace(CF); |
| 102 | } |
| 103 | |
| 104 | for (const auto *CF : CFs) { |
| 105 | assert(CF && "Unexpected Program State"); |
| 106 | |
| 107 | if (CF == A.getParent()) |
| 108 | continue; |
| 109 | |
| 110 | for (const auto &Param : CF->args()) { |
| 111 | auto *CallArg = CB->getArgOperand(Param.getArgNo()); |
| 112 | if (CallArg != Def) |
| 113 | continue; |
| 114 | |
| 115 | if (!CallArg) |
| 116 | continue; |
| 117 | |
| 118 | analyze(Param); |
| 119 | auto &CallAF = getOrCreateArgFlow(*const_cast<Argument *>(&Param)); |
| 120 | if (CallAF.isFilePathString()) { |
| 121 | DefFlow.setFilePathString(); |
| 122 | return; |
| 123 | } |
| 124 | } |
| 125 | |
| 126 | auto Name = util::getDemangledName(CF->getName()); |
| 127 | auto Regex = |
| 128 | util::regex(Name, "std::.*::basic_string.*::basic_string\\(char " |
| 129 | "const\\*, std::allocator<char> const&\\)"); |
nothing calls this directly
no test coverage detected