| 101 | } |
| 102 | |
| 103 | void DirectionAnalyzer::handleUser(StackFrame &Frame, llvm::Value &User, |
| 104 | std::stack<StackFrame> &DefUseChains, |
| 105 | std::set<llvm::Value *> &VisitedNodes) { |
| 106 | Value *Def = Frame.Value; |
| 107 | ArgFlow &DefFlow = Frame.AnalysisResult; |
| 108 | auto &A = DefFlow.getLLVMArg(); |
| 109 | |
| 110 | if (auto *CB = dyn_cast<CallBase>(&User)) { |
| 111 | auto *CF = util::getCalledFunction(*CB, Solver); |
| 112 | if (!CF) { |
| 113 | DefFlow |= Dir_Unidentified; |
| 114 | return; |
| 115 | } |
| 116 | |
| 117 | auto *BB = CB->getParent(); |
| 118 | assert(BB && "Unexpected Program State"); |
| 119 | if (CF->isDeclaration() && mayThrow(*BB)) |
| 120 | return; |
| 121 | if (CF == A.getParent()) |
| 122 | return; |
| 123 | |
| 124 | for (auto &Param : CF->args()) { |
| 125 | auto *CallArg = CB->getArgOperand(Param.getArgNo()); |
| 126 | if (CallArg != Def) |
| 127 | continue; |
| 128 | if (!CallArg) |
| 129 | continue; |
| 130 | |
| 131 | analyze(Param); |
| 132 | auto &CallAF = getOrCreateArgFlow(Param); |
| 133 | DefFlow.mergeDirection(CallAF); |
| 134 | } |
| 135 | return; |
| 136 | } |
| 137 | |
| 138 | if (auto *SI = dyn_cast<StoreInst>(&User)) { |
| 139 | // if current user is store instruction, |
| 140 | auto *Op1 = SI->getOperand(1); |
| 141 | assert(Op1 && "Unexpected Program State"); |
| 142 | |
| 143 | // if storedDef has not been visited yet and is not an argument, |
| 144 | // go traverse Def-Use Chain. |
| 145 | if (VisitedNodes.find(Op1) != VisitedNodes.end()) { |
| 146 | if (isa<GetElementPtrInst>(Op1)) |
| 147 | DefFlow |= Dir_In; |
| 148 | |
| 149 | auto *ValueOp = SI->getValueOperand(); |
| 150 | if (VisitedNodes.find(ValueOp) == VisitedNodes.end()) { |
| 151 | DefFlow |= Dir_Out; |
| 152 | } |
| 153 | } |
| 154 | |
| 155 | if ((VisitedNodes.find(Op1) == VisitedNodes.end()) && !isa<Argument>(Op1)) |
| 156 | DefUseChains.emplace(Op1, DefFlow); |
| 157 | |
| 158 | return; |
| 159 | } |
| 160 |
nothing calls this directly
no test coverage detected