2525#include " phasar/PhasarLLVM/DataFlowSolver/IfdsIde/Problems/ExtendedTaintAnalysis/TransferEdgeFunction.h"
2626#include " phasar/PhasarLLVM/DataFlowSolver/IfdsIde/Problems/IDEExtendedTaintAnalysis.h"
2727#include " phasar/PhasarLLVM/Pointer/LLVMPointsToInfo.h"
28+ #include " phasar/PhasarLLVM/Pointer/PointsToInfo.h"
2829#include " phasar/PhasarLLVM/TaintConfig/TaintConfig.h"
2930#include " phasar/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.h"
3031#include " phasar/Utils/DebugOutput.h"
@@ -424,10 +425,31 @@ IDEExtendedTaintAnalysis::getRetFlowFunction(n_t CallSite, f_t CalleeFun,
424425 });
425426 }
426427
428+ // / Cache points-to-sets for the arguments of the CallSite for the case that
429+ // / computing points-to-info is expensive (e.g. a demand-driven
430+ // / pointer-analysis)
431+ class ArgPointsToCache {
432+ public:
433+ explicit ArgPointsToCache (PointsToInfo<v_t , n_t > *PT, size_t NumArgs)
434+ : Vec(NumArgs, nullptr ), PT(PT) {}
435+
436+ const PointsToInfo<v_t , n_t >::PointsToSetTy &
437+ getOrCreatePts (size_t Idx, const llvm::Value *Ptr,
438+ const llvm::Instruction *Call) const {
439+ auto &PSet = Vec[Idx];
440+ return PSet ? *PSet : *(PSet = PT->getPointsToSet (Ptr, Call));
441+ }
442+
443+ private:
444+ mutable std::vector<PointsToInfo<v_t , n_t >::PointsToSetPtrTy> Vec;
445+ PointsToInfo<v_t , n_t > *PT;
446+ };
447+
427448 const auto *Call = llvm::cast<llvm::CallBase>(CallSite);
428449 return makeLambdaFlow<d_t >([this , Call, CalleeFun,
429- ExitStmt{llvm::cast<llvm::ReturnInst>(ExitStmt)}](
430- d_t Source) {
450+ ExitStmt{llvm::cast<llvm::ReturnInst>(ExitStmt)},
451+ PTC{ArgPointsToCache (
452+ PT, Call->getNumArgOperands ())}](d_t Source) {
431453 std::set<d_t > Ret;
432454
433455 using ArgIterator = llvm::User::const_op_iterator;
@@ -441,18 +463,20 @@ IDEExtendedTaintAnalysis::getRetFlowFunction(n_t CallSite, f_t CalleeFun,
441463 for (; FIt != FEnd && It != End; ++FIt, ++It) {
442464 // Only map back pointer parameters, since for all others we have
443465 // call-by-value.
444- if (FIt->getType ()->isPointerTy () &&
445- equivalent (Source, makeFlowFact (&*FIt))) {
446- Ret.insert (
447- FactFactory.withTransferFrom (Source, makeFlowFact (It->get ())));
448-
449- if (HasPrecisePointsToInfo) {
450- const auto *PTS = PT->getPointsToSet (It->get (), Call);
451- for (const auto *Alias : *PTS) {
452- Ret.insert (
453- FactFactory.withTransferFrom (Source, makeFlowFact (Alias)));
454- }
455- }
466+ if (!FIt->getType ()->isPointerTy () ||
467+ !equivalent (Source, makeFlowFact (&*FIt))) {
468+ continue ;
469+ }
470+
471+ Ret.insert (FactFactory.withTransferFrom (Source, makeFlowFact (It->get ())));
472+
473+ if (!HasPrecisePointsToInfo) {
474+ continue ;
475+ }
476+
477+ for (const auto *Alias :
478+ PTC.getOrCreatePts (FIt->getArgNo (), It->get (), Call)) {
479+ Ret.insert (FactFactory.withTransferFrom (Source, makeFlowFact (Alias)));
456480 }
457481 }
458482 // For now, ignore mapping back varargs
0 commit comments