| 13 | DirectionReport(DirectionReport) {} |
| 14 | |
| 15 | bool ExternalFilter::check(const ASTIRNode &Node) const { |
| 16 | if (isCallReturn(Node.AST)) |
| 17 | return true; |
| 18 | |
| 19 | auto Def = Node.IR.getDefinition(); |
| 20 | auto *CB = llvm::dyn_cast_or_null<llvm::CallBase>(Def.first); |
| 21 | if (!CB) |
| 22 | return false; |
| 23 | |
| 24 | // Generally, definition indicates return of call when an instruction is |
| 25 | // callbase and its index is -1 in DFNode. However, there is an exception case |
| 26 | // for example, consant memset for aggregate type. This case is an assignment |
| 27 | // definition to aggregate type variable. Thus, this case is not considered |
| 28 | // externally assigned because call return case is checked using |
| 29 | // Node.AST.isCallReturn() above call statement in this function. |
| 30 | if (Def.second == -1) |
| 31 | return false; |
| 32 | |
| 33 | auto *F = util::getCalledFunction(*CB); |
| 34 | if (!F) |
| 35 | return false; |
| 36 | |
| 37 | if (F->isVarArg() && (unsigned)Def.second >= F->arg_size()) |
| 38 | return false; |
| 39 | |
| 40 | auto *A = F->getArg(Def.second); |
| 41 | if (!A) |
| 42 | return false; |
| 43 | |
| 44 | if (!DirectionReport.has(*A)) |
| 45 | return false; |
| 46 | |
| 47 | return DirectionReport.get(*A) == Dir_Out; |
| 48 | } |
| 49 | |
| 50 | bool ExternalFilter::isCallReturn(const ASTDefNode &Node) const { |
| 51 | auto *Assigned = Node.getAssigned(); |
nothing calls this directly
no test coverage detected