From 6befb33235440c5c2de5c09f97850e03110c70e1 Mon Sep 17 00:00:00 2001 From: Martin Mory Date: Thu, 23 Dec 2021 00:26:20 +0100 Subject: [PATCH 1/5] various fixes in IDE solver - identifier renames and multiple changes of range loops to use references, those are marked with TODO/FIXME - please review whether that is right, tests pass but I would like some other eyes looking at that --- external/googletest | 2 +- external/json-schema-validator | 2 +- .../DataFlowSolver/IfdsIde/Solver/IDESolver.h | 1228 +++++++++-------- .../IfdsIde/Solver/IDESummaryGenerator.h | 22 +- .../IfdsIde/Solver/IFDSSolver.h | 26 +- .../Solver/IFDSToIDETabulationProblem.h | 80 +- .../IfdsIde/Solver/JoinHandlingNode.h | 8 +- .../IfdsIde/Solver/JumpFunctions.h | 171 ++- .../IfdsIde/Solver/LinkedNode.h | 4 +- .../DataFlowSolver/IfdsIde/Solver/PathEdge.h | 26 +- .../IfdsIde/Solver/SolverResults.h | 34 +- include/phasar/PhasarLLVM/Utils/DOTGraph.h | 210 +-- include/phasar/Utils/LLVMShorthands.h | 24 +- include/phasar/Utils/Utilities.h | 38 +- lib/PhasarLLVM/Utils/DOTGraph.cpp | 140 +- lib/Utils/LLVMShorthands.cpp | 20 +- lib/Utils/Utilities.cpp | 11 +- 17 files changed, 1065 insertions(+), 981 deletions(-) diff --git a/external/googletest b/external/googletest index e2239ee604..16f637fbf4 160000 --- a/external/googletest +++ b/external/googletest @@ -1 +1 @@ -Subproject commit e2239ee6043f73722e7aa812a459f54a28552929 +Subproject commit 16f637fbf4ffc3f7a01fa4eceb7906634565242f diff --git a/external/json-schema-validator b/external/json-schema-validator index 27fc1d0945..89ed13d76b 160000 --- a/external/json-schema-validator +++ b/external/json-schema-validator @@ -1 +1 @@ -Subproject commit 27fc1d094503623dfe39365ba82581507524545c +Subproject commit 89ed13d76b95a8dc5de1a26af85231d7dff61e47 diff --git a/include/phasar/PhasarLLVM/DataFlowSolver/IfdsIde/Solver/IDESolver.h b/include/phasar/PhasarLLVM/DataFlowSolver/IfdsIde/Solver/IDESolver.h index 707a1be3d9..0001fba8cf 100644 --- a/include/phasar/PhasarLLVM/DataFlowSolver/IfdsIde/Solver/IDESolver.h +++ b/include/phasar/PhasarLLVM/DataFlowSolver/IfdsIde/Solver/IDESolver.h @@ -103,9 +103,9 @@ class IDESolver IDESolver(IDETabulationProblem &Problem) : IDEProblem(Problem), ZeroValue(Problem.getZeroValue()), ICF(Problem.getICFG()), SolverConfig(Problem.getIFDSIDESolverConfig()), - cachedFlowEdgeFunctions(Problem), allTop(Problem.allTopFunction()), - jumpFn(std::make_shared>( - allTop, IDEProblem)), + CachedFlowEdgeFunctions(Problem), AllTop(Problem.allTopFunction()), + JumpFn(std::make_shared>( + AllTop, IDEProblem)), Seeds(Problem.initialSeeds()) {} IDESolver(const IDESolver &) = delete; @@ -119,27 +119,27 @@ class IDESolver using TableCell = typename Table::Cell; const static std::string DataFlowID = "DataFlow"; nlohmann::json J; - auto results = this->valtab.cellSet(); - if (results.empty()) { + auto Results = this->ValTab.cellSet(); + if (Results.empty()) { J[DataFlowID] = "EMPTY"; } else { - std::vector cells(results.begin(), results.end()); - sort(cells.begin(), cells.end(), [](TableCell a, TableCell b) { - return a.getRowKey() < b.getRowKey(); + std::vector Cells(Results.begin(), Results.end()); + sort(Cells.begin(), Cells.end(), [](TableCell Lhs, TableCell Rhs) { + return Lhs.getRowKey() < Rhs.getRowKey(); }); - n_t curr; - for (unsigned i = 0; i < cells.size(); ++i) { - curr = cells[i].getRowKey(); - std::string n = IDEProblem.NtoString(cells[i].getRowKey()); - boost::algorithm::trim(n); - std::string node = - ICF->getFunctionName(ICF->getFunctionOf(curr)) + "::" + n; - J[DataFlowID][node]; - std::string fact = IDEProblem.DtoString(cells[i].getColumnKey()); - boost::algorithm::trim(fact); - std::string value = IDEProblem.LtoString(cells[i].getValue()); - boost::algorithm::trim(value); - J[DataFlowID][node]["Facts"] += {fact, value}; + n_t Curr; + for (unsigned I = 0; I < Cells.size(); ++I) { + Curr = Cells[I].getRowKey(); + std::string NStr = IDEProblem.NtoString(Cells[I].getRowKey()); + boost::algorithm::trim(NStr); + std::string NodeStr = + ICF->getFunctionName(ICF->getFunctionOf(Curr)) + "::" + NStr; + J[DataFlowID][NodeStr]; + std::string FactStr = IDEProblem.DtoString(Cells[I].getColumnKey()); + boost::algorithm::trim(FactStr); + std::string ValueStr = IDEProblem.LtoString(Cells[I].getValue()); + boost::algorithm::trim(ValueStr); + J[DataFlowID][NodeStr]["Facts"] += {FactStr, ValueStr}; } } return J; @@ -195,8 +195,8 @@ class IDESolver } /// Returns the L-type result for the given value at the given statement. - [[nodiscard]] virtual l_t resultAt(n_t stmt, d_t value) { - return valtab.get(stmt, value); + [[nodiscard]] virtual l_t resultAt(n_t Stmt, d_t Value) { + return ValTab.get(Stmt, Value); } /// Returns the L-type result at the given statement for the given data-flow @@ -217,30 +217,30 @@ class IDESolver template [[nodiscard]] typename std::enable_if_t< std::is_same_v, llvm::Instruction *>, l_t> - resultAtInLLVMSSA(NTy stmt, d_t value) { - if (stmt->getType()->isVoidTy()) { - return valtab.get(stmt, value); + resultAtInLLVMSSA(NTy Stmt, d_t Value) { + if (Stmt->getType()->isVoidTy()) { + return ValTab.get(Stmt, Value); } - assert(stmt->getNextNode() && "Expected to find a valid successor node!"); - return valtab.get(stmt->getNextNode(), value); + assert(Stmt->getNextNode() && "Expected to find a valid successor node!"); + return ValTab.get(Stmt->getNextNode(), Value); } /// Returns the resulting environment for the given statement. /// The artificial zero value can be automatically stripped. /// TOP values are never returned. [[nodiscard]] virtual std::unordered_map - resultsAt(n_t stmt, bool stripZero = false) /*TODO const*/ { - std::unordered_map result = valtab.row(stmt); - if (stripZero) { - for (auto it = result.begin(); it != result.end();) { - if (IDEProblem.isZeroValue(it->first)) { - it = result.erase(it); + resultsAt(n_t Stmt, bool StripZero = false) /*TODO const*/ { + std::unordered_map Result = ValTab.row(Stmt); + if (StripZero) { + for (auto It = Result.begin(); It != Result.end();) { + if (IDEProblem.isZeroValue(It->first)) { + It = Result.erase(It); } else { - ++it; + ++It; } } } - return result; + return Result; } /// Returns the data-flow results at the given statement while respecting @@ -262,24 +262,24 @@ class IDESolver [[nodiscard]] typename std::enable_if_t< std::is_same_v, llvm::Instruction *>, std::unordered_map> - resultsAtInLLVMSSA(NTy stmt, bool stripZero = false) { - std::unordered_map result = [this, stmt]() { - if (stmt->getType()->isVoidTy()) { - return valtab.row(stmt); + resultsAtInLLVMSSA(NTy Stmt, bool StripZero = false) { + std::unordered_map Result = [this, Stmt]() { + if (Stmt->getType()->isVoidTy()) { + return ValTab.row(Stmt); } - return valtab.row(stmt->getNextNode()); + return ValTab.row(Stmt->getNextNode()); }(); - if (stripZero) { + if (StripZero) { // TODO: replace with std::erase_if (C++20) - for (auto it = result.begin(); it != result.end();) { - if (IDEProblem.isZeroValue(it->first)) { - it = result.erase(it); + for (auto It = Result.begin(); It != Result.end();) { + if (IDEProblem.isZeroValue(It->first)) { + It = Result.erase(It); } else { - ++it; + ++It; } } } - return result; + return Result; } virtual void emitTextReport(std::ostream &OS = std::cout) { @@ -296,41 +296,41 @@ class IDESolver OS << "\n***************************************************************\n" << "* Raw IDESolver results *\n" << "***************************************************************\n"; - auto cells = this->valtab.cellVec(); - if (cells.empty()) { + auto Cells = this->ValTab.cellVec(); + if (Cells.empty()) { OS << "No results computed!" << std::endl; } else { - llvmValueIDLess llvmIDLess; + LLVMValueIDLess LLVMIDLess; std::sort( - cells.begin(), cells.end(), - [&llvmIDLess](const auto &a, const auto &b) { + Cells.begin(), Cells.end(), + [&LLVMIDLess](const auto &Lhs, const auto &Rhs) { if constexpr (std::is_same_v) { - return llvmIDLess(a.getRowKey(), b.getRowKey()); + return LLVMIDLess(Lhs.getRowKey(), Rhs.getRowKey()); } else { // If non-LLVM IR is used - return a.getRowKey() < b.getRowKey(); + return Lhs.getRowKey() < Rhs.getRowKey(); } }); - n_t prev = n_t{}; - n_t curr = n_t{}; - f_t prevFn = f_t{}; - f_t currFn = f_t{}; - for (unsigned i = 0; i < cells.size(); ++i) { - curr = cells[i].getRowKey(); - currFn = ICF->getFunctionOf(curr); - if (prevFn != currFn) { - prevFn = currFn; + n_t Prev = n_t{}; + n_t Curr = n_t{}; + f_t PrevFn = f_t{}; + f_t CurrFn = f_t{}; + for (unsigned I = 0; I < Cells.size(); ++I) { + Curr = Cells[I].getRowKey(); + CurrFn = ICF->getFunctionOf(Curr); + if (PrevFn != CurrFn) { + PrevFn = CurrFn; OS << "\n\n============ Results for function '" + - ICF->getFunctionName(currFn) + "' ============\n"; + ICF->getFunctionName(CurrFn) + "' ============\n"; } - if (prev != curr) { - prev = curr; - std::string NString = IDEProblem.NtoString(curr); - std::string line(NString.size(), '-'); - OS << "\n\nN: " << NString << "\n---" << line << '\n'; + if (Prev != Curr) { + Prev = Curr; + std::string NString = IDEProblem.NtoString(Curr); + std::string Line(NString.size(), '-'); + OS << "\n\nN: " << NString << "\n---" << Line << '\n'; } - OS << "\tD: " << IDEProblem.DtoString(cells[i].getColumnKey()) - << " | V: " << IDEProblem.LtoString(cells[i].getValue()) << '\n'; + OS << "\tD: " << IDEProblem.DtoString(Cells[I].getColumnKey()) + << " | V: " << IDEProblem.LtoString(Cells[I].getValue()) << '\n'; } } OS << '\n'; @@ -339,19 +339,19 @@ class IDESolver void dumpAllInterPathEdges() { std::cout << "COMPUTED INTER PATH EDGES" << std::endl; - auto interpe = this->computedInterPathEdges.cellSet(); - for (const auto &cell : interpe) { + auto Interpe = this->computedInterPathEdges.cellSet(); + for (const auto &Cell : Interpe) { std::cout << "FROM" << std::endl; - IDEProblem.printNode(std::cout, cell.getRowKey()); + IDEProblem.printNode(std::cout, Cell.getRowKey()); std::cout << "TO" << std::endl; - IDEProblem.printNode(std::cout, cell.getColumnKey()); + IDEProblem.printNode(std::cout, Cell.getColumnKey()); std::cout << "FACTS" << std::endl; - for (const auto &fact : cell.getValue()) { + for (const auto &Fact : Cell.getValue()) { std::cout << "fact" << std::endl; - IDEProblem.printDataFlowFact(std::cout, fact.first); + IDEProblem.printDataFlowFact(std::cout, Fact.first); std::cout << "produces" << std::endl; - for (const auto &out : fact.second) { - IDEProblem.printDataFlowFact(std::cout, out); + for (const auto &Out : Fact.second) { + IDEProblem.printDataFlowFact(std::cout, Out); } } } @@ -359,26 +359,26 @@ class IDESolver void dumpAllIntraPathEdges() { std::cout << "COMPUTED INTRA PATH EDGES" << std::endl; - auto intrape = this->computedIntraPathEdges.cellSet(); - for (auto &cell : intrape) { + auto Intrape = this->computedIntraPathEdges.cellSet(); + for (auto &Cell : Intrape) { std::cout << "FROM" << std::endl; - IDEProblem.printNode(std::cout, cell.getRowKey()); + IDEProblem.printNode(std::cout, Cell.getRowKey()); std::cout << "TO" << std::endl; - IDEProblem.printNode(std::cout, cell.getColumnKey()); + IDEProblem.printNode(std::cout, Cell.getColumnKey()); std::cout << "FACTS" << std::endl; - for (auto &fact : cell.getValue()) { + for (auto &Fact : Cell.getValue()) { std::cout << "fact" << std::endl; - IDEProblem.printDataFlowFact(std::cout, fact.first); + IDEProblem.printDataFlowFact(std::cout, Fact.first); std::cout << "produces" << std::endl; - for (auto &out : fact.second) { - IDEProblem.printDataFlowFact(std::cout, out); + for (auto &Out : Fact.second) { + IDEProblem.printDataFlowFact(std::cout, Out); } } } } SolverResults getSolverResults() { - return SolverResults(this->valtab, + return SolverResults(this->ValTab, IDEProblem.getZeroValue()); } @@ -390,36 +390,36 @@ class IDESolver IFDSIDESolverConfig &SolverConfig; unsigned PathEdgeCount = 0; - FlowEdgeFunctionCache cachedFlowEdgeFunctions; + FlowEdgeFunctionCache CachedFlowEdgeFunctions; - Table> computedIntraPathEdges; + Table> ComputedIntraPathEdges; - Table> computedInterPathEdges; + Table> ComputedInterPathEdges; - EdgeFunctionPtrType allTop; + EdgeFunctionPtrType AllTop; - std::shared_ptr> jumpFn; + std::shared_ptr> JumpFn; std::map, std::vector> - intermediateEdgeFunctions; + IntermediateEdgeFunctions; // stores summaries that were queried before they were computed // see CC 2010 paper by Naeem, Lhotak and Rodriguez - Table> endsummarytab; + Table> EndsummaryTab; // edges going along calls // see CC 2010 paper by Naeem, Lhotak and Rodriguez - Table> incomingtab; + Table> IncomingTab; // stores the return sites (inside callers) to which we have unbalanced // returns if SolverConfig.followReturnPastSeeds is enabled - std::set unbalancedRetSites; + std::set UnbalancedRetSites; InitialSeeds Seeds; - Table valtab; + Table ValTab; - std::map, size_t> fSummaryReuse; + std::map, size_t> FSummaryReuse; // When transforming an IFDSTabulationProblem into an IDETabulationProblem, // we need to allocate dynamically, otherwise the objects lifetime runs out @@ -436,10 +436,10 @@ class IDESolver IDEProblem(*this->TransformedProblem), ZeroValue(IDEProblem.getZeroValue()), ICF(IDEProblem.getICFG()), SolverConfig(IDEProblem.getIFDSIDESolverConfig()), - cachedFlowEdgeFunctions(IDEProblem), - allTop(IDEProblem.allTopFunction()), - jumpFn(std::make_shared>( - allTop, IDEProblem)), + CachedFlowEdgeFunctions(IDEProblem), + AllTop(IDEProblem.allTopFunction()), + JumpFn(std::make_shared>( + AllTop, IDEProblem)), Seeds(IDEProblem.initialSeeds()) {} /// Lines 13-20 of the algorithm; processing a call site in the caller's @@ -459,97 +459,100 @@ class IDESolver /// /// @param edge an edge whose target node resembles a method call /// - virtual void processCall(const PathEdge edge) { + virtual void processCall(const PathEdge Edge) { PAMM_GET_INSTANCE; INC_COUNTER("Process Call", 1, PAMM_SEVERITY_LEVEL::Full); LOG_IF_ENABLE(BOOST_LOG_SEV(lg::get(), DEBUG) << "Process call at target: " - << IDEProblem.NtoString(edge.getTarget())); - d_t d1 = edge.factAtSource(); - n_t n = edge.getTarget(); // a call node; line 14... - d_t d2 = edge.factAtTarget(); - EdgeFunctionPtrType f = jumpFunction(edge); - const std::set returnSiteNs = ICF->getReturnSitesOfCallAt(n); - const std::set callees = ICF->getCalleesOfCallAt(n); + << IDEProblem.NtoString(Edge.getTarget())); + d_t d1 = Edge.factAtSource(); // NOLINT - keep close to algorithm notion + n_t n = Edge.getTarget(); // NOLINT - keep close to algorithm notion + // a call node; line 14... + d_t d2 = Edge.factAtTarget(); // NOLINT - keep close to algorithm notion + EdgeFunctionPtrType f = // NOLINT - keep close to algorithm notion + jumpFunction(Edge); + const std::set ReturnSiteNs = ICF->getReturnSitesOfCallAt(n); + const std::set Callees = ICF->getCalleesOfCallAt(n); LOG_IF_ENABLE( BOOST_LOG_SEV(lg::get(), DEBUG) << "Possible callees:"; - for (auto callee - : callees) { - BOOST_LOG_SEV(lg::get(), DEBUG) << " " << callee->getName().str(); + for (auto Callee + : Callees) { + BOOST_LOG_SEV(lg::get(), DEBUG) << " " << Callee->getName().str(); } BOOST_LOG_SEV(lg::get(), DEBUG) << "Possible return sites:"; for (auto ret - : returnSiteNs) { + : ReturnSiteNs) { BOOST_LOG_SEV(lg::get(), DEBUG) << " " << IDEProblem.NtoString(ret); } BOOST_LOG_SEV(lg::get(), DEBUG) << ' '); // for each possible callee - for (f_t sCalledProcN : callees) { // still line 14 + for (f_t SCalledProcN : Callees) { // still line 14 // check if a special summary for the called procedure exists - FlowFunctionPtrType specialSum = - cachedFlowEdgeFunctions.getSummaryFlowFunction(n, sCalledProcN); + FlowFunctionPtrType SpecialSum = + CachedFlowEdgeFunctions.getSummaryFlowFunction(n, SCalledProcN); // if a special summary is available, treat this as a normal flow // and use the summary flow and edge functions - if (specialSum) { + if (SpecialSum) { LOG_IF_ENABLE(BOOST_LOG_SEV(lg::get(), DEBUG) << "Found and process special summary"); - for (n_t returnSiteN : returnSiteNs) { - container_type res = computeSummaryFlowFunction(specialSum, d1, d2); + for (n_t ReturnSiteN : ReturnSiteNs) { + container_type Res = computeSummaryFlowFunction(SpecialSum, d1, d2); INC_COUNTER("SpecialSummary-FF Application", 1, PAMM_SEVERITY_LEVEL::Full); ADD_TO_HISTOGRAM("Data-flow facts", res.size(), 1, PAMM_SEVERITY_LEVEL::Full); - saveEdges(n, returnSiteN, d2, res, false); - for (d_t d3 : res) { - EdgeFunctionPtrType sumEdgFnE = - cachedFlowEdgeFunctions.getSummaryEdgeFunction(n, d2, - returnSiteN, d3); + saveEdges(n, ReturnSiteN, d2, Res, false); + for (d_t d3 : Res) { // NOLINT - keep close to algorithm notion + EdgeFunctionPtrType SumEdgFnE = + CachedFlowEdgeFunctions.getSummaryEdgeFunction(n, d2, + ReturnSiteN, d3); INC_COUNTER("SpecialSummary-EF Queries", 1, PAMM_SEVERITY_LEVEL::Full); LOG_IF_ENABLE( BOOST_LOG_SEV(lg::get(), DEBUG) - << "Queried Summary Edge Function: " << sumEdgFnE->str(); + << "Queried Summary Edge Function: " << SumEdgFnE->str(); BOOST_LOG_SEV(lg::get(), DEBUG) - << "Compose: " << sumEdgFnE->str() << " * " << f->str(); + << "Compose: " << SumEdgFnE->str() << " * " << f->str(); BOOST_LOG_SEV(lg::get(), DEBUG) << ' '); - propagate(d1, returnSiteN, d3, f->composeWith(sumEdgFnE), n, false); + propagate(d1, ReturnSiteN, d3, f->composeWith(SumEdgFnE), n, false); } } } else { // compute the call-flow function - FlowFunctionPtrType function = - cachedFlowEdgeFunctions.getCallFlowFunction(n, sCalledProcN); + FlowFunctionPtrType Function = + CachedFlowEdgeFunctions.getCallFlowFunction(n, SCalledProcN); INC_COUNTER("FF Queries", 1, PAMM_SEVERITY_LEVEL::Full); - container_type res = computeCallFlowFunction(function, d1, d2); + container_type Res = computeCallFlowFunction(Function, d1, d2); ADD_TO_HISTOGRAM("Data-flow facts", res.size(), 1, PAMM_SEVERITY_LEVEL::Full); // for each callee's start point(s) - std::set startPointsOf = ICF->getStartPointsOf(sCalledProcN); - if (startPointsOf.empty()) { + std::set StartPointsOf = ICF->getStartPointsOf(SCalledProcN); + if (StartPointsOf.empty()) { LOG_IF_ENABLE(BOOST_LOG_SEV(lg::get(), DEBUG) << "Start points of '" + - ICF->getFunctionName(sCalledProcN) + + ICF->getFunctionName(SCalledProcN) + "' currently not available!"; BOOST_LOG_SEV(lg::get(), DEBUG) << ' '); } // if startPointsOf is empty, the called function is a declaration - for (n_t sP : startPointsOf) { - saveEdges(n, sP, d2, res, true); + for (n_t SP : + StartPointsOf) { // NOLINT - keep close to algorithm notion + saveEdges(n, SP, d2, Res, true); // for each result node of the call-flow function - for (d_t d3 : res) { + for (d_t d3 : Res) { // NOLINT - keep close to algorithm notion using TableCell = typename Table::Cell; // create initial self-loop LOG_IF_ENABLE(BOOST_LOG_SEV(lg::get(), DEBUG) << "Create initial self-loop with D: " << IDEProblem.DtoString(d3)); - propagate(d3, sP, d3, EdgeIdentity::getInstance(), n, + propagate(d3, SP, d3, EdgeIdentity::getInstance(), n, false); // line 15 // register the fact that has an incoming edge from // line 15.1 of Naeem/Lhotak/Rodriguez - addIncoming(sP, d3, n, d2); + addIncoming(SP, d3, n, d2); // line 15.2, copy to avoid concurrent modification exceptions by // other threads // const std::set endSumm(endSummary(sP, d3)); @@ -564,44 +567,53 @@ class IDESolver // , create new caller-side jump functions to the return // sites because we have observed a potentially new incoming // edge into - for (const TableCell entry : endSummary(sP, d3)) { - n_t eP = entry.getRowKey(); - d_t d4 = entry.getColumnKey(); - EdgeFunctionPtrType fCalleeSummary = entry.getValue(); + for (const TableCell &Entry : endSummary( + SP, + d3)) { // TODO/FIXME: does the reference break the solver? + n_t eP = // NOLINT - keep close to algorithm notion + Entry.getRowKey(); + d_t d4 = Entry.getColumnKey(); // NOLINT - keep close to algorithm + // notion + EdgeFunctionPtrType + fCalleeSummary = // NOLINT - keep close to algorithm notion + Entry.getValue(); // for each return site - for (n_t retSiteN : returnSiteNs) { + for (n_t RetSiteN : ReturnSiteNs) { // compute return-flow function - FlowFunctionPtrType retFunction = - cachedFlowEdgeFunctions.getRetFlowFunction(n, sCalledProcN, - eP, retSiteN); + FlowFunctionPtrType RetFunction = + CachedFlowEdgeFunctions.getRetFlowFunction(n, SCalledProcN, + eP, RetSiteN); INC_COUNTER("FF Queries", 1, PAMM_SEVERITY_LEVEL::Full); - const container_type returnedFacts = computeReturnFlowFunction( - retFunction, d3, d4, n, Container{d2}); + const container_type ReturnedFacts = computeReturnFlowFunction( + RetFunction, d3, d4, n, Container{d2}); ADD_TO_HISTOGRAM("Data-flow facts", returnedFacts.size(), 1, PAMM_SEVERITY_LEVEL::Full); - saveEdges(eP, retSiteN, d4, returnedFacts, true); + saveEdges(eP, RetSiteN, d4, ReturnedFacts, true); // for each target value of the function - for (d_t d5 : returnedFacts) { + for (d_t d5 : // NOLINT - keep close to algorithm notion + ReturnedFacts) { // update the caller-side summary function // get call edge function - EdgeFunctionPtrType f4 = - cachedFlowEdgeFunctions.getCallEdgeFunction( - n, d2, sCalledProcN, d3); + EdgeFunctionPtrType + f4 = // NOLINT - keep close to algorithm notion + CachedFlowEdgeFunctions.getCallEdgeFunction( + n, d2, SCalledProcN, d3); LOG_IF_ENABLE(BOOST_LOG_SEV(lg::get(), DEBUG) << "Queried Call Edge Function: " << f4->str()); // get return edge function - EdgeFunctionPtrType f5 = - cachedFlowEdgeFunctions.getReturnEdgeFunction( - n, sCalledProcN, eP, d4, retSiteN, d5); + EdgeFunctionPtrType + f5 = // NOLINT - keep close to algorithm notion + CachedFlowEdgeFunctions.getReturnEdgeFunction( + n, SCalledProcN, eP, d4, RetSiteN, d5); LOG_IF_ENABLE(BOOST_LOG_SEV(lg::get(), DEBUG) << "Queried Return Edge Function: " << f5->str()); if (SolverConfig.emitESG()) { - for (auto sP : ICF->getStartPointsOf(sCalledProcN)) { - intermediateEdgeFunctions[std::make_tuple(n, d2, sP, d3)] + for (auto SP : ICF->getStartPointsOf(SCalledProcN)) { + IntermediateEdgeFunctions[std::make_tuple(n, d2, SP, d3)] .push_back(f4); } - intermediateEdgeFunctions[std::make_tuple(eP, d4, retSiteN, + IntermediateEdgeFunctions[std::make_tuple(eP, d4, RetSiteN, d5)] .push_back(f5); } @@ -613,18 +625,20 @@ class IDESolver << f4->str(); BOOST_LOG_SEV(lg::get(), DEBUG) << " (return * calleeSummary * call)"); - EdgeFunctionPtrType fPrime = + EdgeFunctionPtrType + fPrime = // NOLINT - keep close to algorithm notion f4->composeWith(fCalleeSummary)->composeWith(f5); LOG_IF_ENABLE(BOOST_LOG_SEV(lg::get(), DEBUG) << " = " << fPrime->str(); BOOST_LOG_SEV(lg::get(), DEBUG) << ' '); - d_t d5_restoredCtx = restoreContextOnReturnedFact(n, d2, d5); + d_t d5_restoredCtx // NOLINT - keep close to algorithm notion + = restoreContextOnReturnedFact(n, d2, d5); // propagte the effects of the entire call LOG_IF_ENABLE(BOOST_LOG_SEV(lg::get(), DEBUG) << "Compose: " << fPrime->str() << " * " << f->str(); BOOST_LOG_SEV(lg::get(), DEBUG) << ' '); - propagate(d1, retSiteN, d5_restoredCtx, + propagate(d1, RetSiteN, d5_restoredCtx, f->composeWith(fPrime), n, false); } } @@ -635,34 +649,35 @@ class IDESolver } // line 17-19 of Naeem/Lhotak/Rodriguez // process intra-procedural flows along call-to-return flow functions - for (n_t returnSiteN : returnSiteNs) { - FlowFunctionPtrType callToReturnFlowFunction = - cachedFlowEdgeFunctions.getCallToRetFlowFunction(n, returnSiteN, - callees); + for (n_t ReturnSiteN : ReturnSiteNs) { + FlowFunctionPtrType CallToReturnFF = + CachedFlowEdgeFunctions.getCallToRetFlowFunction(n, ReturnSiteN, + Callees); INC_COUNTER("FF Queries", 1, PAMM_SEVERITY_LEVEL::Full); - container_type returnFacts = - computeCallToReturnFlowFunction(callToReturnFlowFunction, d1, d2); + container_type ReturnFacts = + computeCallToReturnFlowFunction(CallToReturnFF, d1, d2); ADD_TO_HISTOGRAM("Data-flow facts", returnFacts.size(), 1, PAMM_SEVERITY_LEVEL::Full); - saveEdges(n, returnSiteN, d2, returnFacts, false); - for (d_t d3 : returnFacts) { - EdgeFunctionPtrType edgeFnE = - cachedFlowEdgeFunctions.getCallToRetEdgeFunction(n, d2, returnSiteN, - d3, callees); + saveEdges(n, ReturnSiteN, d2, ReturnFacts, false); + for (d_t d3 : ReturnFacts) { // NOLINT - keep close to algorithm notion + EdgeFunctionPtrType EdgeFnE = + CachedFlowEdgeFunctions.getCallToRetEdgeFunction(n, d2, ReturnSiteN, + d3, Callees); LOG_IF_ENABLE(BOOST_LOG_SEV(lg::get(), DEBUG) << "Queried Call-to-Return Edge Function: " - << edgeFnE->str()); + << EdgeFnE->str()); if (SolverConfig.emitESG()) { - intermediateEdgeFunctions[std::make_tuple(n, d2, returnSiteN, d3)] - .push_back(edgeFnE); + IntermediateEdgeFunctions[std::make_tuple(n, d2, ReturnSiteN, d3)] + .push_back(EdgeFnE); } INC_COUNTER("EF Queries", 1, PAMM_SEVERITY_LEVEL::Full); - auto fPrime = f->composeWith(edgeFnE); + auto fPrime = // NOLINT - keep close to algorithm notion + f->composeWith(EdgeFnE); LOG_IF_ENABLE(BOOST_LOG_SEV(lg::get(), DEBUG) - << "Compose: " << edgeFnE->str() << " * " << f->str() + << "Compose: " << EdgeFnE->str() << " * " << f->str() << " = " << fPrime->str(); BOOST_LOG_SEV(lg::get(), DEBUG) << ' '); - propagate(d1, returnSiteN, d3, fPrime, n, false); + propagate(d1, ReturnSiteN, d3, fPrime, n, false); } } } @@ -671,33 +686,34 @@ class IDESolver /// Simply propagate normal, intra-procedural flows. /// @param edge /// - virtual void processNormalFlow(const PathEdge edge) { + virtual void processNormalFlow(const PathEdge Edge) { PAMM_GET_INSTANCE; INC_COUNTER("Process Normal", 1, PAMM_SEVERITY_LEVEL::Full); LOG_IF_ENABLE(BOOST_LOG_SEV(lg::get(), DEBUG) << "Process normal at target: " - << IDEProblem.NtoString(edge.getTarget())); - d_t d1 = edge.factAtSource(); - n_t n = edge.getTarget(); - d_t d2 = edge.factAtTarget(); - EdgeFunctionPtrType f = jumpFunction(edge); - for (const auto fn : ICF->getSuccsOf(n)) { - FlowFunctionPtrType flowFunction = - cachedFlowEdgeFunctions.getNormalFlowFunction(n, fn); + << IDEProblem.NtoString(Edge.getTarget())); + d_t d1 = Edge.factAtSource(); // NOLINT - keep close to algorithm notion + n_t n = Edge.getTarget(); // NOLINT - keep close to algorithm notion + d_t d2 = Edge.factAtTarget(); // NOLINT - keep close to algorithm notion + EdgeFunctionPtrType f = // NOLINT - keep close to algorithm notion + jumpFunction(Edge); + for (const auto Fn : ICF->getSuccsOf(n)) { + FlowFunctionPtrType FlowFunc = + CachedFlowEdgeFunctions.getNormalFlowFunction(n, Fn); INC_COUNTER("FF Queries", 1, PAMM_SEVERITY_LEVEL::Full); - const container_type res = - computeNormalFlowFunction(flowFunction, d1, d2); + const container_type Res = computeNormalFlowFunction(FlowFunc, d1, d2); ADD_TO_HISTOGRAM("Data-flow facts", res.size(), 1, PAMM_SEVERITY_LEVEL::Full); - saveEdges(n, fn, d2, res, false); - for (d_t d3 : res) { - EdgeFunctionPtrType g = - cachedFlowEdgeFunctions.getNormalEdgeFunction(n, d2, fn, d3); + saveEdges(n, Fn, d2, Res, false); + for (d_t d3 : Res) { // NOLINT - keep close to algorithm notion + EdgeFunctionPtrType g = // NOLINT - keep close to algorithm notion + CachedFlowEdgeFunctions.getNormalEdgeFunction(n, d2, Fn, d3); LOG_IF_ENABLE(BOOST_LOG_SEV(lg::get(), DEBUG) << "Queried Normal Edge Function: " << g->str()); - EdgeFunctionPtrType fprime = f->composeWith(g); + EdgeFunctionPtrType fprime = // NOLINT - keep close to algorithm notion + f->composeWith(g); if (SolverConfig.emitESG()) { - intermediateEdgeFunctions[std::make_tuple(n, d2, fn, d3)].push_back( + IntermediateEdgeFunctions[std::make_tuple(n, d2, Fn, d3)].push_back( g); } LOG_IF_ENABLE(BOOST_LOG_SEV(lg::get(), DEBUG) @@ -705,116 +721,121 @@ class IDESolver << " = " << fprime->str(); BOOST_LOG_SEV(lg::get(), DEBUG) << ' '); INC_COUNTER("EF Queries", 1, PAMM_SEVERITY_LEVEL::Full); - propagate(d1, fn, d3, fprime, nullptr, false); + propagate(d1, Fn, d3, fprime, nullptr, false); } } } - void propagateValueAtStart(const std::pair nAndD, n_t n) { + void propagateValueAtStart(const std::pair NAndD, n_t Stmt) { PAMM_GET_INSTANCE; - d_t d = nAndD.second; - f_t p = ICF->getFunctionOf(n); - for (const n_t c : ICF->getCallsFromWithin(p)) { - auto lookupResults = jumpFn->forwardLookup(d, c); - if (!lookupResults) { + d_t Fact = NAndD.second; + f_t Func = ICF->getFunctionOf(Stmt); + for (const n_t CallSite : ICF->getCallsFromWithin(Func)) { + auto LookupResults = JumpFn->forwardLookup(Fact, CallSite); + if (!LookupResults) { continue; } - for (auto entry : lookupResults->get()) { - d_t dPrime = entry.first; - EdgeFunctionPtrType fPrime = entry.second; - n_t sP = n; - l_t value = val(sP, d); + for (const auto &Entry : + LookupResults->get()) { // TODO/FIXME: does the & break the solver? + d_t dPrime = Entry.first; // NOLINT - keep close to algorithm notion + EdgeFunctionPtrType fPrime = // NOLINT - keep close to algorithm notion + Entry.second; + n_t SP = Stmt; + l_t Val = val(SP, Fact); INC_COUNTER("Value Propagation", 1, PAMM_SEVERITY_LEVEL::Full); - propagateValue(c, dPrime, fPrime->computeTarget(value)); + propagateValue(CallSite, dPrime, fPrime->computeTarget(Val)); } } } - void propagateValueAtCall(const std::pair nAndD, n_t n) { + void propagateValueAtCall(const std::pair NAndD, n_t Stmt) { PAMM_GET_INSTANCE; - d_t d = nAndD.second; - for (const f_t q : ICF->getCalleesOfCallAt(n)) { - FlowFunctionPtrType callFlowFunction = - cachedFlowEdgeFunctions.getCallFlowFunction(n, q); + d_t Fact = NAndD.second; + for (const f_t Callee : ICF->getCalleesOfCallAt(Stmt)) { + FlowFunctionPtrType CallFlowFunction = + CachedFlowEdgeFunctions.getCallFlowFunction(Stmt, Callee); INC_COUNTER("FF Queries", 1, PAMM_SEVERITY_LEVEL::Full); - for (const d_t dPrime : callFlowFunction->computeTargets(d)) { - EdgeFunctionPtrType edgeFn = - cachedFlowEdgeFunctions.getCallEdgeFunction(n, d, q, dPrime); + for (const d_t dPrime // NOLINT - keep close to algorithm notion + : CallFlowFunction->computeTargets(Fact)) { + EdgeFunctionPtrType EdgeFn = + CachedFlowEdgeFunctions.getCallEdgeFunction(Stmt, Fact, Callee, + dPrime); LOG_IF_ENABLE(BOOST_LOG_SEV(lg::get(), DEBUG) - << "Queried Call Edge Function: " << edgeFn->str()); + << "Queried Call Edge Function: " << EdgeFn->str()); if (SolverConfig.emitESG()) { - for (const auto sP : ICF->getStartPointsOf(q)) { - intermediateEdgeFunctions[std::make_tuple(n, d, sP, dPrime)] - .push_back(edgeFn); + for (const auto SP : ICF->getStartPointsOf(Callee)) { + IntermediateEdgeFunctions[std::make_tuple(Stmt, Fact, SP, dPrime)] + .push_back(EdgeFn); } } INC_COUNTER("EF Queries", 1, PAMM_SEVERITY_LEVEL::Full); - for (const n_t startPoint : ICF->getStartPointsOf(q)) { + for (const n_t StartPoint : ICF->getStartPointsOf(Callee)) { INC_COUNTER("Value Propagation", 1, PAMM_SEVERITY_LEVEL::Full); - propagateValue(startPoint, dPrime, edgeFn->computeTarget(val(n, d))); + propagateValue(StartPoint, dPrime, + EdgeFn->computeTarget(val(Stmt, Fact))); } } } } - void propagateValue(n_t nHashN, d_t nHashD, const l_t &l) { - l_t valNHash = val(nHashN, nHashD); - l_t lPrime = joinValueAt(nHashN, nHashD, valNHash, l); - if (!(lPrime == valNHash)) { - setVal(nHashN, nHashD, std::move(lPrime)); - valuePropagationTask(std::pair(nHashN, nHashD)); + void propagateValue(n_t NHashN, d_t NHashD, const l_t &L) { + l_t ValNHash = val(NHashN, NHashD); + l_t LPrime = joinValueAt(NHashN, NHashD, ValNHash, L); + if (!(LPrime == ValNHash)) { + setVal(NHashN, NHashD, std::move(LPrime)); + valuePropagationTask(std::pair(NHashN, NHashD)); } } - l_t val(n_t nHashN, d_t nHashD) { - if (valtab.contains(nHashN, nHashD)) { - return valtab.get(nHashN, nHashD); + l_t val(n_t NHashN, d_t NHashD) { + if (ValTab.contains(NHashN, NHashD)) { + return ValTab.get(NHashN, NHashD); } // implicitly initialized to top; see line [1] of Fig. 7 in SRH96 paper return IDEProblem.topElement(); } - void setVal(n_t nHashN, d_t nHashD, l_t l) { + void setVal(n_t NHashN, d_t NHashD, l_t L) { LOG_IF_ENABLE([&]() { BOOST_LOG_SEV(lg::get(), DEBUG) - << "Function : " << ICF->getFunctionOf(nHashN)->getName().str(); + << "Function : " << ICF->getFunctionOf(NHashN)->getName().str(); BOOST_LOG_SEV(lg::get(), DEBUG) - << "Inst. : " << IDEProblem.NtoString(nHashN); + << "Inst. : " << IDEProblem.NtoString(NHashN); BOOST_LOG_SEV(lg::get(), DEBUG) - << "Fact : " << IDEProblem.DtoString(nHashD); + << "Fact : " << IDEProblem.DtoString(NHashD); BOOST_LOG_SEV(lg::get(), DEBUG) - << "Value : " << IDEProblem.LtoString(l); + << "Value : " << IDEProblem.LtoString(L); BOOST_LOG_SEV(lg::get(), DEBUG) << ' '; }()); // TOP is the implicit default value which we do not need to store. // if (l == IDEProblem.topElement()) { // do not store top values - // valtab.remove(nHashN, nHashD); + // ValTab.remove(nHashN, nHashD); // } else { - valtab.insert(nHashN, nHashD, std::move(l)); + ValTab.insert(NHashN, NHashD, std::move(L)); // } } - EdgeFunctionPtrType jumpFunction(const PathEdge edge) { + EdgeFunctionPtrType jumpFunction(const PathEdge Edge) { LOG_IF_ENABLE( BOOST_LOG_SEV(lg::get(), DEBUG) << " "; BOOST_LOG_SEV(lg::get(), DEBUG) << "JumpFunctions Forward-Lookup:"; BOOST_LOG_SEV(lg::get(), DEBUG) - << " Source D: " << IDEProblem.DtoString(edge.factAtSource()); + << " Source D: " << IDEProblem.DtoString(Edge.factAtSource()); BOOST_LOG_SEV(lg::get(), DEBUG) - << " Target N: " << IDEProblem.NtoString(edge.getTarget()); + << " Target N: " << IDEProblem.NtoString(Edge.getTarget()); BOOST_LOG_SEV(lg::get(), DEBUG) - << " Target D: " << IDEProblem.DtoString(edge.factAtTarget())); - - auto fwdLookupRes = - jumpFn->forwardLookup(edge.factAtSource(), edge.getTarget()); - if (fwdLookupRes) { - auto &ref = fwdLookupRes->get(); - if (auto Find = std::find_if(ref.begin(), ref.end(), - [edge](const auto &Pair) { - return edge.factAtTarget() == Pair.first; + << " Target D: " << IDEProblem.DtoString(Edge.factAtTarget())); + + auto FwdLookupRes = + JumpFn->forwardLookup(Edge.factAtSource(), Edge.getTarget()); + if (FwdLookupRes) { + auto &Ref = FwdLookupRes->get(); + if (auto Find = std::find_if(Ref.begin(), Ref.end(), + [Edge](const auto &Pair) { + return Edge.factAtTarget() == Pair.first; }); - Find != ref.end()) { + Find != Ref.end()) { LOG_IF_ENABLE(BOOST_LOG_SEV(lg::get(), DEBUG) << " => EdgeFn: " << Find->second->str(); BOOST_LOG_SEV(lg::get(), DEBUG) << " "); @@ -822,21 +843,23 @@ class IDESolver } } LOG_IF_ENABLE(BOOST_LOG_SEV(lg::get(), DEBUG) - << " => EdgeFn: " << allTop->str(); + << " => EdgeFn: " << AllTop->str(); BOOST_LOG_SEV(lg::get(), DEBUG) << " "); // JumpFn initialized to all-top, see line [2] in SRH96 paper - return allTop; + return AllTop; } - void addEndSummary(n_t sP, d_t d1, n_t eP, d_t d2, EdgeFunctionPtrType f) { + void addEndSummary( + n_t SP, d_t d1, n_t eP, d_t d2, // NOLINT - keep close to algorithm notion + EdgeFunctionPtrType f) { // NOLINT - keep close to algorithm notion // note: at this point we don't need to join with a potential previous f // because f is a jump function, which is already properly joined // within propagate(..) - endsummarytab.get(sP, d1).insert(eP, d2, std::move(f)); + EndsummaryTab.get(SP, d1).insert(eP, d2, std::move(f)); } // should be made a callable at some point - void pathEdgeProcessingTask(const PathEdge edge) { + void pathEdgeProcessingTask(const PathEdge Edge) { PAMM_GET_INSTANCE; INC_COUNTER("JumpFn Construction", 1, PAMM_SEVERITY_LEVEL::Full); LOG_IF_ENABLE( @@ -847,75 +870,78 @@ class IDESolver BOOST_LOG_SEV(lg::get(), DEBUG) << "Process " << PathEdgeCount << ". path edge:"; BOOST_LOG_SEV(lg::get(), DEBUG) - << "< D source: " << IDEProblem.DtoString(edge.factAtSource()) << " ;"; + << "< D source: " << IDEProblem.DtoString(Edge.factAtSource()) << " ;"; BOOST_LOG_SEV(lg::get(), DEBUG) - << " N target: " << IDEProblem.NtoString(edge.getTarget()) << " ;"; + << " N target: " << IDEProblem.NtoString(Edge.getTarget()) << " ;"; BOOST_LOG_SEV(lg::get(), DEBUG) - << " D target: " << IDEProblem.DtoString(edge.factAtTarget()) << " >"; + << " D target: " << IDEProblem.DtoString(Edge.factAtTarget()) << " >"; BOOST_LOG_SEV(lg::get(), DEBUG) << ' '); - if (!ICF->isCallSite(edge.getTarget())) { - if (ICF->isExitInst(edge.getTarget())) { - processExit(edge); + if (!ICF->isCallSite(Edge.getTarget())) { + if (ICF->isExitInst(Edge.getTarget())) { + processExit(Edge); } - if (!ICF->getSuccsOf(edge.getTarget()).empty()) { - processNormalFlow(edge); + if (!ICF->getSuccsOf(Edge.getTarget()).empty()) { + processNormalFlow(Edge); } } else { - processCall(edge); + processCall(Edge); } } // should be made a callable at some point - void valuePropagationTask(const std::pair nAndD) { - n_t n = nAndD.first; + void valuePropagationTask(const std::pair NAndD) { + n_t n = NAndD.first; // NOLINT - keep close to algorithm notion // our initial seeds are not necessarily method-start points but here they // should be treated as such the same also for unbalanced return sites in // an unbalanced problem if (ICF->isStartPoint(n) || Seeds.containsInitialSeedsFor(n) || - unbalancedRetSites.count(n)) { + UnbalancedRetSites.count(n)) { // FIXME: is currently not executed for main!!! // initial seeds are set in the global constructor, and main is also not // officially called by any other function - propagateValueAtStart(nAndD, n); + propagateValueAtStart(NAndD, n); } if (ICF->isCallSite(n)) { - propagateValueAtCall(nAndD, n); + propagateValueAtCall(NAndD, n); } } // should be made a callable at some point - void valueComputationTask(const std::vector &values) { + void valueComputationTask(const std::vector &Values) { PAMM_GET_INSTANCE; - for (n_t n : values) { - for (n_t sP : ICF->getStartPointsOf(ICF->getFunctionOf(n))) { + for (n_t n : Values) { // NOLINT - keep close to algorithm notion + for (n_t SP : ICF->getStartPointsOf(ICF->getFunctionOf(n))) { using TableCell = typename Table::Cell; - Table lookupByTarget; - lookupByTarget = jumpFn->lookupByTarget(n); - for (const TableCell &sourceValTargetValAndFunction : - lookupByTarget.cellSet()) { - d_t dPrime = sourceValTargetValAndFunction.getRowKey(); - d_t d = sourceValTargetValAndFunction.getColumnKey(); - EdgeFunctionPtrType fPrime = sourceValTargetValAndFunction.getValue(); - l_t targetVal = val(sP, dPrime); + Table LookupByTarget; + LookupByTarget = JumpFn->lookupByTarget(n); + for (const TableCell &SourceValTargetValAndFunction : + LookupByTarget.cellSet()) { + d_t dPrime // NOLINT - keep close to algorithm notion + = SourceValTargetValAndFunction.getRowKey(); + d_t d // NOLINT - keep close to algorithm notion + = SourceValTargetValAndFunction.getColumnKey(); + EdgeFunctionPtrType fPrime // NOLINT - keep close to algorithm notion + = SourceValTargetValAndFunction.getValue(); + l_t TargetVal = val(SP, dPrime); setVal(n, d, IDEProblem.join(val(n, d), - fPrime->computeTarget(std::move(targetVal)))); + fPrime->computeTarget(std::move(TargetVal)))); INC_COUNTER("Value Computation", 1, PAMM_SEVERITY_LEVEL::Full); } } } } - virtual void saveEdges(n_t sourceNode, n_t sinkStmt, d_t sourceVal, - const container_type &destVals, bool interP) { + virtual void saveEdges(n_t SourceNode, n_t SinkStmt, d_t SourceVal, + const container_type &DestVals, bool InterP) { if (!SolverConfig.recordEdges()) { return; } - Table> &tgtMap = - (interP) ? computedInterPathEdges : computedIntraPathEdges; - tgtMap.get(sourceNode, sinkStmt)[sourceVal].insert(destVals.begin(), - destVals.end()); + Table> &TgtMap = + (InterP) ? ComputedInterPathEdges : ComputedIntraPathEdges; + TgtMap.get(SourceNode, SinkStmt)[SourceVal].insert(DestVals.begin(), + DestVals.end()); } /// Computes the final values for edge functions. @@ -923,9 +949,9 @@ class IDESolver LOG_IF_ENABLE(BOOST_LOG_SEV(lg::get(), DEBUG) << "Start computing values"); // Phase II(i) std::map> AllSeeds = Seeds.getSeeds(); - for (n_t unbalancedRetSite : unbalancedRetSites) { - if (AllSeeds.find(unbalancedRetSite) == AllSeeds.end()) { - AllSeeds[unbalancedRetSite][ZeroValue] = IDEProblem.topElement(); + for (n_t UnbalancedRetSite : UnbalancedRetSites) { + if (AllSeeds.find(UnbalancedRetSite) == AllSeeds.end()) { + AllSeeds[UnbalancedRetSite][ZeroValue] = IDEProblem.topElement(); } } // do processing @@ -939,16 +965,16 @@ class IDESolver // initialize the initial seeds with the top element as we have no // information at the beginning of the value computation problem setVal(StartPoint, Fact, Value); - std::pair superGraphNode(StartPoint, Fact); - valuePropagationTask(superGraphNode); + std::pair SuperGraphNode(StartPoint, Fact); + valuePropagationTask(SuperGraphNode); } } // Phase II(ii) // we create an array of all nodes and then dispatch fractions of this // array to multiple threads - const std::set allNonCallStartNodes = ICF->allNonCallStartNodes(); + const std::set AllNonCallStartNodes = ICF->allNonCallStartNodes(); valueComputationTask( - {allNonCallStartNodes.begin(), allNonCallStartNodes.end()}); + {AllNonCallStartNodes.begin(), AllNonCallStartNodes.end()}); } /// Schedules the processing of initial seeds, initiating the analysis. @@ -999,7 +1025,7 @@ class IDESolver } propagate(Fact, StartPoint, Fact, EdgeIdentity::getInstance(), nullptr, false); - jumpFn->addFunction(Fact, StartPoint, Fact, + JumpFn->addFunction(Fact, StartPoint, Fact, EdgeIdentity::getInstance()); } } @@ -1013,72 +1039,80 @@ class IDESolver /// /// @param edge an edge whose target node resembles a method exit /// - virtual void processExit(const PathEdge edge) { + virtual void processExit(const PathEdge Edge) { PAMM_GET_INSTANCE; INC_COUNTER("Process Exit", 1, PAMM_SEVERITY_LEVEL::Full); LOG_IF_ENABLE(BOOST_LOG_SEV(lg::get(), DEBUG) << "Process exit at target: " - << IDEProblem.NtoString(edge.getTarget())); - n_t n = edge.getTarget(); // an exit node; line 21... - EdgeFunctionPtrType f = jumpFunction(edge); - f_t functionThatNeedsSummary = ICF->getFunctionOf(n); - d_t d1 = edge.factAtSource(); - d_t d2 = edge.factAtTarget(); + << IDEProblem.NtoString(Edge.getTarget())); + n_t n // NOLINT - keep close to algorithm notion + = Edge.getTarget(); // an exit node; line 21... + EdgeFunctionPtrType f // NOLINT - keep close to algorithm notion + = jumpFunction(Edge); + f_t FunctionThatNeedsSummary = ICF->getFunctionOf(n); + d_t d1 // NOLINT - keep close to algorithm notion + = Edge.factAtSource(); + d_t d2 // NOLINT - keep close to algorithm notion + = Edge.factAtTarget(); // for each of the method's start points, determine incoming calls - const std::set startPointsOf = - ICF->getStartPointsOf(functionThatNeedsSummary); - std::map inc; - for (n_t sP : startPointsOf) { + const std::set StartPointsOf = + ICF->getStartPointsOf(FunctionThatNeedsSummary); + std::map Inc; + for (n_t SP : StartPointsOf) { // line 21.1 of Naeem/Lhotak/Rodriguez // register end-summary - addEndSummary(sP, d1, n, d2, f); - for (auto entry : incoming(d1, sP)) { - inc[entry.first] = Container{entry.second}; + addEndSummary(SP, d1, n, d2, f); + for (const auto &Entry : + incoming(d1, SP)) { // FIXME: does & break the solver? + Inc[Entry.first] = Container{Entry.second}; } } printEndSummaryTab(); printIncomingTab(); // for each incoming call edge already processed //(see processCall(..)) - for (auto entry : inc) { + for (const auto &Entry : Inc) { // TODO/FIXME: does & break the solver? // line 22 - n_t c = entry.first; + n_t c // NOLINT - keep close to algorithm notion + = Entry.first; // for each return site - for (n_t retSiteC : ICF->getReturnSitesOfCallAt(c)) { + for (n_t RetSiteC : ICF->getReturnSitesOfCallAt(c)) { // compute return-flow function - FlowFunctionPtrType retFunction = - cachedFlowEdgeFunctions.getRetFlowFunction( - c, functionThatNeedsSummary, n, retSiteC); + FlowFunctionPtrType RetFunction = + CachedFlowEdgeFunctions.getRetFlowFunction( + c, FunctionThatNeedsSummary, n, RetSiteC); INC_COUNTER("FF Queries", 1, PAMM_SEVERITY_LEVEL::Full); // for each incoming-call value - for (d_t d4 : entry.second) { - const container_type targets = - computeReturnFlowFunction(retFunction, d1, d2, c, entry.second); + for (d_t d4 // NOLINT - keep close to algorithm notion + : Entry.second) { + const container_type Targets = + computeReturnFlowFunction(RetFunction, d1, d2, c, Entry.second); ADD_TO_HISTOGRAM("Data-flow facts", targets.size(), 1, PAMM_SEVERITY_LEVEL::Full); - saveEdges(n, retSiteC, d2, targets, true); + saveEdges(n, RetSiteC, d2, Targets, true); // for each target value at the return site // line 23 - for (d_t d5 : targets) { + for (d_t d5 // NOLINT - keep close to algorithm notion + : Targets) { // compute composed function // get call edge function - EdgeFunctionPtrType f4 = - cachedFlowEdgeFunctions.getCallEdgeFunction( + EdgeFunctionPtrType f4 // NOLINT - keep close to algorithm notion + = CachedFlowEdgeFunctions.getCallEdgeFunction( c, d4, ICF->getFunctionOf(n), d1); LOG_IF_ENABLE(BOOST_LOG_SEV(lg::get(), DEBUG) << "Queried Call Edge Function: " << f4->str()); // get return edge function - EdgeFunctionPtrType f5 = - cachedFlowEdgeFunctions.getReturnEdgeFunction( - c, ICF->getFunctionOf(n), n, d2, retSiteC, d5); + EdgeFunctionPtrType f5 // NOLINT - keep close to algorithm notion + = CachedFlowEdgeFunctions.getReturnEdgeFunction( + c, ICF->getFunctionOf(n), n, d2, RetSiteC, d5); LOG_IF_ENABLE(BOOST_LOG_SEV(lg::get(), DEBUG) << "Queried Return Edge Function: " << f5->str()); if (SolverConfig.emitESG()) { - for (auto sP : ICF->getStartPointsOf(ICF->getFunctionOf(n))) { - intermediateEdgeFunctions[std::make_tuple(c, d4, sP, d1)] + for (auto SP : ICF->getStartPointsOf(ICF->getFunctionOf(n))) { + IntermediateEdgeFunctions[std::make_tuple(c, d4, SP, d1)] .push_back(f4); } - intermediateEdgeFunctions[std::make_tuple(n, d2, retSiteC, d5)] + IntermediateEdgeFunctions[std::make_tuple(n, d2, RetSiteC, d5)] .push_back(f5); } INC_COUNTER("EF Queries", 2, PAMM_SEVERITY_LEVEL::Full); @@ -1088,24 +1122,32 @@ class IDESolver << " * " << f4->str(); BOOST_LOG_SEV(lg::get(), DEBUG) << " (return * function * call)"); - EdgeFunctionPtrType fPrime = f4->composeWith(f)->composeWith(f5); + EdgeFunctionPtrType + fPrime // NOLINT - keep close to algorithm notion + = f4->composeWith(f)->composeWith(f5); LOG_IF_ENABLE(BOOST_LOG_SEV(lg::get(), DEBUG) << " = " << fPrime->str(); BOOST_LOG_SEV(lg::get(), DEBUG) << ' '); // for each jump function coming into the call, propagate to // return site using the composed function - auto revLookupResult = jumpFn->reverseLookup(c, d4); - if (revLookupResult) { - for (auto valAndFunc : revLookupResult->get()) { - EdgeFunctionPtrType f3 = valAndFunc.second; - if (!f3->equal_to(allTop)) { - d_t d3 = valAndFunc.first; - d_t d5_restoredCtx = restoreContextOnReturnedFact(c, d4, d5); + auto RevLookupResult = JumpFn->reverseLookup(c, d4); + if (RevLookupResult) { + for (const auto &ValAndFunc : + RevLookupResult + ->get()) { // TODO/FIXME: does & break the solver? + EdgeFunctionPtrType + f3 // NOLINT - keep close to algorithm notion + = ValAndFunc.second; + if (!f3->equal_to(AllTop)) { + d_t d3 = // NOLINT - keep close to algorithm notion + ValAndFunc.first; + d_t d5_restoredCtx // NOLINT - keep close to algorithm notion + = restoreContextOnReturnedFact(c, d4, d5); LOG_IF_ENABLE(BOOST_LOG_SEV(lg::get(), DEBUG) << "Compose: " << fPrime->str() << " * " << f3->str(); BOOST_LOG_SEV(lg::get(), DEBUG) << ' '); - propagate(d3, retSiteC, d5_restoredCtx, + propagate(d3, RetSiteC, d5_restoredCtx, f3->composeWith(fPrime), c, false); } } @@ -1120,37 +1162,39 @@ class IDESolver // conditionally generated values should only // be propagated into callers that have an incoming edge for this // condition - if (SolverConfig.followReturnsPastSeeds() && inc.empty() && + if (SolverConfig.followReturnsPastSeeds() && Inc.empty() && IDEProblem.isZeroValue(d1)) { - const std::set callers = ICF->getCallersOf(functionThatNeedsSummary); - for (n_t c : callers) { - for (n_t retSiteC : ICF->getReturnSitesOfCallAt(c)) { - FlowFunctionPtrType retFunction = - cachedFlowEdgeFunctions.getRetFlowFunction( - c, functionThatNeedsSummary, n, retSiteC); + const std::set Callers = ICF->getCallersOf(FunctionThatNeedsSummary); + for (n_t Caller : Callers) { + for (n_t RetSiteC : ICF->getReturnSitesOfCallAt(Caller)) { + FlowFunctionPtrType RetFunction = + CachedFlowEdgeFunctions.getRetFlowFunction( + Caller, FunctionThatNeedsSummary, n, RetSiteC); INC_COUNTER("FF Queries", 1, PAMM_SEVERITY_LEVEL::Full); - const container_type targets = computeReturnFlowFunction( - retFunction, d1, d2, c, Container{ZeroValue}); + const container_type Targets = computeReturnFlowFunction( + RetFunction, d1, d2, Caller, Container{ZeroValue}); ADD_TO_HISTOGRAM("Data-flow facts", targets.size(), 1, PAMM_SEVERITY_LEVEL::Full); - saveEdges(n, retSiteC, d2, targets, true); - for (d_t d5 : targets) { - EdgeFunctionPtrType f5 = - cachedFlowEdgeFunctions.getReturnEdgeFunction( - c, ICF->getFunctionOf(n), n, d2, retSiteC, d5); + saveEdges(n, RetSiteC, d2, Targets, true); + for (d_t d5 // NOLINT - keep close to algorithm notion + : Targets) { + EdgeFunctionPtrType f5 // NOLINT - keep close to algorithm notion + = CachedFlowEdgeFunctions.getReturnEdgeFunction( + Caller, ICF->getFunctionOf(n), n, d2, RetSiteC, d5); LOG_IF_ENABLE(BOOST_LOG_SEV(lg::get(), DEBUG) << "Queried Return Edge Function: " << f5->str()); if (SolverConfig.emitESG()) { - intermediateEdgeFunctions[std::make_tuple(n, d2, retSiteC, d5)] + IntermediateEdgeFunctions[std::make_tuple(n, d2, RetSiteC, d5)] .push_back(f5); } INC_COUNTER("EF Queries", 1, PAMM_SEVERITY_LEVEL::Full); LOG_IF_ENABLE(BOOST_LOG_SEV(lg::get(), DEBUG) << "Compose: " << f5->str() << " * " << f->str(); BOOST_LOG_SEV(lg::get(), DEBUG) << ' '); - propagteUnbalancedReturnFlow(retSiteC, d5, f->composeWith(f5), c); + propagteUnbalancedReturnFlow(RetSiteC, d5, f->composeWith(f5), + Caller); // register for value processing (2nd IDE phase) - unbalancedRetSites.insert(retSiteC); + UnbalancedRetSites.insert(RetSiteC); } } } @@ -1158,21 +1202,21 @@ class IDESolver // normally not be processed at all; this might be undesirable if // the flow function has a side effect such as registering a taint; // instead we thus call the return flow function will a null caller - if (callers.empty()) { - FlowFunctionPtrType retFunction = - cachedFlowEdgeFunctions.getRetFlowFunction( - nullptr, functionThatNeedsSummary, n, nullptr); + if (Callers.empty()) { + FlowFunctionPtrType RetFunction = + CachedFlowEdgeFunctions.getRetFlowFunction( + nullptr, FunctionThatNeedsSummary, n, nullptr); INC_COUNTER("FF Queries", 1, PAMM_SEVERITY_LEVEL::Full); - retFunction->computeTargets(d2); + RetFunction->computeTargets(d2); } } } - void propagteUnbalancedReturnFlow(n_t retSiteC, d_t targetVal, - EdgeFunctionPtrType edgeFunction, - n_t relatedCallSite) { - propagate(ZeroValue, retSiteC, targetVal, std::move(edgeFunction), - relatedCallSite, true); + void propagteUnbalancedReturnFlow(n_t RetSiteC, d_t TargetVal, + EdgeFunctionPtrType EdgeFunc, + n_t RelatedCallSite) { + propagate(ZeroValue, RetSiteC, TargetVal, std::move(EdgeFunc), + RelatedCallSite, true); } /// This method will be called for each incoming edge and can be used to @@ -1187,7 +1231,10 @@ class IDESolver /// Fact that originally should be propagated to the caller. /// @return Fact that will be propagated to the caller. /// - d_t restoreContextOnReturnedFact(n_t callSite, d_t d4, d_t d5) { + d_t restoreContextOnReturnedFact( + n_t /*CallSite*/, d_t /*d4*/, + d_t d5 // NOLINT - keep close to algorithm notion + ) { // TODO support LinkedNode and JoinHandlingNode // if (d5 instanceof LinkedNode) { // ((LinkedNode) d5).setCallingContext(d4); @@ -1207,14 +1254,17 @@ class IDESolver /// @return The set of abstractions at the successor node /// container_type - computeNormalFlowFunction(const FlowFunctionPtrType &flowFunction, d_t d1, - d_t d2) { - return flowFunction->computeTargets(d2); + computeNormalFlowFunction(const FlowFunctionPtrType &FlowFunc, d_t /*d1*/, + d_t d2 // NOLINT - keep close to algorithm notion + ) { + return FlowFunc->computeTargets(d2); } container_type computeSummaryFlowFunction(const FlowFunctionPtrType &SummaryFlowFunction, - d_t d1, d_t d2) { + d_t /*d1*/, + d_t d2 // NOLINT - keep close to algorithm notion + ) { return SummaryFlowFunction->computeTargets(d2); } @@ -1225,9 +1275,11 @@ class IDESolver /// @return The set of caller-side abstractions at the callee's start node /// container_type - computeCallFlowFunction(const FlowFunctionPtrType &callFlowFunction, d_t d1, - d_t d2) { - return callFlowFunction->computeTargets(d2); + computeCallFlowFunction(const FlowFunctionPtrType &CallFlowFunction, + d_t /*d1*/, + d_t d2 // NOLINT - keep close to algorithm notion + ) { + return CallFlowFunction->computeTargets(d2); } /// Computes the call-to-return flow function for the given call-site @@ -1239,8 +1291,10 @@ class IDESolver /// @return The set of caller-side abstractions at the return site /// container_type computeCallToReturnFlowFunction( - const FlowFunctionPtrType &callToReturnFlowFunction, d_t d1, d_t d2) { - return callToReturnFlowFunction->computeTargets(d2); + const FlowFunctionPtrType &CallToReturnFlowFunction, d_t /*d1*/, + d_t d2 // NOLINT - keep close to algorithm notion + ) { + return CallToReturnFlowFunction->computeTargets(d2); } /// Computes the return flow function for the given set of caller-side @@ -1252,22 +1306,22 @@ class IDESolver /// @param callerSideDs The abstractions at the call site /// @return The set of caller-side abstractions at the return site /// - container_type - computeReturnFlowFunction(const FlowFunctionPtrType &retFunction, d_t d1, - d_t d2, n_t callSite, - const Container &callerSideDs) { - return retFunction->computeTargets(d2); + container_type computeReturnFlowFunction( + const FlowFunctionPtrType &RetFlowFunction, d_t /*d1*/, + d_t d2, // NOLINT - keep close to algorithm notion + n_t /*CallSite*/, const Container & /*CallerSideDs*/) { + return RetFlowFunction->computeTargets(d2); } /// Propagates the flow further down the exploded super graph, merging any - /// edge function that might already have been computed for targetVal at - /// target. + /// edge function that might already have been computed for TargetVal at + /// Target. /// - /// @param sourceVal the source value of the propagated summary edge - /// @param target the target statement - /// @param targetVal the target value at the target statement - /// @param f the new edge function computed from (s0,sourceVal) to - /// (target,targetVal) + /// @param SourceVal the source value of the propagated summary edge + /// @param Target the target statement + /// @param TargetVal the target value at the target statement + /// @param f the new edge function computed from (s0,SourceVal) to + /// (Target,TargetVal) /// @param relatedCallSite for call and return flows the related call /// statement, nullptr otherwise (this value is not used within this /// implementation but may be useful for subclasses of IDESolver) @@ -1275,61 +1329,64 @@ class IDESolver /// unbalanced return (this value is not used within this implementation /// but may be useful for subclasses of {@link IDESolver}) /// - void - propagate(d_t sourceVal, n_t target, d_t targetVal, - const EdgeFunctionPtrType &f, - /* deliberately exposed to clients */ n_t relatedCallSite, - /* deliberately exposed to clients */ bool isUnbalancedReturn) { + void propagate( + d_t SourceVal, n_t Target, d_t TargetVal, + const EdgeFunctionPtrType &f, // NOLINT - keep close to algorithm notion + /* deliberately exposed to clients */ + n_t /*RelatedCallSite*/, + /* deliberately exposed to clients */ + bool /*IsUnbalancedReturn*/) { LOG_IF_ENABLE(BOOST_LOG_SEV(lg::get(), DEBUG) << "Propagate flow"; BOOST_LOG_SEV(lg::get(), DEBUG) - << "Source value : " << IDEProblem.DtoString(sourceVal); + << "Source value : " << IDEProblem.DtoString(SourceVal); BOOST_LOG_SEV(lg::get(), DEBUG) - << "Target : " << IDEProblem.NtoString(target); + << "Target : " << IDEProblem.NtoString(Target); BOOST_LOG_SEV(lg::get(), DEBUG) - << "Target value : " << IDEProblem.DtoString(targetVal); + << "Target value : " << IDEProblem.DtoString(TargetVal); BOOST_LOG_SEV(lg::get(), DEBUG) << "Edge function : " << f.get()->str() << " (result of previous compose)"; BOOST_LOG_SEV(lg::get(), DEBUG) << ' '); - EdgeFunctionPtrType jumpFnE = [&]() { - const auto revLookupResult = jumpFn->reverseLookup(target, targetVal); - if (revLookupResult) { - const auto &JumpFnContainer = revLookupResult->get(); + EdgeFunctionPtrType JumpFnE = [&]() { + const auto RevLookupResult = JumpFn->reverseLookup(Target, TargetVal); + if (RevLookupResult) { + const auto &JumpFnContainer = RevLookupResult->get(); const auto Find = std::find_if( JumpFnContainer.begin(), JumpFnContainer.end(), - [sourceVal](auto &KVpair) { return KVpair.first == sourceVal; }); + [SourceVal](auto &KVpair) { return KVpair.first == SourceVal; }); if (Find != JumpFnContainer.end()) { return Find->second; } } // jump function is initialized to all-top if no entry was found - return allTop; + return AllTop; }(); - EdgeFunctionPtrType fPrime = jumpFnE->joinWith(f); - bool newFunction = !(fPrime->equal_to(jumpFnE)); + EdgeFunctionPtrType fPrime // NOLINT - keep close to algorithm notion + = JumpFnE->joinWith(f); + bool NewFunction = !(fPrime->equal_to(JumpFnE)); LOG_IF_ENABLE(BOOST_LOG_SEV(lg::get(), DEBUG) - << "Join: " << jumpFnE->str() << " & " << f.get()->str() - << (jumpFnE->equal_to(f) ? " (EF's are equal)" : " "); + << "Join: " << JumpFnE->str() << " & " << f.get()->str() + << (JumpFnE->equal_to(f) ? " (EF's are equal)" : " "); BOOST_LOG_SEV(lg::get(), DEBUG) << " = " << fPrime->str() - << (newFunction ? " (new jump func)" : " "); + << (NewFunction ? " (new jump func)" : " "); BOOST_LOG_SEV(lg::get(), DEBUG) << ' '); - if (newFunction) { - jumpFn->addFunction(sourceVal, target, targetVal, fPrime); - const PathEdge edge(sourceVal, target, targetVal); + if (NewFunction) { + JumpFn->addFunction(SourceVal, Target, TargetVal, fPrime); + const PathEdge Edge(SourceVal, Target, TargetVal); PathEdgeCount++; - pathEdgeProcessingTask(edge); + pathEdgeProcessingTask(Edge); - LOG_IF_ENABLE(if (!IDEProblem.isZeroValue(targetVal)) { + LOG_IF_ENABLE(if (!IDEProblem.isZeroValue(TargetVal)) { BOOST_LOG_SEV(lg::get(), DEBUG) - << "EDGE: getFunction()->getName().str() - << ", D: " << IDEProblem.DtoString(sourceVal) << '>'; + << "EDGE: getFunction()->getName().str() + << ", D: " << IDEProblem.DtoString(SourceVal) << '>'; BOOST_LOG_SEV(lg::get(), DEBUG) - << " ---> str() << '>'; BOOST_LOG_SEV(lg::get(), DEBUG) << ' '; }); @@ -1339,47 +1396,58 @@ class IDESolver } } - l_t joinValueAt(n_t unit, d_t fact, l_t curr, l_t newVal) { - return IDEProblem.join(std::move(curr), std::move(newVal)); + l_t joinValueAt(n_t /*Unit*/, d_t /*Fact*/, l_t Curr, l_t NewVal) { + return IDEProblem.join(std::move(Curr), std::move(NewVal)); } std::set::Cell> - endSummary(n_t sP, d_t d3) { + endSummary(n_t SP, + d_t d3 // NOLINT - keep close to algorithm notion + ) { if constexpr (PAMM_CURR_SEV_LEVEL >= PAMM_SEVERITY_LEVEL::Core) { - auto key = std::make_pair(sP, d3); - auto findND = fSummaryReuse.find(key); - if (findND == fSummaryReuse.end()) { - fSummaryReuse.emplace(key, 0); + auto Key = std::make_pair(SP, d3); + auto FindND = FSummaryReuse.find(Key); + if (FindND == FSummaryReuse.end()) { + FSummaryReuse.emplace(Key, 0); } else { - fSummaryReuse[key] += 1; + FSummaryReuse[Key] += 1; } } - return endsummarytab.get(sP, d3).cellSet(); + return EndsummaryTab.get(SP, d3).cellSet(); } - std::map incoming(d_t d1, n_t sP) { - return incomingtab.get(sP, d1); + std::map + incoming(d_t d1, // NOLINT - keep close to algorithm notion + n_t SP) { + return IncomingTab.get(SP, d1); } - void addIncoming(n_t sP, d_t d3, n_t n, d_t d2) { - incomingtab.get(sP, d3)[n].insert(d2); + void addIncoming(n_t SP, + d_t d3, // NOLINT - keep close to algorithm notion + n_t n, // NOLINT - keep close to algorithm notion + d_t d2 // NOLINT - keep close to algorithm notion + ) { + IncomingTab.get(SP, d3)[n].insert(d2); } void printIncomingTab() const { #ifdef DYNAMIC_LOG if (boost::log::core::get()->get_logging_enabled()) { BOOST_LOG_SEV(lg::get(), DEBUG) << "Start of incomingtab entry"; - for (auto cell : incomingtab.cellSet()) { + for (const auto &Cell : + IncomingTab.cellSet()) { // TODO/FIXME: does & break the solver? BOOST_LOG_SEV(lg::get(), DEBUG) - << "sP: " << IDEProblem.NtoString(cell.getRowKey()); + << "sP: " << IDEProblem.NtoString(Cell.getRowKey()); BOOST_LOG_SEV(lg::get(), DEBUG) - << "d3: " << IDEProblem.DtoString(cell.getColumnKey()); - for (auto entry : cell.getValue()) { + << "d3: " << IDEProblem.DtoString(Cell.getColumnKey()); + for (const auto &Entry : + Cell.getValue()) { // TODO/FIXME: does & break the solver? BOOST_LOG_SEV(lg::get(), DEBUG) - << " n: " << IDEProblem.NtoString(entry.first); - for (auto fact : entry.second) { + << " n: " << IDEProblem.NtoString(Entry.first); + for (const auto &Fact : + Entry.second) { // TODO/FIXME: does & break the solver? BOOST_LOG_SEV(lg::get(), DEBUG) - << " d2: " << IDEProblem.DtoString(fact); + << " d2: " << IDEProblem.DtoString(Fact); } } BOOST_LOG_SEV(lg::get(), DEBUG) << "---------------"; @@ -1394,18 +1462,21 @@ class IDESolver #ifdef DYNAMIC_LOG if (boost::log::core::get()->get_logging_enabled()) { BOOST_LOG_SEV(lg::get(), DEBUG) << "Start of endsummarytab entry"; - for (auto cell : endsummarytab.cellVec()) { + for (const auto &Cell : + EndsummaryTab.cellVec()) { // TODO/FIXME: does & break the solver? BOOST_LOG_SEV(lg::get(), DEBUG) - << "sP: " << IDEProblem.NtoString(cell.getRowKey()); + << "sP: " << IDEProblem.NtoString(Cell.getRowKey()); BOOST_LOG_SEV(lg::get(), DEBUG) - << "d1: " << IDEProblem.DtoString(cell.getColumnKey()); - for (auto inner_cell : cell.getValue().cellVec()) { + << "d1: " << IDEProblem.DtoString(Cell.getColumnKey()); + for (const auto &InnerCell : + Cell.getValue() + .cellVec()) { // TODO/FIXME: does & break the solver? BOOST_LOG_SEV(lg::get(), DEBUG) - << " eP: " << IDEProblem.NtoString(inner_cell.getRowKey()); + << " eP: " << IDEProblem.NtoString(InnerCell.getRowKey()); BOOST_LOG_SEV(lg::get(), DEBUG) - << " d2: " << IDEProblem.DtoString(inner_cell.getColumnKey()); + << " d2: " << IDEProblem.DtoString(InnerCell.getColumnKey()); BOOST_LOG_SEV(lg::get(), DEBUG) - << " EF: " << inner_cell.getValue()->str(); + << " EF: " << InnerCell.getValue()->str(); BOOST_LOG_SEV(lg::get(), DEBUG) << ' '; } BOOST_LOG_SEV(lg::get(), DEBUG) << "---------------"; @@ -1424,18 +1495,18 @@ class IDESolver << "\n**********************************************************\n"; // Sort intra-procedural path edges - auto cells = computedIntraPathEdges.cellVec(); - StmtLess stmtless(ICF); - sort(cells.begin(), cells.end(), [&stmtless](auto a, auto b) { - return stmtless(a.getRowKey(), b.getRowKey()); + auto Cells = ComputedIntraPathEdges.cellVec(); + StmtLess Stmtless(ICF); + sort(Cells.begin(), Cells.end(), [&Stmtless](auto Lhs, auto Rhs) { + return Stmtless(Lhs.getRowKey(), Rhs.getRowKey()); }); - for (auto cell : cells) { - auto Edge = std::make_pair(cell.getRowKey(), cell.getColumnKey()); - std::string n2_label = IDEProblem.NtoString(Edge.second); + for (const auto &Cell : Cells) { // TODO/FIXME: does & break the solver? + auto Edge = std::make_pair(Cell.getRowKey(), Cell.getColumnKey()); + std::string N2Label = IDEProblem.NtoString(Edge.second); std::cout << "\nN1: " << IDEProblem.NtoString(Edge.first) << '\n' - << "N2: " << n2_label << "\n----" - << std::string(n2_label.size(), '-') << '\n'; - for (auto D1ToD2Set : cell.getValue()) { + << "N2: " << N2Label << "\n----" + << std::string(N2Label.size(), '-') << '\n'; + for (auto D1ToD2Set : Cell.getValue()) { auto D1Fact = D1ToD2Set.first; std::cout << "D1: " << IDEProblem.DtoString(D1Fact) << '\n'; for (auto D2Fact : D1ToD2Set.second) { @@ -1451,17 +1522,17 @@ class IDESolver << "\n**********************************************************\n"; // Sort intra-procedural path edges - cells = computedInterPathEdges.cellVec(); - sort(cells.begin(), cells.end(), [&stmtless](auto a, auto b) { - return stmtless(a.getRowKey(), b.getRowKey()); + Cells = ComputedInterPathEdges.cellVec(); + sort(Cells.begin(), Cells.end(), [&Stmtless](auto Lhs, auto Rhs) { + return Stmtless(Lhs.getRowKey(), Rhs.getRowKey()); }); - for (auto cell : cells) { - auto Edge = std::make_pair(cell.getRowKey(), cell.getColumnKey()); - std::string n2_label = IDEProblem.NtoString(Edge.second); + for (const auto &Cell : Cells) { // TODO/FIXME: does & break the solver? + auto Edge = std::make_pair(Cell.getRowKey(), Cell.getColumnKey()); + std::string N2Label = IDEProblem.NtoString(Edge.second); std::cout << "\nN1: " << IDEProblem.NtoString(Edge.first) << '\n' - << "N2: " << n2_label << "\n----" - << std::string(n2_label.size(), '-') << '\n'; - for (auto D1ToD2Set : cell.getValue()) { + << "N2: " << N2Label << "\n----" + << std::string(N2Label.size(), '-') << '\n'; + for (auto D1ToD2Set : Cell.getValue()) { auto D1Fact = D1ToD2Set.first; std::cout << "D1: " << IDEProblem.DtoString(D1Fact) << '\n'; for (auto D2Fact : D1ToD2Set.second) { @@ -1499,13 +1570,15 @@ class IDESolver // d1 --> d2-Set // Case 1: d1 in d2-Set // Case 2: d1 not in d2-Set, i.e., d1 was killed. d2-Set could be empty. - for (auto cell : computedIntraPathEdges.cellSet()) { - auto Edge = std::make_pair(cell.getRowKey(), cell.getColumnKey()); + for (const auto &Cell : + ComputedIntraPathEdges + .cellSet()) { // TODO/FIXME: does & break the solver? + auto Edge = std::make_pair(Cell.getRowKey(), Cell.getColumnKey()); LOG_IF_ENABLE(BOOST_LOG_SEV(lg::get(), DEBUG) << "N1: " << IDEProblem.NtoString(Edge.first); BOOST_LOG_SEV(lg::get(), DEBUG) << "N2: " << IDEProblem.NtoString(Edge.second)); - for (auto &[D1, D2s] : cell.getValue()) { + for (auto &[D1, D2s] : Cell.getValue()) { LOG_IF_ENABLE(BOOST_LOG_SEV(lg::get(), DEBUG) << "d1: " << IDEProblem.DtoString(D1)); NumIntraPathEdges += D2s.size(); @@ -1540,8 +1613,10 @@ class IDESolver LOG_IF_ENABLE(BOOST_LOG_SEV(lg::get(), DEBUG) << "=============================================="; BOOST_LOG_SEV(lg::get(), DEBUG) << "INTER PATH EDGES"); - for (auto cell : computedInterPathEdges.cellSet()) { - auto Edge = std::make_pair(cell.getRowKey(), cell.getColumnKey()); + for (const auto &Cell : + ComputedInterPathEdges + .cellSet()) { // TODO/FIXME: does & break the solver? + auto Edge = std::make_pair(Cell.getRowKey(), Cell.getColumnKey()); LOG_IF_ENABLE(BOOST_LOG_SEV(lg::get(), DEBUG) << "N1: " << IDEProblem.NtoString(Edge.first); BOOST_LOG_SEV(lg::get(), DEBUG) @@ -1561,7 +1636,7 @@ class IDESolver // Special Case: Summary was applied for a particular call // Process the summary's #gen and #kill. if (ICF->isCallSite(Edge.first)) { - for (auto &[D1, D2s] : cell.getValue()) { + for (auto &[D1, D2s] : Cell.getValue()) { LOG_IF_ENABLE(BOOST_LOG_SEV(lg::get(), DEBUG) << "d1: " << IDEProblem.DtoString(D1)); NumInterPathEdges += D2s.size(); @@ -1573,7 +1648,7 @@ class IDESolver if (ProcessSummaryFacts.find(std::make_pair(Edge.second, D2)) != ProcessSummaryFacts.end()) { std::multiset SummaryDMultiSet = - endsummarytab.get(Edge.second, D2).columnKeySet(); + EndsummaryTab.get(Edge.second, D2).columnKeySet(); // remove duplicates from multiset std::set SummaryDSet(SummaryDMultiSet.begin(), SummaryDMultiSet.end()); @@ -1603,8 +1678,8 @@ class IDESolver // caller will count as a kill. If an actual new fact is propagated to // the caller, we have to increase the number of generated facts by one. // Zero value does not count towards generated/killed facts. - if (ICF->isExitInst(cell.getRowKey())) { - for (auto &[D1, D2s] : cell.getValue()) { + if (ICF->isExitInst(Cell.getRowKey())) { + for (auto &[D1, D2s] : Cell.getValue()) { LOG_IF_ENABLE(BOOST_LOG_SEV(lg::get(), DEBUG) << "d1: " << IDEProblem.DtoString(D1)); NumInterPathEdges += D2s.size(); @@ -1627,14 +1702,15 @@ class IDESolver } LOG_IF_ENABLE(BOOST_LOG_SEV(lg::get(), DEBUG) << "SUMMARY REUSE"); std::size_t TotalSummaryReuse = 0; - for (auto entry : fSummaryReuse) { + for (const auto &Entry : + FSummaryReuse) { // TODO/FIXME: does & break the solver? LOG_IF_ENABLE(BOOST_LOG_SEV(lg::get(), DEBUG) - << "N1: " << IDEProblem.NtoString(entry.first.first); + << "N1: " << IDEProblem.NtoString(Entry.first.first); BOOST_LOG_SEV(lg::get(), DEBUG) - << "D1: " << IDEProblem.DtoString(entry.first.second); + << "D1: " << IDEProblem.DtoString(Entry.first.second); BOOST_LOG_SEV(lg::get(), DEBUG) - << "#Reuse: " << entry.second); - TotalSummaryReuse += entry.second; + << "#Reuse: " << Entry.second); + TotalSummaryReuse += Entry.second; } INC_COUNTER("Gen facts", NumGenFacts, PAMM_SEVERITY_LEVEL::Core); INC_COUNTER("Kill facts", NumKillFacts, PAMM_SEVERITY_LEVEL::Core); @@ -1680,7 +1756,7 @@ class IDESolver << "Phase II duration: " << PRINT_TIMER("DFA Phase II"); BOOST_LOG_SEV(lg::get(), INFO) << "----------------------------------------------"); - cachedFlowEdgeFunctions.print(); + CachedFlowEdgeFunctions.print(); } } @@ -1701,65 +1777,66 @@ class IDESolver DOTFunctionSubGraph *FG = nullptr; // Sort intra-procedural path edges - auto cells = computedIntraPathEdges.cellVec(); - StmtLess stmtless(ICF); - sort(cells.begin(), cells.end(), [&stmtless](auto a, auto b) { - return stmtless(a.getRowKey(), b.getRowKey()); + auto Cells = ComputedIntraPathEdges.cellVec(); + StmtLess Stmtless(ICF); + sort(Cells.begin(), Cells.end(), [&Stmtless](auto Lhs, auto Rhs) { + return Stmtless(Lhs.getRowKey(), Rhs.getRowKey()); }); - for (auto cell : cells) { - auto Edge = std::make_pair(cell.getRowKey(), cell.getColumnKey()); - std::string n1_label = IDEProblem.NtoString(Edge.first); - std::string n2_label = IDEProblem.NtoString(Edge.second); - LOG_IF_ENABLE(BOOST_LOG_SEV(lg::get(), DEBUG) << "N1: " << n1_label; - BOOST_LOG_SEV(lg::get(), DEBUG) << "N2: " << n2_label); - std::string n1_stmtId = ICF->getStatementId(Edge.first); - std::string n2_stmtId = ICF->getStatementId(Edge.second); - std::string fnName = ICF->getFunctionOf(Edge.first)->getName().str(); + for (const auto &Cell : Cells) { // TODO/FIXME: does & break the solver? + auto Edge = std::make_pair(Cell.getRowKey(), Cell.getColumnKey()); + std::string N1Label = IDEProblem.NtoString(Edge.first); + std::string N2Label = IDEProblem.NtoString(Edge.second); + LOG_IF_ENABLE(BOOST_LOG_SEV(lg::get(), DEBUG) << "N1: " << N1Label; + BOOST_LOG_SEV(lg::get(), DEBUG) << "N2: " << N2Label); + std::string N1StmtId = ICF->getStatementId(Edge.first); + std::string N2StmtId = ICF->getStatementId(Edge.second); + std::string FuncName = ICF->getFunctionOf(Edge.first)->getName().str(); // Get or create function subgraph - if (!FG || FG->id != fnName) { - FG = &G.functions[fnName]; - FG->id = fnName; + if (!FG || FG->Id != FuncName) { + FG = &G.Functions[FuncName]; + FG->Id = FuncName; } // Create control flow nodes - DOTNode N1(fnName, n1_label, n1_stmtId); - DOTNode N2(fnName, n2_label, n2_stmtId); + DOTNode N1(FuncName, N1Label, N1StmtId); + DOTNode N2(FuncName, N2Label, N2StmtId); // Add control flow node(s) to function subgraph - FG->stmts.insert(N1); + FG->Stmts.insert(N1); if (ICF->isExitInst(Edge.second)) { - FG->stmts.insert(N2); + FG->Stmts.insert(N2); } // Set control flow edge - FG->intraCFEdges.emplace(N1, N2); + FG->IntraCFEdges.emplace(N1, N2); - DOTFactSubGraph *D1_FSG = nullptr; + DOTFactSubGraph *D1FSG = nullptr; unsigned D1FactId = 0; unsigned D2FactId = 0; - for (auto D1ToD2Set : cell.getValue()) { + for (const auto &D1ToD2Set : + Cell.getValue()) { // TODO/FIXME: does & break the solver? auto D1Fact = D1ToD2Set.first; LOG_IF_ENABLE(BOOST_LOG_SEV(lg::get(), DEBUG) << "d1: " << IDEProblem.DtoString(D1Fact)); DOTNode D1; if (IDEProblem.isZeroValue(D1Fact)) { - D1 = {fnName, "Λ", n1_stmtId, 0, false, true}; + D1 = {FuncName, "Λ", N1StmtId, 0, false, true}; D1FactId = 0; } else { // Get the fact-ID D1FactId = G.getFactID(D1Fact); - std::string d1_label = IDEProblem.DtoString(D1Fact); + std::string D1Label = IDEProblem.DtoString(D1Fact); // Get or create the fact subgraph - D1_FSG = FG->getOrCreateFactSG(D1FactId, d1_label); + D1FSG = FG->getOrCreateFactSG(D1FactId, D1Label); // Insert D1 to fact subgraph - D1 = {fnName, d1_label, n1_stmtId, D1FactId, false, true}; - D1_FSG->nodes.insert(std::make_pair(n1_stmtId, D1)); + D1 = {FuncName, D1Label, N1StmtId, D1FactId, false, true}; + D1FSG->Nodes.insert(std::make_pair(N1StmtId, D1)); } - DOTFactSubGraph *D2_FSG = nullptr; - for (auto D2Fact : D1ToD2Set.second) { + DOTFactSubGraph *D2FSG = nullptr; + for (const auto &D2Fact : D1ToD2Set.second) { LOG_IF_ENABLE(BOOST_LOG_SEV(lg::get(), DEBUG) << "d2: " << IDEProblem.DtoString(D2Fact)); // We do not need to generate any intra-procedural nodes and edges @@ -1767,26 +1844,26 @@ class IDESolver if (!IDEProblem.isZeroValue(D2Fact)) { // Get the fact-ID D2FactId = G.getFactID(D2Fact); - std::string d2_label = IDEProblem.DtoString(D2Fact); - DOTNode D2 = {fnName, d2_label, n2_stmtId, D2FactId, false, true}; + std::string D2Label = IDEProblem.DtoString(D2Fact); + DOTNode D2 = {FuncName, D2Label, N2StmtId, D2FactId, false, true}; std::string EFLabel; - auto EFVec = intermediateEdgeFunctions[std::make_tuple( + auto EFVec = IntermediateEdgeFunctions[std::make_tuple( Edge.first, D1Fact, Edge.second, D2Fact)]; - for (auto EF : EFVec) { + for (const auto &EF : EFVec) { EFLabel += EF->str() + ", "; } LOG_IF_ENABLE(BOOST_LOG_SEV(lg::get(), DEBUG) << "EF LABEL: " << EFLabel); if (D1FactId == D2FactId && !IDEProblem.isZeroValue(D1Fact)) { - assert(D1_FSG && "D1_FSG was nullptr but should be valid."); - D1_FSG->nodes.insert(std::make_pair(n2_stmtId, D2)); - D1_FSG->edges.emplace(D1, D2, true, EFLabel); + assert(D1FSG && "D1_FSG was nullptr but should be valid."); + D1FSG->Nodes.insert(std::make_pair(N2StmtId, D2)); + D1FSG->Edges.emplace(D1, D2, true, EFLabel); } else { // Get or create the fact subgraph - D2_FSG = FG->getOrCreateFactSG(D2FactId, d2_label); + D2FSG = FG->getOrCreateFactSG(D2FactId, D2Label); - D2_FSG->nodes.insert(std::make_pair(n2_stmtId, D2)); - FG->crossFactEdges.emplace(D1, D2, true, EFLabel); + D2FSG->Nodes.insert(std::make_pair(N2StmtId, D2)); + FG->CrossFactEdges.emplace(D1, D2, true, EFLabel); } } } @@ -1801,111 +1878,111 @@ class IDESolver << "Process inter-procedural path edges"; BOOST_LOG_SEV(lg::get(), DEBUG) << "============================================="); - cells = computedInterPathEdges.cellVec(); - sort(cells.begin(), cells.end(), [&stmtless](auto a, auto b) { - return stmtless(a.getRowKey(), b.getRowKey()); + Cells = ComputedInterPathEdges.cellVec(); + sort(Cells.begin(), Cells.end(), [&Stmtless](auto Lhs, auto Rhs) { + return Stmtless(Lhs.getRowKey(), Rhs.getRowKey()); }); - for (auto cell : cells) { - auto Edge = std::make_pair(cell.getRowKey(), cell.getColumnKey()); - std::string n1_label = IDEProblem.NtoString(Edge.first); - std::string n2_label = IDEProblem.NtoString(Edge.second); - std::string fNameOfN1 = ICF->getFunctionOf(Edge.first)->getName().str(); - std::string fNameOfN2 = ICF->getFunctionOf(Edge.second)->getName().str(); - std::string n1_stmtId = ICF->getStatementId(Edge.first); - std::string n2_stmtId = ICF->getStatementId(Edge.second); - LOG_IF_ENABLE(BOOST_LOG_SEV(lg::get(), DEBUG) << "N1: " << n1_label; - BOOST_LOG_SEV(lg::get(), DEBUG) << "N2: " << n2_label); + for (const auto &Cell : Cells) { // TODO/FIXME: does & break the solver? + auto Edge = std::make_pair(Cell.getRowKey(), Cell.getColumnKey()); + std::string N1Label = IDEProblem.NtoString(Edge.first); + std::string N2Label = IDEProblem.NtoString(Edge.second); + std::string FNameOfN1 = ICF->getFunctionOf(Edge.first)->getName().str(); + std::string FNameOfN2 = ICF->getFunctionOf(Edge.second)->getName().str(); + std::string N1StmtId = ICF->getStatementId(Edge.first); + std::string N2StmtId = ICF->getStatementId(Edge.second); + LOG_IF_ENABLE(BOOST_LOG_SEV(lg::get(), DEBUG) << "N1: " << N1Label; + BOOST_LOG_SEV(lg::get(), DEBUG) << "N2: " << N2Label); // Add inter-procedural control flow edge - DOTNode N1(fNameOfN1, n1_label, n1_stmtId); - DOTNode N2(fNameOfN2, n2_label, n2_stmtId); + DOTNode N1(FNameOfN1, N1Label, N1StmtId); + DOTNode N2(FNameOfN2, N2Label, N2StmtId); // Handle recursion control flow as intra-procedural control flow // since those eges never leave the function subgraph FG = nullptr; - if (fNameOfN1 == fNameOfN2) { + if (FNameOfN1 == FNameOfN2) { // This function subgraph is guaranteed to exist - FG = &G.functions[fNameOfN1]; - FG->intraCFEdges.emplace(N1, N2); + FG = &G.Functions[FNameOfN1]; + FG->IntraCFEdges.emplace(N1, N2); } else { // Check the case where the callee is a single statement function, // thus does not contain intra-procedural path edges. We have to // generate the function sub graph here! - if (!G.functions.count(fNameOfN1)) { - FG = &G.functions[fNameOfN1]; - FG->id = fNameOfN1; - FG->stmts.insert(N1); - } else if (!G.functions.count(fNameOfN2)) { - FG = &G.functions[fNameOfN2]; - FG->id = fNameOfN2; - FG->stmts.insert(N2); + if (!G.Functions.count(FNameOfN1)) { + FG = &G.Functions[FNameOfN1]; + FG->Id = FNameOfN1; + FG->Stmts.insert(N1); + } else if (!G.Functions.count(FNameOfN2)) { + FG = &G.Functions[FNameOfN2]; + FG->Id = FNameOfN2; + FG->Stmts.insert(N2); } - G.interCFEdges.emplace(N1, N2); + G.InterCFEdges.emplace(N1, N2); } // Create D1 and D2, if D1 == D2 == lambda then add Edge(D1, D2) to // interLambdaEges otherwise add Edge(D1, D2) to interFactEdges unsigned D1FactId = 0; unsigned D2FactId = 0; - for (auto D1ToD2Set : cell.getValue()) { + for (const auto &D1ToD2Set : Cell.getValue()) { auto D1Fact = D1ToD2Set.first; LOG_IF_ENABLE(BOOST_LOG_SEV(lg::get(), DEBUG) << "d1: " << IDEProblem.DtoString(D1Fact)); DOTNode D1; if (IDEProblem.isZeroValue(D1Fact)) { - D1 = {fNameOfN1, "Λ", n1_stmtId, 0, false, true}; + D1 = {FNameOfN1, "Λ", N1StmtId, 0, false, true}; } else { // Get the fact-ID D1FactId = G.getFactID(D1Fact); - std::string d1_label = IDEProblem.DtoString(D1Fact); - D1 = {fNameOfN1, d1_label, n1_stmtId, D1FactId, false, true}; + std::string D1Label = IDEProblem.DtoString(D1Fact); + D1 = {FNameOfN1, D1Label, N1StmtId, D1FactId, false, true}; // FG should already exist even for single statement functions - if (!G.containsFactSG(fNameOfN1, D1FactId)) { - FG = &G.functions[fNameOfN1]; - auto *D1_FSG = FG->getOrCreateFactSG(D1FactId, d1_label); - D1_FSG->nodes.insert(std::make_pair(n1_stmtId, D1)); + if (!G.containsFactSG(FNameOfN1, D1FactId)) { + FG = &G.Functions[FNameOfN1]; + auto *D1FSG = FG->getOrCreateFactSG(D1FactId, D1Label); + D1FSG->Nodes.insert(std::make_pair(N1StmtId, D1)); } } auto D2Set = D1ToD2Set.second; - for (auto D2Fact : D2Set) { + for (const auto &D2Fact : D2Set) { LOG_IF_ENABLE(BOOST_LOG_SEV(lg::get(), DEBUG) << "d2: " << IDEProblem.DtoString(D2Fact)); DOTNode D2; if (IDEProblem.isZeroValue(D2Fact)) { - D2 = {fNameOfN2, "Λ", n2_stmtId, 0, false, true}; + D2 = {FNameOfN2, "Λ", N2StmtId, 0, false, true}; } else { // Get the fact-ID D2FactId = G.getFactID(D2Fact); - std::string d2_label = IDEProblem.DtoString(D2Fact); - D2 = {fNameOfN2, d2_label, n2_stmtId, D2FactId, false, true}; + std::string D2Label = IDEProblem.DtoString(D2Fact); + D2 = {FNameOfN2, D2Label, N2StmtId, D2FactId, false, true}; // FG should already exist even for single statement functions - if (!G.containsFactSG(fNameOfN2, D2FactId)) { - FG = &G.functions[fNameOfN2]; - auto *D2_FSG = FG->getOrCreateFactSG(D2FactId, d2_label); - D2_FSG->nodes.insert(std::make_pair(n2_stmtId, D2)); + if (!G.containsFactSG(FNameOfN2, D2FactId)) { + FG = &G.Functions[FNameOfN2]; + auto *D2FSG = FG->getOrCreateFactSG(D2FactId, D2Label); + D2FSG->Nodes.insert(std::make_pair(N2StmtId, D2)); } } if (IDEProblem.isZeroValue(D1Fact) && IDEProblem.isZeroValue(D2Fact)) { // Do not add lambda recursion edges as inter-procedural edges - if (D1.funcName != D2.funcName) { - G.interLambdaEdges.emplace(D1, D2, true, "AllBottom", "BOT"); + if (D1.FuncName != D2.FuncName) { + G.InterLambdaEdges.emplace(D1, D2, true, "AllBottom", "BOT"); } } else { // std::string EFLabel = EF ? EF->str() : " "; std::string EFLabel; - auto EFVec = intermediateEdgeFunctions[std::make_tuple( + auto EFVec = IntermediateEdgeFunctions[std::make_tuple( Edge.first, D1Fact, Edge.second, D2Fact)]; - for (auto EF : EFVec) { + for (const auto &EF : EFVec) { LOG_IF_ENABLE(BOOST_LOG_SEV(lg::get(), DEBUG) << "Partial EF Label: " << EF->str()); EFLabel.append(EF->str() + ", "); } LOG_IF_ENABLE(BOOST_LOG_SEV(lg::get(), DEBUG) << "EF LABEL: " << EFLabel); - G.interFactEdges.emplace(D1, D2, true, EFLabel); + G.InterFactEdges.emplace(D1, D2, true, EFLabel); } } LOG_IF_ENABLE(BOOST_LOG_SEV(lg::get(), DEBUG) << "----------"); @@ -1918,20 +1995,19 @@ class IDESolver /// @brief: Allows less-than comparison based on the statement ID. struct StmtLess { const i_t *ICF; - stringIDLess strIDLess; - StmtLess(const i_t *ICF) : ICF(ICF), strIDLess(stringIDLess()) {} - bool operator()(n_t lhs, n_t rhs) { - return strIDLess(ICF->getStatementId(lhs), ICF->getStatementId(rhs)); + StringIDLess StrIDLess; + StmtLess(const i_t *ICF) : ICF(ICF), StrIDLess(StringIDLess()) {} + bool operator()(n_t Lhs, n_t Rhs) { + return StrIDLess(ICF->getStatementId(Lhs), ICF->getStatementId(Rhs)); } }; }; template -std::ostream & -operator<<(std::ostream &os, - const IDESolver &ide_solver) { - ide_solver.dumpResults(os); - return os; +std::ostream &operator<<(std::ostream &OS, + const IDESolver &Solver) { + Solver.dumpResults(OS); + return OS; } template diff --git a/include/phasar/PhasarLLVM/DataFlowSolver/IfdsIde/Solver/IDESummaryGenerator.h b/include/phasar/PhasarLLVM/DataFlowSolver/IfdsIde/Solver/IDESummaryGenerator.h index f6fa78ef7f..ad4657160b 100644 --- a/include/phasar/PhasarLLVM/DataFlowSolver/IfdsIde/Solver/IDESummaryGenerator.h +++ b/include/phasar/PhasarLLVM/DataFlowSolver/IfdsIde/Solver/IDESummaryGenerator.h @@ -29,17 +29,17 @@ template class IDESummaryGenerator { protected: - const std::string toSummarize; - const I icfg; + const std::string ToSummarize; + const I ICFG; const SummaryGenerationStrategy CTXStrategy; class CTXFunctionProblem : public ConcreteTabulationProblem { public: - const N start; - std::set facts; + const N Start; + std::set Facts; - CTXFunctionProblem(N start, std::set facts, I icfg) - : ConcreteTabulationProblem(icfg), start(start), facts(facts) { + CTXFunctionProblem(N Start, std::set Facts, I ICFG) + : ConcreteTabulationProblem(ICFG), Start(Start), Facts(Facts) { this->solver_config.followReturnsPastSeeds = false; this->solver_config.autoAddZero = true; this->solver_config.computeValues = true; @@ -47,17 +47,17 @@ class IDESummaryGenerator { this->solver_config.computePersistedSummaries = false; } - virtual std::map> initialSeeds() override { - std::map> seeds; - seeds.insert(make_pair(start, facts)); - return seeds; + std::map> initialSeeds() override { + std::map> Seeds; + Seeds.insert({Start, Facts}); + return Seeds; } }; public: IDESummaryGenerator(std::string Function, I Icfg, SummaryGenerationStrategy Strategy) - : toSummarize(Function), icfg(Icfg), CTXStrategy(Strategy) {} + : ToSummarize(std::move(Function)), ICFG(Icfg), CTXStrategy(Strategy) {} virtual ~IDESummaryGenerator() = default; void generateSummaries() { // initialize the input combinations that should be considered diff --git a/include/phasar/PhasarLLVM/DataFlowSolver/IfdsIde/Solver/IFDSSolver.h b/include/phasar/PhasarLLVM/DataFlowSolver/IfdsIde/Solver/IFDSSolver.h index a6ac445d8b..d42a7537d1 100644 --- a/include/phasar/PhasarLLVM/DataFlowSolver/IfdsIde/Solver/IFDSSolver.h +++ b/include/phasar/PhasarLLVM/DataFlowSolver/IfdsIde/Solver/IFDSSolver.h @@ -48,7 +48,7 @@ class IFDSSolver : public IDESolver> { [[nodiscard]] virtual std::set ifdsResultsAt(N Inst) { std::set KeySet; std::unordered_map ResultMap = this->resultsAt(Inst); - for (auto FlowFact : ResultMap) { + for (const auto &FlowFact : ResultMap) { KeySet.insert(FlowFact.first); } return KeySet; @@ -74,18 +74,18 @@ class IFDSSolver : public IDESolver> { std::is_same_v, llvm::Instruction *>, std::set> ifdsResultsAtInLLVMSSA(NTy Inst) { - auto getResultMap = [this, Inst]() { - if (Inst->getType()->isVoidTy()) { - return this->resultsAt(Inst); - } else { - // In this case we have a value on the left-hand side and must return - // the results at the successor instruction. Note that terminator - // instructions are always of void type. - assert(Inst->getNextNode() && - "Expected to find a valid successor node!"); - return this->resultsAt(Inst->getNextNode()); - } - }; + auto getResultMap // NOLINT + = [this, Inst]() { + if (Inst->getType()->isVoidTy()) { + return this->resultsAt(Inst); + } + // In this case we have a value on the left-hand side and must + // return the results at the successor instruction. Note that + // terminator instructions are always of void type. + assert(Inst->getNextNode() && + "Expected to find a valid successor node!"); + return this->resultsAt(Inst->getNextNode()); + }; std::set KeySet; for (auto &[FlowFact, LatticeValue] : getResultMap()) { KeySet.insert(FlowFact); diff --git a/include/phasar/PhasarLLVM/DataFlowSolver/IfdsIde/Solver/IFDSToIDETabulationProblem.h b/include/phasar/PhasarLLVM/DataFlowSolver/IfdsIde/Solver/IFDSToIDETabulationProblem.h index c1abe7a2a2..9ddf741974 100644 --- a/include/phasar/PhasarLLVM/DataFlowSolver/IfdsIde/Solver/IFDSToIDETabulationProblem.h +++ b/include/phasar/PhasarLLVM/DataFlowSolver/IfdsIde/Solver/IFDSToIDETabulationProblem.h @@ -37,7 +37,7 @@ struct AnalysisDomainExtender : public OriginalAnalysisDomain { }; template -struct is_analysis_domain_extensions : std::false_type {}; +struct is_analysis_domain_extensions : std::false_type {}; // NOLINT template struct is_analysis_domain_extensions< @@ -75,27 +75,27 @@ class IFDSToIDETabulationProblem this->ZeroValue = Problem.createZeroValue(); } - FlowFunctionPtrType getNormalFlowFunction(n_t curr, n_t succ) override { - return Problem.getNormalFlowFunction(curr, succ); + FlowFunctionPtrType getNormalFlowFunction(n_t Curr, n_t Succ) override { + return Problem.getNormalFlowFunction(Curr, Succ); } - FlowFunctionPtrType getCallFlowFunction(n_t callSite, f_t destFun) override { - return Problem.getCallFlowFunction(callSite, destFun); + FlowFunctionPtrType getCallFlowFunction(n_t CallSite, f_t DestFun) override { + return Problem.getCallFlowFunction(CallSite, DestFun); } - FlowFunctionPtrType getRetFlowFunction(n_t callSite, f_t calleeFun, - n_t exitInst, n_t retSite) override { - return Problem.getRetFlowFunction(callSite, calleeFun, exitInst, retSite); + FlowFunctionPtrType getRetFlowFunction(n_t CallSite, f_t CalleeFun, + n_t ExitInst, n_t RetSite) override { + return Problem.getRetFlowFunction(CallSite, CalleeFun, ExitInst, RetSite); } - FlowFunctionPtrType getCallToRetFlowFunction(n_t callSite, n_t retSite, - std::set callees) override { - return Problem.getCallToRetFlowFunction(callSite, retSite, callees); + FlowFunctionPtrType getCallToRetFlowFunction(n_t CallSite, n_t RetSite, + std::set Callees) override { + return Problem.getCallToRetFlowFunction(CallSite, RetSite, Callees); } - FlowFunctionPtrType getSummaryFlowFunction(n_t callSite, - f_t destFun) override { - return Problem.getSummaryFlowFunction(callSite, destFun); + FlowFunctionPtrType getSummaryFlowFunction(n_t CallSite, + f_t DestFun) override { + return Problem.getSummaryFlowFunction(CallSite, DestFun); } InitialSeeds initialSeeds() override { @@ -110,12 +110,11 @@ class IFDSToIDETabulationProblem BinaryDomain bottomElement() override { return BinaryDomain::BOTTOM; } - BinaryDomain join(BinaryDomain left, BinaryDomain right) override { - if (left == BinaryDomain::TOP && right == BinaryDomain::TOP) { + BinaryDomain join(BinaryDomain Lhs, BinaryDomain Rhs) override { + if (Lhs == BinaryDomain::TOP && Rhs == BinaryDomain::TOP) { return BinaryDomain::TOP; - } else { - return BinaryDomain::BOTTOM; } + return BinaryDomain::BOTTOM; } std::shared_ptr> allTopFunction() override { @@ -123,60 +122,63 @@ class IFDSToIDETabulationProblem } std::shared_ptr> - getNormalEdgeFunction(n_t src, d_t srcNode, n_t tgt, d_t tgtNode) override { - if (Problem.isZeroValue(srcNode)) { + getNormalEdgeFunction(n_t /*Src*/, d_t SrcNode, n_t /*Tgt*/, + d_t /*TgtNode*/) override { + if (Problem.isZeroValue(SrcNode)) { return ALLBOTTOM; } return EdgeIdentity::getInstance(); } std::shared_ptr> - getCallEdgeFunction(n_t callSite, d_t srcNode, f_t destinationFunction, - d_t destNode) override { - if (Problem.isZeroValue(srcNode)) { + getCallEdgeFunction(n_t /*CallSite*/, d_t SrcNode, + f_t /*DestinationFunction*/, d_t /*DestNode*/) override { + if (Problem.isZeroValue(SrcNode)) { return ALLBOTTOM; } return EdgeIdentity::getInstance(); } std::shared_ptr> - getReturnEdgeFunction(n_t callSite, f_t calleeFunction, n_t exitInst, - d_t exitNode, n_t returnSite, d_t retNode) override { - if (Problem.isZeroValue(exitNode)) { + getReturnEdgeFunction(n_t /*CallSite*/, f_t /*CalleeFunction*/, + n_t /*ExitInst*/, d_t ExitNode, n_t /*ReturnSite*/, + d_t /*RetNode*/) override { + if (Problem.isZeroValue(ExitNode)) { return ALLBOTTOM; } return EdgeIdentity::getInstance(); } std::shared_ptr> - getCallToRetEdgeFunction(n_t callSite, d_t callNode, n_t returnSite, - d_t returnSideNode, std::set callees) override { - if (Problem.isZeroValue(callNode)) { + getCallToRetEdgeFunction(n_t /*CallSite*/, d_t CallNode, n_t /*ReturnSite*/, + d_t /*ReturnSideNode*/, + std::set /*Callees*/) override { + if (Problem.isZeroValue(CallNode)) { return ALLBOTTOM; } return EdgeIdentity::getInstance(); } std::shared_ptr> - getSummaryEdgeFunction(n_t callSite, d_t callNode, n_t retSite, - d_t retSiteNode) override { + getSummaryEdgeFunction(n_t /*CallSite*/, d_t /*CallNode*/, n_t /*RetSite*/, + d_t /*RetSiteNode*/) override { return EdgeIdentity::getInstance(); } - void printNode(std::ostream &os, n_t n) const override { - Problem.printNode(os, n); + void printNode(std::ostream &OS, n_t Stmt) const override { + Problem.printNode(OS, Stmt); } - void printDataFlowFact(std::ostream &os, d_t d) const override { - Problem.printDataFlowFact(os, d); + void printDataFlowFact(std::ostream &OS, d_t Fact) const override { + Problem.printDataFlowFact(OS, Fact); } - void printFunction(std::ostream &os, f_t f) const override { - Problem.printFunction(os, f); + void printFunction(std::ostream &OS, f_t Func) const override { + Problem.printFunction(OS, Func); } - void printEdgeFact(std::ostream &os, BinaryDomain v) const override { - os << v; + void printEdgeFact(std::ostream &OS, BinaryDomain Val) const override { + OS << Val; } void emitTextReport(const SolverResults &Results, diff --git a/include/phasar/PhasarLLVM/DataFlowSolver/IfdsIde/Solver/JoinHandlingNode.h b/include/phasar/PhasarLLVM/DataFlowSolver/IfdsIde/Solver/JoinHandlingNode.h index 64683cd753..5f00416c64 100644 --- a/include/phasar/PhasarLLVM/DataFlowSolver/IfdsIde/Solver/JoinHandlingNode.h +++ b/include/phasar/PhasarLLVM/DataFlowSolver/IfdsIde/Solver/JoinHandlingNode.h @@ -24,6 +24,8 @@ namespace psr { template class JoinHandlingNode { public: virtual ~JoinHandlingNode(); + JoinHandlingNode(JoinHandlingNode &Other) = delete; + JoinHandlingNode &operator=(JoinHandlingNode &Other) = delete; /** * * @param joiningNode the node abstraction that was propagated to the same @@ -32,11 +34,11 @@ template class JoinHandlingNode { * {@code joiningNode} is necessary, otherwise false meaning * the node should be propagated by the solver. */ - virtual bool handleJoin(T joiningNode) = 0; + virtual bool handleJoin(T JoiningNode) = 0; class JoinKey { private: - std::vector elements; + std::vector Elements; public: /** @@ -44,7 +46,7 @@ template class JoinHandlingNode { * @param elements Passed elements must be immutable with respect to their * hashCode and equals implementations. */ - JoinKey(std::vector elems) : elements(elems) {} + JoinKey(std::vector Elems) : Elements(Elems) {} int hash() { return 0; } bool equals() { return false; } }; diff --git a/include/phasar/PhasarLLVM/DataFlowSolver/IfdsIde/Solver/JumpFunctions.h b/include/phasar/PhasarLLVM/DataFlowSolver/IfdsIde/Solver/JumpFunctions.h index 755081e2d2..5c7443bb18 100644 --- a/include/phasar/PhasarLLVM/DataFlowSolver/IfdsIde/Solver/JumpFunctions.h +++ b/include/phasar/PhasarLLVM/DataFlowSolver/IfdsIde/Solver/JumpFunctions.h @@ -48,30 +48,31 @@ template class JumpFunctions { using EdgeFunctionPtrType = std::shared_ptr; private: - EdgeFunctionPtrType allTop; - const IDETabulationProblem &problem; + EdgeFunctionPtrType Alltop; + const IDETabulationProblem &Problem; protected: // mapping from target node and value to a list of all source values and // associated functions where the list is implemented as a mapping from // the source value to the function we exclude empty default functions Table, 1>> - nonEmptyReverseLookup; + NonEmptyReverseLookup; // mapping from source value and target node to a list of all target values // and associated functions where the list is implemented as a mapping from // the source value to the function we exclude empty default functions Table, 1>> - nonEmptyForwardLookup; + NonEmptyForwardLookup; // a mapping from target node to a list of triples consisting of source value, // target value and associated function; the triple is implemented by a table // we exclude empty default functions std::unordered_map> - nonEmptyLookupByTargetNode; + NonEmptyLookupByTargetNode; public: - JumpFunctions(EdgeFunctionPtrType allTop, - const IDETabulationProblem &p) - : allTop(std::move(allTop)), problem(p) {} + JumpFunctions( + EdgeFunctionPtrType Alltop, + const IDETabulationProblem &Problem) + : Alltop(std::move(Alltop)), Problem(Problem) {} ~JumpFunctions() = default; @@ -84,51 +85,51 @@ template class JumpFunctions { * Records a jump function. The source statement is implicit. * @see PathEdge */ - void addFunction(d_t sourceVal, n_t target, d_t targetVal, - EdgeFunctionPtrType function) { + void addFunction(d_t SourceVal, n_t Target, d_t TargetVal, + EdgeFunctionPtrType EdgeFunc) { LOG_IF_ENABLE(BOOST_LOG_SEV(lg::get(), DEBUG) << "Start adding new jump function"; BOOST_LOG_SEV(lg::get(), DEBUG) - << "Fact at source : " << problem.DtoString(sourceVal); + << "Fact at source : " << Problem.DtoString(SourceVal); BOOST_LOG_SEV(lg::get(), DEBUG) - << "Fact at target : " << problem.DtoString(targetVal); + << "Fact at target : " << Problem.DtoString(TargetVal); BOOST_LOG_SEV(lg::get(), DEBUG) - << "Destination : " << problem.NtoString(target); + << "Destination : " << Problem.NtoString(Target); BOOST_LOG_SEV(lg::get(), DEBUG) - << "Edge Function : " << function->str()); + << "Edge Function : " << EdgeFunc->str()); // we do not store the default function (all-top) - if (function->equal_to(allTop)) { + if (EdgeFunc->equal_to(Alltop)) { return; } - auto &SourceValToFunc = nonEmptyReverseLookup.get(target, targetVal); + auto &SourceValToFunc = NonEmptyReverseLookup.get(Target, TargetVal); if (auto Find = std::find_if( SourceValToFunc.begin(), SourceValToFunc.end(), - [sourceVal](const std::pair &Entry) { - return sourceVal == Entry.first; + [SourceVal](const std::pair &Entry) { + return SourceVal == Entry.first; }); Find != SourceValToFunc.end()) { // it is important that existing values in JumpFunctions are overwritten - Find->second = function; + Find->second = EdgeFunc; } else { - SourceValToFunc.emplace_back(sourceVal, function); + SourceValToFunc.emplace_back(SourceVal, EdgeFunc); } - auto &TargetValToFunc = nonEmptyForwardLookup.get(sourceVal, target); + auto &TargetValToFunc = NonEmptyForwardLookup.get(SourceVal, Target); if (auto Find = std::find_if( TargetValToFunc.begin(), TargetValToFunc.end(), - [targetVal](const std::pair &Entry) { - return targetVal == Entry.first; + [TargetVal](const std::pair &Entry) { + return TargetVal == Entry.first; }); Find != TargetValToFunc.end()) { // it is important that existing values in JumpFunctions are overwritten - Find->second = function; + Find->second = EdgeFunc; } else { - TargetValToFunc.emplace_back(targetVal, function); + TargetValToFunc.emplace_back(TargetVal, EdgeFunc); } // V Table::insert(R r, C c, V v) always overrides (see comments above) - nonEmptyLookupByTargetNode[target].insert(sourceVal, targetVal, function); + NonEmptyLookupByTargetNode[Target].insert(SourceVal, TargetVal, EdgeFunc); LOG_IF_ENABLE(BOOST_LOG_SEV(lg::get(), DEBUG) << "End adding new jump function"; BOOST_LOG_SEV(lg::get(), DEBUG) << ' '); @@ -141,12 +142,11 @@ template class JumpFunctions { */ std::optional, 1>>> - reverseLookup(n_t target, d_t targetVal) { - if (!nonEmptyReverseLookup.contains(target, targetVal)) { + reverseLookup(n_t Target, d_t TargetVal) { + if (!NonEmptyReverseLookup.contains(Target, TargetVal)) { return std::nullopt; - } else { - return {nonEmptyReverseLookup.get(target, targetVal)}; } + return {NonEmptyReverseLookup.get(Target, TargetVal)}; } /** @@ -156,12 +156,11 @@ template class JumpFunctions { */ std::optional, 1>>> - forwardLookup(d_t sourceVal, n_t target) { - if (!nonEmptyForwardLookup.contains(sourceVal, target)) { + forwardLookup(d_t SourceVal, n_t Target) { + if (!NonEmptyForwardLookup.contains(SourceVal, Target)) { return std::nullopt; - } else { - return {nonEmptyForwardLookup.get(sourceVal, target)}; } + return {NonEmptyForwardLookup.get(SourceVal, Target)}; } /** @@ -170,8 +169,8 @@ template class JumpFunctions { * The return value is a set of records of the form * (sourceVal,targetVal,edgeFunction). */ - Table lookupByTarget(n_t target) { - return nonEmptyLookupByTargetNode[target]; + Table lookupByTarget(n_t Target) { + return NonEmptyLookupByTargetNode[Target]; } /** @@ -180,96 +179,96 @@ template class JumpFunctions { * @return True if the function has actually been removed. False if it was not * there anyway. */ - bool removeFunction(d_t sourceVal, n_t target, d_t targetVal) { - auto &SourceValToFunc = nonEmptyReverseLookup.get(target, targetVal); + bool removeFunction(d_t SourceVal, n_t Target, d_t TargetVal) { + auto &SourceValToFunc = NonEmptyReverseLookup.get(Target, TargetVal); if (auto Find = std::find_if( SourceValToFunc.begin(), SourceValToFunc.end(), - [sourceVal](const std::pair &Entry) { - return sourceVal == Entry.first; + [SourceVal](const std::pair &Entry) { + return SourceVal == Entry.first; }); Find != SourceValToFunc.end()) { SourceValToFunc.erase(Find); } - auto &TargetValToFunc = nonEmptyForwardLookup.get(sourceVal, target); + auto &TargetValToFunc = NonEmptyForwardLookup.get(SourceVal, Target); if (auto Find = std::find_if( TargetValToFunc.begin(), TargetValToFunc.end(), - [targetVal](const std::pair &Entry) { - return targetVal == Entry.first; + [TargetVal](const std::pair &Entry) { + return TargetVal == Entry.first; }); Find != TargetValToFunc.end()) { TargetValToFunc.erase(Find); } - return nonEmptyLookupByTargetNode.erase(target); + return NonEmptyLookupByTargetNode.erase(Target); } /** * Removes all jump functions */ void clear() { - nonEmptyReverseLookup.clear(); - nonEmptyForwardLookup.clear(); - nonEmptyLookupByTargetNode.clear(); + NonEmptyReverseLookup.clear(); + NonEmptyForwardLookup.clear(); + NonEmptyLookupByTargetNode.clear(); } - void printJumpFunctions(std::ostream &os) { - os << "\n******************************************************"; - os << "\n* Print all Jump Functions *"; - os << "\n******************************************************\n"; - for (auto &entry : nonEmptyLookupByTargetNode) { - std::string nLabel = problem.NtoString(entry.first); - os << "\nN: " << nLabel << "\n---" << std::string(nLabel.size(), '-') + void printJumpFunctions(std::ostream &OS) { + OS << "\n******************************************************"; + OS << "\n* Print all Jump Functions *"; + OS << "\n******************************************************\n"; + for (auto &Entry : NonEmptyLookupByTargetNode) { + std::string NLabel = Problem.NtoString(Entry.first); + OS << "\nN: " << NLabel << "\n---" << std::string(NLabel.size(), '-') << '\n'; - for (auto cell : entry.second.cellSet()) { - os << "D1: " << problem.DtoString(cell.r) << '\n' - << "\tD2: " << problem.DtoString(cell.c) << '\n' - << "\tEF: " << cell.v->str() << "\n\n"; + for (auto Cell : Entry.second.cellSet()) { + OS << "D1: " << Problem.DtoString(Cell.r) << '\n' + << "\tD2: " << Problem.DtoString(Cell.c) << '\n' + << "\tEF: " << Cell.v->str() << "\n\n"; } } } - void printNonEmptyReverseLookup(std::ostream &os) { - os << "DUMP nonEmptyReverseLookup\nTable>\n"; - auto cellvec = nonEmptyReverseLookup.cellVec(); - for (auto cell : cellvec) { - os << "N : " << problem.NtoString(cell.r) - << "\nD1: " << problem.DtoString(cell.c) << '\n'; - for (auto D2ToEF : cell.v) { - os << "D2: " << problem.DtoString(D2ToEF.first) + auto CellVec = NonEmptyReverseLookup.cellVec(); + for (auto Cell : CellVec) { + OS << "N : " << Problem.NtoString(Cell.r) + << "\nD1: " << Problem.DtoString(Cell.c) << '\n'; + for (auto D2ToEF : Cell.v) { + OS << "D2: " << Problem.DtoString(D2ToEF.first) << "\nEF: " << D2ToEF.second->str() << '\n'; } - os << '\n'; + OS << '\n'; } } - void printNonEmptyForwardLookup(std::ostream &os) { - os << "DUMP nonEmptyForwardLookup\nTable>\n"; - auto cellvec = nonEmptyForwardLookup.cellVec(); - for (auto cell : cellvec) { - os << "D1: " << problem.DtoString(cell.r) - << "\nN : " << problem.NtoString(cell.c) << '\n'; - for (auto D2ToEF : cell.v) { - os << "D2: " << problem.DtoString(D2ToEF.first) + auto CellVec = NonEmptyForwardLookup.cellVec(); + for (auto Cell : CellVec) { + OS << "D1: " << Problem.DtoString(Cell.r) + << "\nN : " << Problem.NtoString(Cell.c) << '\n'; + for (auto D2ToEF : Cell.v) { + OS << "D2: " << Problem.DtoString(D2ToEF.first) << "\nEF: " << D2ToEF.second->str() << '\n'; } - os << '\n'; + OS << '\n'; } } - void printNonEmptyLookupByTargetNode(std::ostream &os) { - os << "DUMP nonEmptyLookupByTargetNode\nstd::unordered_map>\n"; - for (auto node : nonEmptyLookupByTargetNode) { - os << "\nN : " << problem.NtoString(node.first) << '\n'; - auto table = nonEmptyLookupByTargetNode[node.first]; - auto cellvec = table.cellVec(); - for (auto cell : cellvec) { - os << "D1: " << problem.DtoString(cell.r) - << "\nD2: " << problem.DtoString(cell.c) << "\nEF: " << cell.v->str() + for (auto Node : NonEmptyLookupByTargetNode) { + OS << "\nN : " << Problem.NtoString(Node.first) << '\n'; + auto Table = NonEmptyLookupByTargetNode[Node.first]; + auto CellVec = Table.cellVec(); + for (auto Cell : CellVec) { + OS << "D1: " << Problem.DtoString(Cell.r) + << "\nD2: " << Problem.DtoString(Cell.c) << "\nEF: " << Cell.v->str() << '\n'; } - os << '\n'; + OS << '\n'; } } }; diff --git a/include/phasar/PhasarLLVM/DataFlowSolver/IfdsIde/Solver/LinkedNode.h b/include/phasar/PhasarLLVM/DataFlowSolver/IfdsIde/Solver/LinkedNode.h index 8c61f42338..e91d9fc548 100644 --- a/include/phasar/PhasarLLVM/DataFlowSolver/IfdsIde/Solver/LinkedNode.h +++ b/include/phasar/PhasarLLVM/DataFlowSolver/IfdsIde/Solver/LinkedNode.h @@ -34,8 +34,8 @@ template class LinkedNode { * been merged * with this one of paths were not being tracked. */ - virtual void addNeighbor(D originalAbstraction) = 0; - virtual void setCallingContext(D callingContext) = 0; + virtual void addNeighbor(D OriginalAbstraction) = 0; + virtual void setCallingContext(D CallingContext) = 0; }; } // namespace psr diff --git a/include/phasar/PhasarLLVM/DataFlowSolver/IfdsIde/Solver/PathEdge.h b/include/phasar/PhasarLLVM/DataFlowSolver/IfdsIde/Solver/PathEdge.h index 2917b5ef9e..1137ede0ce 100644 --- a/include/phasar/PhasarLLVM/DataFlowSolver/IfdsIde/Solver/PathEdge.h +++ b/include/phasar/PhasarLLVM/DataFlowSolver/IfdsIde/Solver/PathEdge.h @@ -23,13 +23,13 @@ namespace psr { template class PathEdge { private: - const N target; - const D dSource; - const D dTarget; + const N Target; + const D DSource; + const D DTarget; public: - PathEdge(D dSource, N target, D dTarget) - : target(target), dSource(dSource), dTarget(dTarget) {} + PathEdge(D DSource, N Target, D DTarget) + : Target(Target), DSource(DSource), DTarget(DTarget) {} ~PathEdge() = default; @@ -37,19 +37,19 @@ template class PathEdge { PathEdge &operator=(const PathEdge &) = default; - PathEdge(PathEdge &&) = default; + PathEdge(PathEdge &&) noexcept = default; - PathEdge &operator=(PathEdge &&) = default; + PathEdge &operator=(PathEdge &&) noexcept = default; - [[nodiscard]] N getTarget() const { return target; } + [[nodiscard]] N getTarget() const { return Target; } - [[nodiscard]] D factAtSource() const { return dSource; } + [[nodiscard]] D factAtSource() const { return DSource; } - [[nodiscard]] D factAtTarget() const { return dTarget; } + [[nodiscard]] D factAtTarget() const { return DTarget; } - friend std::ostream &operator<<(std::ostream &os, const PathEdge &pathEdge) { - return os << "<" << pathEdge.dSource << "> -> <" << pathEdge.target << "," - << pathEdge.dTarget << ">"; + friend std::ostream &operator<<(std::ostream &OS, const PathEdge &Edge) { + return OS << "<" << Edge.dSource << "> -> <" << Edge.target << "," + << Edge.dTarget << ">"; } }; diff --git a/include/phasar/PhasarLLVM/DataFlowSolver/IfdsIde/Solver/SolverResults.h b/include/phasar/PhasarLLVM/DataFlowSolver/IfdsIde/Solver/SolverResults.h index ca65dbd343..84a1d62f3d 100644 --- a/include/phasar/PhasarLLVM/DataFlowSolver/IfdsIde/Solver/SolverResults.h +++ b/include/phasar/PhasarLLVM/DataFlowSolver/IfdsIde/Solver/SolverResults.h @@ -29,27 +29,26 @@ namespace psr { template class SolverResults { private: - Table &results; - D zeroValue; + Table &Results; + D ZV; public: - SolverResults(Table &res_tab, D zv) - : results(res_tab), zeroValue(zv) {} + SolverResults(Table &ResTab, D ZV) : Results(ResTab), ZV(ZV) {} - L resultAt(N stmt, D node) const { return results.get(stmt, node); } + L resultAt(N Stmt, D Node) const { return Results.get(Stmt, Node); } - std::unordered_map resultsAt(N stmt, bool stripZero = false) const { - std::unordered_map result = results.row(stmt); - if (stripZero) { - for (auto it = result.begin(); it != result.end();) { - if (it->first == zeroValue) { - it = result.erase(it); + std::unordered_map resultsAt(N Stmt, bool StripZero = false) const { + std::unordered_map Result = Results.row(Stmt); + if (StripZero) { + for (auto It = Result.begin(); It != Result.end();) { + if (It->first == ZV) { + It = Result.erase(It); } else { - ++it; + ++It; } } } - return result; + return Result; } // this function only exists for IFDS problems which use BinaryDomain as their @@ -57,17 +56,18 @@ template class SolverResults { template >> - std::set ifdsResultsAt(N stmt) const { + std::set ifdsResultsAt(N Stmt) const { std::set KeySet; - std::unordered_map ResultMap = this->resultsAt(stmt); + std::unordered_map ResultMap = this->resultsAt(Stmt); for (auto FlowFact : ResultMap) { KeySet.insert(FlowFact.first); } return KeySet; } - std::vector::Cell> getAllResultEntries() const { - return results.cellVec(); + [[nodiscard]] std::vector::Cell> + getAllResultEntries() const { + return Results.cellVec(); } }; diff --git a/include/phasar/PhasarLLVM/Utils/DOTGraph.h b/include/phasar/PhasarLLVM/Utils/DOTGraph.h index fc2a75c013..d5494cb81c 100644 --- a/include/phasar/PhasarLLVM/Utils/DOTGraph.h +++ b/include/phasar/PhasarLLVM/Utils/DOTGraph.h @@ -29,18 +29,24 @@ namespace psr { class DOTConfig { public: - static const std::string CFNodeAttr() { return CFNode; } - static const std::string CFIntraEdgeAttr() { return CFIntraEdge; } - static const std::string CFInterEdgeAttr() { return CFInterEdge; } - - static const std::string FactNodeAttr() { return FactNode; } - static const std::string FactIDEdgeAttr() { return FactIDEdge; } - static const std::string FactCrossEdgeAttr() { return FactCrossEdge; } - static const std::string FactInterEdgeAttr() { return FactInterEdge; } + static const std::string CFNodeAttr() { return CFNode; } // NOLINT + static const std::string CFIntraEdgeAttr() { return CFIntraEdge; } // NOLINT + static const std::string CFInterEdgeAttr() { return CFInterEdge; } // NOLINT + + static const std::string FactNodeAttr() { return FactNode; } // NOLINT + static const std::string FactIDEdgeAttr() { return FactIDEdge; } // NOLINT + static const std::string FactCrossEdgeAttr() { // NOLINT + return FactCrossEdge; + } + static const std::string FactInterEdgeAttr() { // NOLINT + return FactInterEdge; + } - static const std::string LambdaNodeAttr() { return LambdaNode; } - static const std::string LambdaIDEdgeAttr() { return LambdaIDEdge; } - static const std::string LambdaInterEdgeAttr() { return LambdaInterEdge; } + static const std::string LambdaNodeAttr() { return LambdaNode; } // NOLINT + static const std::string LambdaIDEdgeAttr() { return LambdaIDEdge; } // NOLINT + static const std::string LambdaInterEdgeAttr() { // NOLINT + return LambdaInterEdge; + } static void importDOTConfig(std::string ConfigPath = PhasarConfig::PhasarDirectory()); @@ -52,26 +58,27 @@ class DOTConfig { private: DOTConfig() = default; - inline static const std::string fontSize = "fontsize=11"; - inline static const std::string arrowSize = "arrowsize=0.7"; - - inline static std::string CFNode = "node [style=filled, shape=record]"; - inline static std::string CFIntraEdge = "edge []"; - inline static std::string CFInterEdge = "edge [weight=0.1]"; - inline static std::string FactNode = "node [style=rounded]"; - inline static std::string FactIDEdge = + inline static const std::string fontSize = "fontsize=11"; // NOLINT + inline static const std::string arrowSize = "arrowsize=0.7"; // NOLINT + + inline static std::string CFNode = // NOLINT + "node [style=filled, shape=record]"; + inline static std::string CFIntraEdge = "edge []"; // NOLINT + inline static std::string CFInterEdge = "edge [weight=0.1]"; // NOLINT + inline static std::string FactNode = "node [style=rounded]"; // NOLINT + inline static std::string FactIDEdge = // NOLINT "edge [style=dotted, arrowhead=normal, " + fontSize + ", " + arrowSize + ']'; - inline static std::string FactCrossEdge = + inline static std::string FactCrossEdge = // NOLINT "edge [style=dotted, arrowhead=normal, " + fontSize + ", " + arrowSize + ']'; - inline static std::string FactInterEdge = + inline static std::string FactInterEdge = // NOLINT "edge [weight=0.1, style=dashed, " + fontSize + ", " + arrowSize + ']'; - inline static std::string LambdaNode = "node [style=rounded]"; - inline static std::string LambdaIDEdge = + inline static std::string LambdaNode = "node [style=rounded]"; // NOLINT + inline static std::string LambdaIDEdge = // NOLINT "edge [style=dotted, arrowhead=normal, " + fontSize + ", " + arrowSize + ']'; - inline static std::string LambdaInterEdge = + inline static std::string LambdaInterEdge = // NOLINT "edge [weight=0.1, style=dashed, " + fontSize + ", " + arrowSize + ']'; }; @@ -84,146 +91,147 @@ struct DOTNode { * Note that in this example fact i is the very first valid fact * encountered so the fact-id is 1 (zero value has fact-id 0) */ - std::string id; - std::string funcName; - std::string label; - std::string stmtId; - unsigned factId; - bool isVisible = true; + std::string Id; + std::string FuncName; + std::string Label; + std::string StmtId; + unsigned FactId = 0; + bool IsVisible = true; DOTNode() = default; - DOTNode(std::string fName, std::string l, std::string sId, unsigned fId = 0, - bool isStmt = true, bool isv = true); - std::string str(const std::string &indent = "") const; + DOTNode(std::string FName, std::string L, std::string SId, unsigned FId = 0, + bool IsStmt = true, bool Isv = true); + [[nodiscard]] std::string str(const std::string &Indent = "") const; }; -bool operator<(const DOTNode &lhs, const DOTNode &rhs); -bool operator==(const DOTNode &lhs, const DOTNode &rhs); -std::ostream &operator<<(std::ostream &os, const DOTNode &node); +bool operator<(const DOTNode &Lhs, const DOTNode &Rhs); +bool operator==(const DOTNode &Lhs, const DOTNode &Rhs); +std::ostream &operator<<(std::ostream &OS, const DOTNode &Node); struct DOTEdge { - DOTNode source; - DOTNode target; - bool isVisible; - std::string edgeFnLabel; - std::string valueLabel; - - DOTEdge(DOTNode src, DOTNode tar, bool isv = true, std::string efl = "", - std::string vl = ""); - std::string str(const std::string &indent = "") const; + DOTNode Source; + DOTNode Target; + bool IsVisible; + std::string EdgeFnLabel; + std::string ValueLabel; + + DOTEdge(DOTNode Src, DOTNode Tar, bool Isv = true, std::string Efl = "", + std::string Vl = ""); + [[nodiscard]] std::string str(const std::string &Indent = "") const; }; -bool operator<(const DOTEdge &lhs, const DOTEdge &rhs); -std::ostream &operator<<(std::ostream &os, const DOTEdge &edge); +bool operator<(const DOTEdge &Lhs, const DOTEdge &Rhs); +std::ostream &operator<<(std::ostream &OS, const DOTEdge &Edge); struct DOTFactSubGraph { // fact subgraph id = _ - std::string id; - unsigned factId; - std::string label; + std::string Id; + unsigned FactId = 0; + std::string Label; // stmt-id -> fact-node - std::map nodes; - std::set edges; + std::map Nodes; + std::set Edges; - std::string str(const std::string &indent = "") const; + [[nodiscard]] std::string str(const std::string &Indent = "") const; }; -std::ostream &operator<<(std::ostream &os, const DOTFactSubGraph &factSG); +std::ostream &operator<<(std::ostream &OS, const DOTFactSubGraph &FactSG); struct DOTFunctionSubGraph { // function subgraph id = - std::string id; - std::set stmts; + std::string Id; + std::set Stmts; // fact-id -> fact-subgraph - std::map facts; - std::set intraCFEdges; + std::map Facts; + std::set IntraCFEdges; /// d1 -> d2 where d1 != d2 - std::set crossFactEdges; + std::set CrossFactEdges; - std::string str(const std::string &indent = "") const; - DOTFactSubGraph *getOrCreateFactSG(unsigned factID, std::string &label); + [[nodiscard]] std::string str(const std::string &Indent = "") const; + DOTFactSubGraph *getOrCreateFactSG(unsigned FactID, std::string &Label); // TODO: pass the actual lambda EF name and value as parameter from DOTGraph - std::string generateLambdaSG(const std::string &indent = "") const; + [[nodiscard]] std::string + generateLambdaSG(const std::string &Indent = "") const; void createLayoutCFNodes(); void createLayoutFactNodes(); void createLayoutFactEdges(); }; -std::ostream &operator<<(std::ostream &os, - const DOTFunctionSubGraph &functionSG); +std::ostream &operator<<(std::ostream &OS, + const DOTFunctionSubGraph &FunctionSG); template struct DOTGraph { - std::string label; - std::map functions; - std::set interCFEdges; - std::set interLambdaEdges; - std::set interFactEdges; + std::string Label; + std::map Functions; + std::set InterCFEdges; + std::set InterLambdaEdges; + std::set InterFactEdges; DOTGraph() = default; - unsigned getFactID(D fact) { - unsigned id = 0; - if (DtoFactId.count(fact)) { - id = DtoFactId[fact]; + unsigned getFactID(D Fact) { + unsigned Id = 0; + if (DtoFactId.count(Fact)) { + Id = DtoFactId[Fact]; } else { - id = factIDCount; - DtoFactId[fact] = factIDCount++; + Id = FactIDCount; + DtoFactId[Fact] = FactIDCount++; } - return id; + return Id; } - bool containsFactSG(std::string fName, unsigned factID) { - if (functions.count(fName)) { - if (functions[fName].facts.count(factID)) { + bool containsFactSG(std::string &FName, unsigned FactId) { + if (Functions.count(FName)) { + if (Functions[FName].Facts.count(FactId)) { return true; } } return false; } - std::string str() const { - std::string indent = " "; - std::string str = "digraph {\n" + indent + "label=\"" + label + "\"\n"; + [[nodiscard]] std::string str() const { + std::string Indent = " "; + std::string Str = "digraph {\n" + Indent + "label=\"" + Label + "\"\n"; // Print function subgraphs - str += '\n' + indent + "// Function sub graphs\n"; - for (auto fsg : functions) { - fsg.second.createLayoutCFNodes(); - fsg.second.createLayoutFactNodes(); - fsg.second.createLayoutFactEdges(); - str += fsg.second.str(indent) + "\n\n"; + Str += '\n' + Indent + "// Function sub graphs\n"; + for (auto Fsg : Functions) { + Fsg.second.createLayoutCFNodes(); + Fsg.second.createLayoutFactNodes(); + Fsg.second.createLayoutFactEdges(); + Str += Fsg.second.str(Indent) + "\n\n"; } // Print inter control flow edges - str += indent + "// Inter-procedural control flow edges\n" + indent + + Str += Indent + "// Inter-procedural control flow edges\n" + Indent + DOTConfig::CFInterEdgeAttr() + '\n'; - for (DOTEdge e : interCFEdges) { - str += e.str(indent) + '\n'; + for (const DOTEdge &Edge : InterCFEdges) { + Str += Edge.str(Indent) + '\n'; } // Print inter lambda edges - str += '\n' + indent + "// Inter-procedural lambda edges\n" + indent + + Str += '\n' + Indent + "// Inter-procedural lambda edges\n" + Indent + DOTConfig::LambdaInterEdgeAttr() + '\n'; - for (DOTEdge e : interLambdaEdges) { - str += e.str(indent) + '\n'; + for (const DOTEdge &Edge : InterLambdaEdges) { + Str += Edge.str(Indent) + '\n'; } // Print inter fact edges - str += '\n' + indent + "// Inter-procedural fact edges\n" + indent + + Str += '\n' + Indent + "// Inter-procedural fact edges\n" + Indent + DOTConfig::FactInterEdgeAttr() + '\n'; - for (DOTEdge e : interFactEdges) { - str += e.str(indent) + '\n'; + for (const DOTEdge &Edge : InterFactEdges) { + Str += Edge.str(Indent) + '\n'; } - return str + '}'; + return Str + '}'; } - friend std::ostream &operator<<(std::ostream &os, const DOTGraph &graph) { - return os << graph.str(); + friend std::ostream &operator<<(std::ostream &OS, const DOTGraph &Graph) { + return OS << Graph.str(); } private: // We introduce a fact-ID for data-flow facts D since only statements N have // an ID - unsigned factIDCount = 1; + unsigned FactIDCount = 1; std::map DtoFactId; }; diff --git a/include/phasar/Utils/LLVMShorthands.h b/include/phasar/Utils/LLVMShorthands.h index 1583479e2f..3092135e33 100644 --- a/include/phasar/Utils/LLVMShorthands.h +++ b/include/phasar/Utils/LLVMShorthands.h @@ -100,10 +100,10 @@ std::string getMetaDataID(const llvm::Value *V); * This is useful, since Instructions/Globals and Arguments have different * underlying types for their ID's, size_t and string respectively. */ -struct llvmValueIDLess { - stringIDLess sless; - llvmValueIDLess(); - bool operator()(const llvm::Value *lhs, const llvm::Value *rhs) const; +struct LLVMValueIDLess { + StringIDLess Sless; + LLVMValueIDLess(); + bool operator()(const llvm::Value *Lhs, const llvm::Value *Rhs) const; }; /** @@ -122,7 +122,7 @@ int getFunctionArgumentNr(const llvm::Argument *Arg); * @return LLVM Argument or nullptr, if argNo invalid. */ const llvm::Argument *getNthFunctionArgument(const llvm::Function *F, - unsigned argNo); + unsigned ArgNo); /** * The Instruction count starts with one (not zero, as in Function arguments). @@ -148,7 +148,7 @@ const llvm::Instruction *getLastInstructionOf(const llvm::Function *F); * @return LLVM Instruction or nullptr, if termInstNo invalid. */ const llvm::Instruction *getNthTermInstruction(const llvm::Function *F, - unsigned termInstNo); + unsigned TermInstNo); /** * The Store Instruction count starts with one (not zero, as in Function * arguments). @@ -160,7 +160,7 @@ const llvm::Instruction *getNthTermInstruction(const llvm::Function *F, * @return LLVM Store Instruction or nullptr, if stoNo invalid. */ const llvm::StoreInst *getNthStoreInstruction(const llvm::Function *F, - unsigned stoNo); + unsigned StoNo); std::vector getAllExitPoints(const llvm::Function *F); @@ -189,7 +189,7 @@ std::string getModuleNameFromVal(const llvm::Value *V); * hash computation. * @return Hash value. */ -std::size_t computeModuleHash(llvm::Module *M, bool considerIdentifier); +std::size_t computeModuleHash(llvm::Module *M, bool ConsiderIdentifier); /** * @brief Computes a hash value for a given LLVM Module. @@ -235,13 +235,13 @@ class ModulesToSlotTracker { private: static inline llvm::SmallDenseMap, 2> - MToST; + MToST; // NOLINT - static void updateMSTForModule(const llvm::Module *); - static void deleteMSTForModule(const llvm::Module *); + static void updateMSTForModule(const llvm::Module *Module); + static void deleteMSTForModule(const llvm::Module *Module); public: - static llvm::ModuleSlotTracker &getSlotTrackerForModule(const llvm::Module *); + static llvm::ModuleSlotTracker &getSlotTrackerForModule(const llvm::Module *Module); }; } // namespace psr diff --git a/include/phasar/Utils/Utilities.h b/include/phasar/Utils/Utilities.h index 7356377e8e..0b5795e3d1 100644 --- a/include/phasar/Utils/Utilities.h +++ b/include/phasar/Utils/Utilities.h @@ -43,7 +43,7 @@ std::vector splitString(const std::string &Str, const std::string &Delimiter); template -std::set> computePowerSet(const std::set &s) { +std::set> computePowerSet(const std::set &S) { // compute all subsets of {a, b, c, d} // bit-pattern - {d, c, b, a} // 0000 {} @@ -63,12 +63,12 @@ std::set> computePowerSet(const std::set &s) { // 1110 {b, c, d} // 1111 {a, b, c, d} std::set> Powerset; - for (std::size_t i = 0; i < (1 << s.size()); ++i) { + for (std::size_t I = 0; I < (1 << S.size()); ++I) { std::set Subset; - for (std::size_t j = 0; j < s.size(); ++j) { - if ((i & (1 << j)) > 0) { - auto It = s.begin(); - advance(It, j); + for (std::size_t J = 0; J < S.size(); ++J) { + if ((I & (1 << J)) > 0) { + auto It = S.begin(); + advance(It, J); Subset.insert(*It); } Powerset.insert(Subset); @@ -97,7 +97,7 @@ intersectWith(ContainerTy &Dest, const OtherContainerTy &Src) { sizeof(ValueTy) <= sizeof(void *), ValueTy, ValueTy *>; - auto removeFrom = [](auto &Dst, auto &&Elem) { + auto removeFrom = [](auto &Dst, auto &&Elem) { // NOLINT if constexpr (std::is_same_v) { Dst.erase(Elem); } else { @@ -154,12 +154,12 @@ void intersectWith(BitVectorSet &Dest, const BitVectorSet &Src) { std::ostream &operator<<(std::ostream &OS, const std::vector &Bits); -struct stringIDLess { +struct StringIDLess { bool operator()(const std::string &LHS, const std::string &RHS) const; }; /// See "https://en.cppreference.com/w/cpp/experimental/scope_exit/scope_exit" -template class scope_exit { +template class scope_exit { // NOLINT public: template ()())> explicit scope_exit(FFn &&F) noexcept( @@ -216,24 +216,22 @@ It remove_by_index(It First, EndIt Last, IdxIt FirstIndex, IdxEndIt LastIndex) { if (Offset >= std::distance(Curr, Last)) { break; } - First = std::move(Curr, Curr + Offset, First); + First = std::move(Curr, Curr + Offset, First); // NOLINT CurrIdx = *FirstIndex; Curr = First + ++GapSize; } - return std::move(Curr, Last, First); - } else { - - for (auto I = First; I != Last; ++CurrIdx, ++I) { - if (CurrIdx != *FirstIndex) { - *First++ = std::move(*I); - if (++FirstIndex == LastIndex) { - return std::move(std::next(I), Last, First); - } + return std::move(Curr, Last, First); // NOLINT + } + for (auto I = First; I != Last; ++CurrIdx, ++I) { + if (CurrIdx != *FirstIndex) { + *First++ = std::move(*I); + if (++FirstIndex == LastIndex) { + return std::move(std::next(I), Last, First); } } - return First; } + return First; } template " + target.id; - if (isVisible) { - if (!edgeFnLabel.empty() && !valueLabel.empty()) { - Str += " [headlabel=\"\\r" + edgeFnLabel + "\", taillabel=\"" + - valueLabel + "\"]"; - } else if (!edgeFnLabel.empty()) { - Str += " [headlabel=\"\\r" + edgeFnLabel + "\"]"; - } else if (!valueLabel.empty()) { - Str += " [taillabel=\"" + valueLabel + "\"]"; + std::string Str = Indent + Source.Id + " -> " + Target.Id; + if (IsVisible) { + if (!EdgeFnLabel.empty() && !ValueLabel.empty()) { + Str += " [headlabel=\"\\r" + EdgeFnLabel + "\", taillabel=\"" + + ValueLabel + "\"]"; + } else if (!EdgeFnLabel.empty()) { + Str += " [headlabel=\"\\r" + EdgeFnLabel + "\"]"; + } else if (!ValueLabel.empty()) { + Str += " [taillabel=\"" + ValueLabel + "\"]"; } - } else if (!isVisible) { + } else if (!IsVisible) { Str += " [style=invis]"; } return Str; @@ -74,18 +74,18 @@ std::string DOTEdge::str(const std::string &Indent) const { std::string DOTFactSubGraph::str(const std::string &Indent) const { std::string InnerIndent = Indent + " "; - std::string Str = Indent + "subgraph cluster_" + id + " {\n" + InnerIndent + - "style=invis\n" + InnerIndent + "label=\"" + label + + std::string Str = Indent + "subgraph cluster_" + Id + " {\n" + InnerIndent + + "style=invis\n" + InnerIndent + "label=\"" + Label + "\"\n\n" + InnerIndent + "// Fact nodes in the ESG\n" + InnerIndent + DOTConfig::FactNodeAttr() + '\n'; // Print fact nodes - for (const auto &N : nodes) { + for (const auto &N : Nodes) { Str += N.second.str(InnerIndent) + '\n'; } // Print id edges Str += '\n' + InnerIndent + "// Identity edges for this fact\n" + InnerIndent + DOTConfig::FactIDEdgeAttr() + '\n'; - for (const DOTEdge &E : edges) { + for (const DOTEdge &E : Edges) { Str += E.str(InnerIndent) + '\n'; } return Str + Indent + '}'; @@ -93,18 +93,18 @@ std::string DOTFactSubGraph::str(const std::string &Indent) const { std::string DOTFunctionSubGraph::str(const std::string &Indent) const { std::string InnerIndent = Indent + " "; - std::string Str = Indent + "subgraph cluster_" + id + " {\n" + InnerIndent + - "label=\"" + id + "\""; + std::string Str = Indent + "subgraph cluster_" + Id + " {\n" + InnerIndent + + "label=\"" + Id + "\""; // Print control flow nodes Str += "\n\n" + InnerIndent + "// Control flow nodes\n" + InnerIndent + DOTConfig::CFNodeAttr() + '\n'; - for (const DOTNode &Stmt : stmts) { + for (const DOTNode &Stmt : Stmts) { Str += Stmt.str(InnerIndent) + '\n'; } // Print fact subgraphs Str += '\n' + InnerIndent + "// Fact subgraphs\n"; - for (const auto &FactSG : facts) { + for (const auto &FactSG : Facts) { Str += FactSG.second.str(InnerIndent) + "\n\n"; } @@ -114,14 +114,14 @@ std::string DOTFunctionSubGraph::str(const std::string &Indent) const { // Print intra control flow edges Str += "\n\n" + InnerIndent + "// Intra-procedural control flow edges\n" + InnerIndent + DOTConfig::CFIntraEdgeAttr() + '\n'; - for (const DOTEdge &E : intraCFEdges) { + for (const DOTEdge &E : IntraCFEdges) { Str += E.str(InnerIndent) + '\n'; } // Print intra cross fact edges Str += '\n' + InnerIndent + "// Intra-procedural cross fact edges\n" + InnerIndent + DOTConfig::FactCrossEdgeAttr() + '\n'; - for (const DOTEdge &E : crossFactEdges) { + for (const DOTEdge &E : CrossFactEdges) { Str += E.str(InnerIndent) + '\n'; } return Str + Indent + '}'; @@ -129,11 +129,11 @@ std::string DOTFunctionSubGraph::str(const std::string &Indent) const { DOTFactSubGraph *DOTFunctionSubGraph::getOrCreateFactSG(unsigned FactID, std::string &Label) { - DOTFactSubGraph *FuncSG = &facts[FactID]; - if (FuncSG->id.empty()) { - FuncSG->id = id + '_' + std::to_string(FactID); - FuncSG->factId = FactID; - FuncSG->label = Label; + DOTFactSubGraph *FuncSG = &Facts[FactID]; + if (FuncSG->Id.empty()) { + FuncSG->Id = Id + '_' + std::to_string(FactID); + FuncSG->FactId = FactID; + FuncSG->Label = Label; } return FuncSG; } @@ -142,21 +142,21 @@ std::string DOTFunctionSubGraph::generateLambdaSG(const std::string &Indent) const { std::string InnerIndent = Indent + " "; std::string Str = Indent + "// Auto-generated lambda nodes and edges\n" + - Indent + "subgraph cluster_" + id + "_lambda {\n" + + Indent + "subgraph cluster_" + Id + "_lambda {\n" + InnerIndent + "style=invis\n" + InnerIndent + "label=\"Λ\"\n" + InnerIndent + DOTConfig::LambdaNodeAttr() + '\n'; // Print lambda nodes - for (const DOTNode &Stmt : stmts) { - Str += InnerIndent + id + "_0_" + Stmt.stmtId + - " [label=\"Λ|SID: " + Stmt.stmtId + "\"]\n"; + for (const DOTNode &Stmt : Stmts) { + Str += InnerIndent + Id + "_0_" + Stmt.StmtId + + " [label=\"Λ|SID: " + Stmt.StmtId + "\"]\n"; } // Print lambda edges Str += '\n' + InnerIndent + DOTConfig::LambdaIDEdgeAttr() + '\n'; - for (const DOTEdge &E : intraCFEdges) { - Str += InnerIndent + id + "_0_" + E.source.stmtId + " -> " + id + "_0_" + - E.target.stmtId; - if (E.isVisible) { + for (const DOTEdge &E : IntraCFEdges) { + Str += InnerIndent + Id + "_0_" + E.Source.StmtId + " -> " + Id + "_0_" + + E.Target.StmtId; + if (E.IsVisible) { Str += " [headlabel=\"\\rAllBottom\", taillabel=\"BOT\"]\n"; } else { Str += " [style=invis]\n"; @@ -166,51 +166,49 @@ DOTFunctionSubGraph::generateLambdaSG(const std::string &Indent) const { } void DOTFunctionSubGraph::createLayoutCFNodes() { - auto Last = stmts.empty() ? stmts.end() : std::prev(stmts.end()); - for (auto FirstIt = stmts.begin(); FirstIt != Last; ++FirstIt) { + auto Last = Stmts.empty() ? Stmts.end() : std::prev(Stmts.end()); + for (auto FirstIt = Stmts.begin(); FirstIt != Last; ++FirstIt) { auto SecondIt = std::next(FirstIt); DOTNode N1 = *FirstIt; DOTNode N2 = *SecondIt; - intraCFEdges.emplace(N1, N2, false); + IntraCFEdges.emplace(N1, N2, false); } } void DOTFunctionSubGraph::createLayoutFactNodes() { - for (auto &[Key, FactSG] : facts) { - for (const auto &Stmt : stmts) { - if (FactSG.nodes.find(Stmt.stmtId) == FactSG.nodes.end()) { - DOTNode FactNode(Stmt.funcName, FactSG.label, Stmt.stmtId, - FactSG.factId, false, false); - FactSG.nodes[Stmt.stmtId] = FactNode; + for (auto &[Key, FactSG] : Facts) { + for (const auto &Stmt : Stmts) { + if (FactSG.Nodes.find(Stmt.StmtId) == FactSG.Nodes.end()) { + DOTNode FactNode(Stmt.FuncName, FactSG.Label, Stmt.StmtId, + FactSG.FactId, false, false); + FactSG.Nodes[Stmt.StmtId] = FactNode; } } } } void DOTFunctionSubGraph::createLayoutFactEdges() { - for (auto &[Key, FactSG] : facts) { - for (const auto &ICFE : intraCFEdges) { - DOTNode D1 = {ICFE.source.funcName, FactSG.label, ICFE.source.stmtId, - FactSG.factId, false}; - DOTNode D2 = {ICFE.target.funcName, FactSG.label, ICFE.target.stmtId, - FactSG.factId, false}; - FactSG.edges.emplace(D1, D2, false); + for (auto &[Key, FactSG] : Facts) { + for (const auto &ICFE : IntraCFEdges) { + DOTNode D1 = {ICFE.Source.FuncName, FactSG.Label, ICFE.Source.StmtId, + FactSG.FactId, false}; + DOTNode D2 = {ICFE.Target.FuncName, FactSG.Label, ICFE.Target.StmtId, + FactSG.FactId, false}; + FactSG.Edges.emplace(D1, D2, false); } } } bool operator<(const DOTNode &Lhs, const DOTNode &Rhs) { - stringIDLess StrLess; + StringIDLess StrLess; // comparing control flow nodes - if (Lhs.factId == 0 && Rhs.factId == 0) { - return StrLess(Lhs.stmtId, Rhs.stmtId); - } else { // comparing fact nodes - if (Lhs.factId == Rhs.factId) { - return StrLess(Lhs.stmtId, Rhs.stmtId); - } else { - return Lhs.factId < Rhs.factId; - } + if (Lhs.FactId == 0 && Rhs.FactId == 0) { + return StrLess(Lhs.StmtId, Rhs.StmtId); + } // comparing fact nodes + if (Lhs.FactId == Rhs.FactId) { + return StrLess(Lhs.StmtId, Rhs.StmtId); } + return Lhs.FactId < Rhs.FactId; } bool operator==(const DOTNode &Lhs, const DOTNode &Rhs) { @@ -222,10 +220,10 @@ std::ostream &operator<<(std::ostream &OS, const DOTNode &Node) { } bool operator<(const DOTEdge &Lhs, const DOTEdge &Rhs) { - if (Lhs.source == Rhs.source) { - return Lhs.target < Rhs.target; + if (Lhs.Source == Rhs.Source) { + return Lhs.Target < Rhs.Target; } - return Lhs.source < Rhs.source; + return Lhs.Source < Rhs.Source; } std::ostream &operator<<(std::ostream &OS, const DOTEdge &Edge) { diff --git a/lib/Utils/LLVMShorthands.cpp b/lib/Utils/LLVMShorthands.cpp index 727eabba19..e74ed88d94 100644 --- a/lib/Utils/LLVMShorthands.cpp +++ b/lib/Utils/LLVMShorthands.cpp @@ -246,13 +246,13 @@ std::string getMetaDataID(const llvm::Value *V) { return "-1"; } -llvmValueIDLess::llvmValueIDLess() : sless(stringIDLess()) {} +LLVMValueIDLess::LLVMValueIDLess() : Sless(StringIDLess()) {} -bool llvmValueIDLess::operator()(const llvm::Value *Lhs, +bool LLVMValueIDLess::operator()(const llvm::Value *Lhs, const llvm::Value *Rhs) const { std::string LhsId = getMetaDataID(Lhs); std::string RhsId = getMetaDataID(Rhs); - return sless(LhsId, RhsId); + return Sless(LhsId, RhsId); } int getFunctionArgumentNr(const llvm::Argument *Arg) { @@ -456,8 +456,8 @@ llvm::StringRef getVarAnnotationIntrinsicName(const llvm::CallInst *CallInst) { assert(llvm::dyn_cast(CE->getOperand(0)) != nullptr); auto *AnnoteStr = llvm::dyn_cast(CE->getOperand(0)); - assert(llvm::dyn_cast( - AnnoteStr->getInitializer())); + assert(AnnoteStr != nullptr && llvm::dyn_cast( + AnnoteStr->getInitializer())); auto *Data = llvm::dyn_cast(AnnoteStr->getInitializer()); @@ -469,12 +469,12 @@ llvm::StringRef getVarAnnotationIntrinsicName(const llvm::CallInst *CallInst) { llvm::ModuleSlotTracker & ModulesToSlotTracker::getSlotTrackerForModule(const llvm::Module *M) { - auto &ret = MToST[M]; - if (M == nullptr && ret == nullptr) { - ret = std::make_unique(M); + auto &Ret = MToST[M]; + if (M == nullptr && Ret == nullptr) { + Ret = std::make_unique(M); } - assert(ret != nullptr && "no ModuleSlotTracker instance for module cached"); - return *ret; + assert(Ret != nullptr && "no ModuleSlotTracker instance for module cached"); + return *Ret; } void ModulesToSlotTracker::updateMSTForModule(const llvm::Module *M) { diff --git a/lib/Utils/Utilities.cpp b/lib/Utils/Utilities.cpp index b1487300de..b6be7d1136 100644 --- a/lib/Utils/Utilities.cpp +++ b/lib/Utils/Utilities.cpp @@ -94,7 +94,7 @@ ostream &operator<<(ostream &OS, const vector &Bits) { return OS; } -bool stringIDLess::operator()(const std::string &Lhs, +bool StringIDLess::operator()(const std::string &Lhs, const std::string &Rhs) const { char *Endptr1; @@ -103,13 +103,14 @@ bool stringIDLess::operator()(const std::string &Lhs, long RhsVal = strtol(Rhs.c_str(), &Endptr2, 10); if (Lhs.c_str() == Endptr1 && Lhs.c_str() == Endptr2) { return Lhs < Rhs; - } else if (Lhs.c_str() == Endptr1 && Rhs.c_str() != Endptr2) { + } + if (Lhs.c_str() == Endptr1 && Rhs.c_str() != Endptr2) { return false; - } else if (Lhs.c_str() != Endptr1 && Rhs.c_str() == Endptr2) { + } + if (Lhs.c_str() != Endptr1 && Rhs.c_str() == Endptr2) { return true; - } else { - return LhsVal < RhsVal; } + return LhsVal < RhsVal; } } // namespace psr From e64885dc9a2dda1dad3f6df021cfcfadfae88754 Mon Sep 17 00:00:00 2001 From: Florian Sattler Date: Fri, 24 Dec 2021 14:17:31 +0100 Subject: [PATCH 2/5] Update include/phasar/Utils/LLVMShorthands.h Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- include/phasar/Utils/LLVMShorthands.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/phasar/Utils/LLVMShorthands.h b/include/phasar/Utils/LLVMShorthands.h index 3092135e33..1cf453b9e9 100644 --- a/include/phasar/Utils/LLVMShorthands.h +++ b/include/phasar/Utils/LLVMShorthands.h @@ -241,7 +241,8 @@ class ModulesToSlotTracker { static void deleteMSTForModule(const llvm::Module *Module); public: - static llvm::ModuleSlotTracker &getSlotTrackerForModule(const llvm::Module *Module); + static llvm::ModuleSlotTracker & + getSlotTrackerForModule(const llvm::Module *Module); }; } // namespace psr From 8da7c5b043509831144afdddfdd8997c8a90b82a Mon Sep 17 00:00:00 2001 From: Philipp Schubert Date: Wed, 5 Jan 2022 09:33:32 +0100 Subject: [PATCH 3/5] few minor adjustments --- external/googletest | 2 +- external/json-schema-validator | 2 +- include/phasar/PhasarLLVM/Utils/DOTGraph.h | 14 +++++++------- include/phasar/Utils/LLVMShorthands.h | 2 +- lib/Utils/LLVMShorthands.cpp | 2 -- 5 files changed, 10 insertions(+), 12 deletions(-) diff --git a/external/googletest b/external/googletest index 16f637fbf4..e2239ee604 160000 --- a/external/googletest +++ b/external/googletest @@ -1 +1 @@ -Subproject commit 16f637fbf4ffc3f7a01fa4eceb7906634565242f +Subproject commit e2239ee6043f73722e7aa812a459f54a28552929 diff --git a/external/json-schema-validator b/external/json-schema-validator index 89ed13d76b..27fc1d0945 160000 --- a/external/json-schema-validator +++ b/external/json-schema-validator @@ -1 +1 @@ -Subproject commit 89ed13d76b95a8dc5de1a26af85231d7dff61e47 +Subproject commit 27fc1d094503623dfe39365ba82581507524545c diff --git a/include/phasar/PhasarLLVM/Utils/DOTGraph.h b/include/phasar/PhasarLLVM/Utils/DOTGraph.h index d5494cb81c..0d9c12a4fe 100644 --- a/include/phasar/PhasarLLVM/Utils/DOTGraph.h +++ b/include/phasar/PhasarLLVM/Utils/DOTGraph.h @@ -58,8 +58,8 @@ class DOTConfig { private: DOTConfig() = default; - inline static const std::string fontSize = "fontsize=11"; // NOLINT - inline static const std::string arrowSize = "arrowsize=0.7"; // NOLINT + inline static const std::string FontSize = "fontsize=11"; + inline static const std::string ArrowSize = "arrowsize=0.7"; inline static std::string CFNode = // NOLINT "node [style=filled, shape=record]"; @@ -67,19 +67,19 @@ class DOTConfig { inline static std::string CFInterEdge = "edge [weight=0.1]"; // NOLINT inline static std::string FactNode = "node [style=rounded]"; // NOLINT inline static std::string FactIDEdge = // NOLINT - "edge [style=dotted, arrowhead=normal, " + fontSize + ", " + arrowSize + + "edge [style=dotted, arrowhead=normal, " + FontSize + ", " + ArrowSize + ']'; inline static std::string FactCrossEdge = // NOLINT - "edge [style=dotted, arrowhead=normal, " + fontSize + ", " + arrowSize + + "edge [style=dotted, arrowhead=normal, " + FontSize + ", " + ArrowSize + ']'; inline static std::string FactInterEdge = // NOLINT - "edge [weight=0.1, style=dashed, " + fontSize + ", " + arrowSize + ']'; + "edge [weight=0.1, style=dashed, " + FontSize + ", " + ArrowSize + ']'; inline static std::string LambdaNode = "node [style=rounded]"; // NOLINT inline static std::string LambdaIDEdge = // NOLINT - "edge [style=dotted, arrowhead=normal, " + fontSize + ", " + arrowSize + + "edge [style=dotted, arrowhead=normal, " + FontSize + ", " + ArrowSize + ']'; inline static std::string LambdaInterEdge = // NOLINT - "edge [weight=0.1, style=dashed, " + fontSize + ", " + arrowSize + ']'; + "edge [weight=0.1, style=dashed, " + FontSize + ", " + ArrowSize + ']'; }; struct DOTNode { diff --git a/include/phasar/Utils/LLVMShorthands.h b/include/phasar/Utils/LLVMShorthands.h index 1cf453b9e9..64e4b7f0c4 100644 --- a/include/phasar/Utils/LLVMShorthands.h +++ b/include/phasar/Utils/LLVMShorthands.h @@ -102,7 +102,7 @@ std::string getMetaDataID(const llvm::Value *V); */ struct LLVMValueIDLess { StringIDLess Sless; - LLVMValueIDLess(); + LLVMValueIDLess() : Sless(StringIDLess()) {} bool operator()(const llvm::Value *Lhs, const llvm::Value *Rhs) const; }; diff --git a/lib/Utils/LLVMShorthands.cpp b/lib/Utils/LLVMShorthands.cpp index e74ed88d94..692ef9c7e5 100644 --- a/lib/Utils/LLVMShorthands.cpp +++ b/lib/Utils/LLVMShorthands.cpp @@ -246,8 +246,6 @@ std::string getMetaDataID(const llvm::Value *V) { return "-1"; } -LLVMValueIDLess::LLVMValueIDLess() : Sless(StringIDLess()) {} - bool LLVMValueIDLess::operator()(const llvm::Value *Lhs, const llvm::Value *Rhs) const { std::string LhsId = getMetaDataID(Lhs); From 4b4f69ffc3b365538d3aab46568eaf232f1012c4 Mon Sep 17 00:00:00 2001 From: Philipp Schubert Date: Wed, 5 Jan 2022 10:22:30 +0100 Subject: [PATCH 4/5] define exceptions for variable naming in IDE solver --- .clang-tidy | 5 + .../DataFlowSolver/IfdsIde/Solver/IDESolver.h | 206 +++++++----------- .../DataFlowSolver/IfdsIde/Solver/PathEdge.h | 4 +- 3 files changed, 82 insertions(+), 133 deletions(-) diff --git a/.clang-tidy b/.clang-tidy index 03636444c0..3946d18add 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -5,6 +5,7 @@ Checks: '-*, -misc-non-private-member-variables-in-classes, -misc-no-recursion, readability-*, + -readability-function-cognitive-complexity, -readability-else-after*, -readability-simplify-boolean-expr, -readability-implicit-bool-cast, @@ -43,6 +44,10 @@ CheckOptions: value: CamelCase - key: readability-identifier-naming.VariableCase value: CamelCase + - key: readability-identifier-naming.VariableIgnoredRegexp + value: (c|d|d1|d2|d3|d4|d5|d5_restoredCtx|eP|f|f3|f4|f5|fCalleeSummary|g|n|dPrime|fPrime) + - key: readability-identifier-naming.ParameterIgnoredRegexp + value: (d|d1|d2|d3|d4|d5|eP|f|n) - key: cppcoreguidelines-special-member-functions.AllowSoleDefaultDtor value: 1 - key: cppcoreguidelines-special-member-functions.AllowMissingMoveFunctions diff --git a/include/phasar/PhasarLLVM/DataFlowSolver/IfdsIde/Solver/IDESolver.h b/include/phasar/PhasarLLVM/DataFlowSolver/IfdsIde/Solver/IDESolver.h index 0001fba8cf..2b20629399 100644 --- a/include/phasar/PhasarLLVM/DataFlowSolver/IfdsIde/Solver/IDESolver.h +++ b/include/phasar/PhasarLLVM/DataFlowSolver/IfdsIde/Solver/IDESolver.h @@ -465,12 +465,11 @@ class IDESolver LOG_IF_ENABLE(BOOST_LOG_SEV(lg::get(), DEBUG) << "Process call at target: " << IDEProblem.NtoString(Edge.getTarget())); - d_t d1 = Edge.factAtSource(); // NOLINT - keep close to algorithm notion - n_t n = Edge.getTarget(); // NOLINT - keep close to algorithm notion - // a call node; line 14... - d_t d2 = Edge.factAtTarget(); // NOLINT - keep close to algorithm notion - EdgeFunctionPtrType f = // NOLINT - keep close to algorithm notion - jumpFunction(Edge); + d_t d1 = Edge.factAtSource(); + n_t n = Edge.getTarget(); + // a call node; line 14... + d_t d2 = Edge.factAtTarget(); + EdgeFunctionPtrType f = jumpFunction(Edge); const std::set ReturnSiteNs = ICF->getReturnSitesOfCallAt(n); const std::set Callees = ICF->getCalleesOfCallAt(n); @@ -504,7 +503,7 @@ class IDESolver ADD_TO_HISTOGRAM("Data-flow facts", res.size(), 1, PAMM_SEVERITY_LEVEL::Full); saveEdges(n, ReturnSiteN, d2, Res, false); - for (d_t d3 : Res) { // NOLINT - keep close to algorithm notion + for (d_t d3 : Res) { EdgeFunctionPtrType SumEdgFnE = CachedFlowEdgeFunctions.getSummaryEdgeFunction(n, d2, ReturnSiteN, d3); @@ -537,11 +536,10 @@ class IDESolver BOOST_LOG_SEV(lg::get(), DEBUG) << ' '); } // if startPointsOf is empty, the called function is a declaration - for (n_t SP : - StartPointsOf) { // NOLINT - keep close to algorithm notion + for (n_t SP : StartPointsOf) { saveEdges(n, SP, d2, Res, true); // for each result node of the call-flow function - for (d_t d3 : Res) { // NOLINT - keep close to algorithm notion + for (d_t d3 : Res) { using TableCell = typename Table::Cell; // create initial self-loop @@ -570,13 +568,9 @@ class IDESolver for (const TableCell &Entry : endSummary( SP, d3)) { // TODO/FIXME: does the reference break the solver? - n_t eP = // NOLINT - keep close to algorithm notion - Entry.getRowKey(); - d_t d4 = Entry.getColumnKey(); // NOLINT - keep close to algorithm - // notion - EdgeFunctionPtrType - fCalleeSummary = // NOLINT - keep close to algorithm notion - Entry.getValue(); + n_t eP = Entry.getRowKey(); + d_t d4 = Entry.getColumnKey(); + EdgeFunctionPtrType fCalleeSummary = Entry.getValue(); // for each return site for (n_t RetSiteN : ReturnSiteNs) { // compute return-flow function @@ -590,19 +584,16 @@ class IDESolver PAMM_SEVERITY_LEVEL::Full); saveEdges(eP, RetSiteN, d4, ReturnedFacts, true); // for each target value of the function - for (d_t d5 : // NOLINT - keep close to algorithm notion - ReturnedFacts) { + for (d_t d5 : ReturnedFacts) { // update the caller-side summary function // get call edge function - EdgeFunctionPtrType - f4 = // NOLINT - keep close to algorithm notion + EdgeFunctionPtrType f4 = CachedFlowEdgeFunctions.getCallEdgeFunction( n, d2, SCalledProcN, d3); LOG_IF_ENABLE(BOOST_LOG_SEV(lg::get(), DEBUG) << "Queried Call Edge Function: " << f4->str()); // get return edge function - EdgeFunctionPtrType - f5 = // NOLINT - keep close to algorithm notion + EdgeFunctionPtrType f5 = CachedFlowEdgeFunctions.getReturnEdgeFunction( n, SCalledProcN, eP, d4, RetSiteN, d5); LOG_IF_ENABLE(BOOST_LOG_SEV(lg::get(), DEBUG) @@ -625,14 +616,12 @@ class IDESolver << f4->str(); BOOST_LOG_SEV(lg::get(), DEBUG) << " (return * calleeSummary * call)"); - EdgeFunctionPtrType - fPrime = // NOLINT - keep close to algorithm notion + EdgeFunctionPtrType fPrime = f4->composeWith(fCalleeSummary)->composeWith(f5); LOG_IF_ENABLE(BOOST_LOG_SEV(lg::get(), DEBUG) << " = " << fPrime->str(); BOOST_LOG_SEV(lg::get(), DEBUG) << ' '); - d_t d5_restoredCtx // NOLINT - keep close to algorithm notion - = restoreContextOnReturnedFact(n, d2, d5); + d_t d5_restoredCtx = restoreContextOnReturnedFact(n, d2, d5); // propagte the effects of the entire call LOG_IF_ENABLE(BOOST_LOG_SEV(lg::get(), DEBUG) << "Compose: " << fPrime->str() << " * " @@ -659,7 +648,7 @@ class IDESolver ADD_TO_HISTOGRAM("Data-flow facts", returnFacts.size(), 1, PAMM_SEVERITY_LEVEL::Full); saveEdges(n, ReturnSiteN, d2, ReturnFacts, false); - for (d_t d3 : ReturnFacts) { // NOLINT - keep close to algorithm notion + for (d_t d3 : ReturnFacts) { EdgeFunctionPtrType EdgeFnE = CachedFlowEdgeFunctions.getCallToRetEdgeFunction(n, d2, ReturnSiteN, d3, Callees); @@ -671,8 +660,7 @@ class IDESolver .push_back(EdgeFnE); } INC_COUNTER("EF Queries", 1, PAMM_SEVERITY_LEVEL::Full); - auto fPrime = // NOLINT - keep close to algorithm notion - f->composeWith(EdgeFnE); + auto fPrime = f->composeWith(EdgeFnE); LOG_IF_ENABLE(BOOST_LOG_SEV(lg::get(), DEBUG) << "Compose: " << EdgeFnE->str() << " * " << f->str() << " = " << fPrime->str(); @@ -692,11 +680,10 @@ class IDESolver LOG_IF_ENABLE(BOOST_LOG_SEV(lg::get(), DEBUG) << "Process normal at target: " << IDEProblem.NtoString(Edge.getTarget())); - d_t d1 = Edge.factAtSource(); // NOLINT - keep close to algorithm notion - n_t n = Edge.getTarget(); // NOLINT - keep close to algorithm notion - d_t d2 = Edge.factAtTarget(); // NOLINT - keep close to algorithm notion - EdgeFunctionPtrType f = // NOLINT - keep close to algorithm notion - jumpFunction(Edge); + d_t d1 = Edge.factAtSource(); + n_t n = Edge.getTarget(); + d_t d2 = Edge.factAtTarget(); + EdgeFunctionPtrType f = jumpFunction(Edge); for (const auto Fn : ICF->getSuccsOf(n)) { FlowFunctionPtrType FlowFunc = CachedFlowEdgeFunctions.getNormalFlowFunction(n, Fn); @@ -705,23 +692,22 @@ class IDESolver ADD_TO_HISTOGRAM("Data-flow facts", res.size(), 1, PAMM_SEVERITY_LEVEL::Full); saveEdges(n, Fn, d2, Res, false); - for (d_t d3 : Res) { // NOLINT - keep close to algorithm notion - EdgeFunctionPtrType g = // NOLINT - keep close to algorithm notion + for (d_t d3 : Res) { + EdgeFunctionPtrType g = CachedFlowEdgeFunctions.getNormalEdgeFunction(n, d2, Fn, d3); LOG_IF_ENABLE(BOOST_LOG_SEV(lg::get(), DEBUG) << "Queried Normal Edge Function: " << g->str()); - EdgeFunctionPtrType fprime = // NOLINT - keep close to algorithm notion - f->composeWith(g); + EdgeFunctionPtrType fPrime = f->composeWith(g); if (SolverConfig.emitESG()) { IntermediateEdgeFunctions[std::make_tuple(n, d2, Fn, d3)].push_back( g); } LOG_IF_ENABLE(BOOST_LOG_SEV(lg::get(), DEBUG) << "Compose: " << g->str() << " * " << f->str() - << " = " << fprime->str(); + << " = " << fPrime->str(); BOOST_LOG_SEV(lg::get(), DEBUG) << ' '); INC_COUNTER("EF Queries", 1, PAMM_SEVERITY_LEVEL::Full); - propagate(d1, Fn, d3, fprime, nullptr, false); + propagate(d1, Fn, d3, fPrime, nullptr, false); } } } @@ -736,10 +722,9 @@ class IDESolver continue; } for (const auto &Entry : - LookupResults->get()) { // TODO/FIXME: does the & break the solver? - d_t dPrime = Entry.first; // NOLINT - keep close to algorithm notion - EdgeFunctionPtrType fPrime = // NOLINT - keep close to algorithm notion - Entry.second; + LookupResults->get()) { // TODO/FIXME: does the & break the solver? + d_t dPrime = Entry.first; + EdgeFunctionPtrType fPrime = Entry.second; n_t SP = Stmt; l_t Val = val(SP, Fact); INC_COUNTER("Value Propagation", 1, PAMM_SEVERITY_LEVEL::Full); @@ -755,8 +740,7 @@ class IDESolver FlowFunctionPtrType CallFlowFunction = CachedFlowEdgeFunctions.getCallFlowFunction(Stmt, Callee); INC_COUNTER("FF Queries", 1, PAMM_SEVERITY_LEVEL::Full); - for (const d_t dPrime // NOLINT - keep close to algorithm notion - : CallFlowFunction->computeTargets(Fact)) { + for (const d_t dPrime : CallFlowFunction->computeTargets(Fact)) { EdgeFunctionPtrType EdgeFn = CachedFlowEdgeFunctions.getCallEdgeFunction(Stmt, Fact, Callee, dPrime); @@ -849,9 +833,7 @@ class IDESolver return AllTop; } - void addEndSummary( - n_t SP, d_t d1, n_t eP, d_t d2, // NOLINT - keep close to algorithm notion - EdgeFunctionPtrType f) { // NOLINT - keep close to algorithm notion + void addEndSummary(n_t SP, d_t d1, n_t eP, d_t d2, EdgeFunctionPtrType f) { // note: at this point we don't need to join with a potential previous f // because f is a jump function, which is already properly joined // within propagate(..) @@ -891,7 +873,7 @@ class IDESolver // should be made a callable at some point void valuePropagationTask(const std::pair NAndD) { - n_t n = NAndD.first; // NOLINT - keep close to algorithm notion + n_t n = NAndD.first; // our initial seeds are not necessarily method-start points but here they // should be treated as such the same also for unbalanced return sites in // an unbalanced problem @@ -910,19 +892,16 @@ class IDESolver // should be made a callable at some point void valueComputationTask(const std::vector &Values) { PAMM_GET_INSTANCE; - for (n_t n : Values) { // NOLINT - keep close to algorithm notion + for (n_t n : Values) { for (n_t SP : ICF->getStartPointsOf(ICF->getFunctionOf(n))) { using TableCell = typename Table::Cell; Table LookupByTarget; LookupByTarget = JumpFn->lookupByTarget(n); for (const TableCell &SourceValTargetValAndFunction : LookupByTarget.cellSet()) { - d_t dPrime // NOLINT - keep close to algorithm notion - = SourceValTargetValAndFunction.getRowKey(); - d_t d // NOLINT - keep close to algorithm notion - = SourceValTargetValAndFunction.getColumnKey(); - EdgeFunctionPtrType fPrime // NOLINT - keep close to algorithm notion - = SourceValTargetValAndFunction.getValue(); + d_t dPrime = SourceValTargetValAndFunction.getRowKey(); + d_t d = SourceValTargetValAndFunction.getColumnKey(); + EdgeFunctionPtrType fPrime = SourceValTargetValAndFunction.getValue(); l_t TargetVal = val(SP, dPrime); setVal(n, d, IDEProblem.join(val(n, d), @@ -1045,15 +1024,11 @@ class IDESolver LOG_IF_ENABLE(BOOST_LOG_SEV(lg::get(), DEBUG) << "Process exit at target: " << IDEProblem.NtoString(Edge.getTarget())); - n_t n // NOLINT - keep close to algorithm notion - = Edge.getTarget(); // an exit node; line 21... - EdgeFunctionPtrType f // NOLINT - keep close to algorithm notion - = jumpFunction(Edge); + n_t n = Edge.getTarget(); // an exit node; line 21... + EdgeFunctionPtrType f = jumpFunction(Edge); f_t FunctionThatNeedsSummary = ICF->getFunctionOf(n); - d_t d1 // NOLINT - keep close to algorithm notion - = Edge.factAtSource(); - d_t d2 // NOLINT - keep close to algorithm notion - = Edge.factAtTarget(); + d_t d1 = Edge.factAtSource(); + d_t d2 = Edge.factAtTarget(); // for each of the method's start points, determine incoming calls const std::set StartPointsOf = ICF->getStartPointsOf(FunctionThatNeedsSummary); @@ -1073,8 +1048,7 @@ class IDESolver //(see processCall(..)) for (const auto &Entry : Inc) { // TODO/FIXME: does & break the solver? // line 22 - n_t c // NOLINT - keep close to algorithm notion - = Entry.first; + n_t c = Entry.first; // for each return site for (n_t RetSiteC : ICF->getReturnSitesOfCallAt(c)) { // compute return-flow function @@ -1083,8 +1057,7 @@ class IDESolver c, FunctionThatNeedsSummary, n, RetSiteC); INC_COUNTER("FF Queries", 1, PAMM_SEVERITY_LEVEL::Full); // for each incoming-call value - for (d_t d4 // NOLINT - keep close to algorithm notion - : Entry.second) { + for (d_t d4 : Entry.second) { const container_type Targets = computeReturnFlowFunction(RetFunction, d1, d2, c, Entry.second); ADD_TO_HISTOGRAM("Data-flow facts", targets.size(), 1, @@ -1092,18 +1065,17 @@ class IDESolver saveEdges(n, RetSiteC, d2, Targets, true); // for each target value at the return site // line 23 - for (d_t d5 // NOLINT - keep close to algorithm notion - : Targets) { + for (d_t d5 : Targets) { // compute composed function // get call edge function - EdgeFunctionPtrType f4 // NOLINT - keep close to algorithm notion - = CachedFlowEdgeFunctions.getCallEdgeFunction( + EdgeFunctionPtrType f4 = + CachedFlowEdgeFunctions.getCallEdgeFunction( c, d4, ICF->getFunctionOf(n), d1); LOG_IF_ENABLE(BOOST_LOG_SEV(lg::get(), DEBUG) << "Queried Call Edge Function: " << f4->str()); // get return edge function - EdgeFunctionPtrType f5 // NOLINT - keep close to algorithm notion - = CachedFlowEdgeFunctions.getReturnEdgeFunction( + EdgeFunctionPtrType f5 = + CachedFlowEdgeFunctions.getReturnEdgeFunction( c, ICF->getFunctionOf(n), n, d2, RetSiteC, d5); LOG_IF_ENABLE(BOOST_LOG_SEV(lg::get(), DEBUG) << "Queried Return Edge Function: " << f5->str()); @@ -1122,9 +1094,7 @@ class IDESolver << " * " << f4->str(); BOOST_LOG_SEV(lg::get(), DEBUG) << " (return * function * call)"); - EdgeFunctionPtrType - fPrime // NOLINT - keep close to algorithm notion - = f4->composeWith(f)->composeWith(f5); + EdgeFunctionPtrType fPrime = f4->composeWith(f)->composeWith(f5); LOG_IF_ENABLE(BOOST_LOG_SEV(lg::get(), DEBUG) << " = " << fPrime->str(); BOOST_LOG_SEV(lg::get(), DEBUG) << ' '); @@ -1135,14 +1105,10 @@ class IDESolver for (const auto &ValAndFunc : RevLookupResult ->get()) { // TODO/FIXME: does & break the solver? - EdgeFunctionPtrType - f3 // NOLINT - keep close to algorithm notion - = ValAndFunc.second; + EdgeFunctionPtrType f3 = ValAndFunc.second; if (!f3->equal_to(AllTop)) { - d_t d3 = // NOLINT - keep close to algorithm notion - ValAndFunc.first; - d_t d5_restoredCtx // NOLINT - keep close to algorithm notion - = restoreContextOnReturnedFact(c, d4, d5); + d_t d3 = ValAndFunc.first; + d_t d5_restoredCtx = restoreContextOnReturnedFact(c, d4, d5); LOG_IF_ENABLE(BOOST_LOG_SEV(lg::get(), DEBUG) << "Compose: " << fPrime->str() << " * " << f3->str(); @@ -1176,10 +1142,9 @@ class IDESolver ADD_TO_HISTOGRAM("Data-flow facts", targets.size(), 1, PAMM_SEVERITY_LEVEL::Full); saveEdges(n, RetSiteC, d2, Targets, true); - for (d_t d5 // NOLINT - keep close to algorithm notion - : Targets) { - EdgeFunctionPtrType f5 // NOLINT - keep close to algorithm notion - = CachedFlowEdgeFunctions.getReturnEdgeFunction( + for (d_t d5 : Targets) { + EdgeFunctionPtrType f5 = + CachedFlowEdgeFunctions.getReturnEdgeFunction( Caller, ICF->getFunctionOf(n), n, d2, RetSiteC, d5); LOG_IF_ENABLE(BOOST_LOG_SEV(lg::get(), DEBUG) << "Queried Return Edge Function: " << f5->str()); @@ -1231,10 +1196,7 @@ class IDESolver /// Fact that originally should be propagated to the caller. /// @return Fact that will be propagated to the caller. /// - d_t restoreContextOnReturnedFact( - n_t /*CallSite*/, d_t /*d4*/, - d_t d5 // NOLINT - keep close to algorithm notion - ) { + d_t restoreContextOnReturnedFact(n_t /*CallSite*/, d_t /*d4*/, d_t d5) { // TODO support LinkedNode and JoinHandlingNode // if (d5 instanceof LinkedNode) { // ((LinkedNode) d5).setCallingContext(d4); @@ -1253,18 +1215,14 @@ class IDESolver /// @param d2 The abstraction at the current node /// @return The set of abstractions at the successor node /// - container_type - computeNormalFlowFunction(const FlowFunctionPtrType &FlowFunc, d_t /*d1*/, - d_t d2 // NOLINT - keep close to algorithm notion - ) { + container_type computeNormalFlowFunction(const FlowFunctionPtrType &FlowFunc, + d_t /*d1*/, d_t d2) { return FlowFunc->computeTargets(d2); } container_type computeSummaryFlowFunction(const FlowFunctionPtrType &SummaryFlowFunction, - d_t /*d1*/, - d_t d2 // NOLINT - keep close to algorithm notion - ) { + d_t /*d1*/, d_t d2) { return SummaryFlowFunction->computeTargets(d2); } @@ -1276,9 +1234,7 @@ class IDESolver /// container_type computeCallFlowFunction(const FlowFunctionPtrType &CallFlowFunction, - d_t /*d1*/, - d_t d2 // NOLINT - keep close to algorithm notion - ) { + d_t /*d1*/, d_t d2) { return CallFlowFunction->computeTargets(d2); } @@ -1291,9 +1247,7 @@ class IDESolver /// @return The set of caller-side abstractions at the return site /// container_type computeCallToReturnFlowFunction( - const FlowFunctionPtrType &CallToReturnFlowFunction, d_t /*d1*/, - d_t d2 // NOLINT - keep close to algorithm notion - ) { + const FlowFunctionPtrType &CallToReturnFlowFunction, d_t /*d1*/, d_t d2) { return CallToReturnFlowFunction->computeTargets(d2); } @@ -1306,10 +1260,10 @@ class IDESolver /// @param callerSideDs The abstractions at the call site /// @return The set of caller-side abstractions at the return site /// - container_type computeReturnFlowFunction( - const FlowFunctionPtrType &RetFlowFunction, d_t /*d1*/, - d_t d2, // NOLINT - keep close to algorithm notion - n_t /*CallSite*/, const Container & /*CallerSideDs*/) { + container_type + computeReturnFlowFunction(const FlowFunctionPtrType &RetFlowFunction, + d_t /*d1*/, d_t d2, n_t /*CallSite*/, + const Container & /*CallerSideDs*/) { return RetFlowFunction->computeTargets(d2); } @@ -1329,13 +1283,12 @@ class IDESolver /// unbalanced return (this value is not used within this implementation /// but may be useful for subclasses of {@link IDESolver}) /// - void propagate( - d_t SourceVal, n_t Target, d_t TargetVal, - const EdgeFunctionPtrType &f, // NOLINT - keep close to algorithm notion - /* deliberately exposed to clients */ - n_t /*RelatedCallSite*/, - /* deliberately exposed to clients */ - bool /*IsUnbalancedReturn*/) { + void propagate(d_t SourceVal, n_t Target, d_t TargetVal, + const EdgeFunctionPtrType &f, + /* deliberately exposed to clients */ + n_t /*RelatedCallSite*/, + /* deliberately exposed to clients */ + bool /*IsUnbalancedReturn*/) { LOG_IF_ENABLE(BOOST_LOG_SEV(lg::get(), DEBUG) << "Propagate flow"; BOOST_LOG_SEV(lg::get(), DEBUG) << "Source value : " << IDEProblem.DtoString(SourceVal); @@ -1362,8 +1315,7 @@ class IDESolver // jump function is initialized to all-top if no entry was found return AllTop; }(); - EdgeFunctionPtrType fPrime // NOLINT - keep close to algorithm notion - = JumpFnE->joinWith(f); + EdgeFunctionPtrType fPrime = JumpFnE->joinWith(f); bool NewFunction = !(fPrime->equal_to(JumpFnE)); LOG_IF_ENABLE(BOOST_LOG_SEV(lg::get(), DEBUG) @@ -1401,9 +1353,7 @@ class IDESolver } std::set::Cell> - endSummary(n_t SP, - d_t d3 // NOLINT - keep close to algorithm notion - ) { + endSummary(n_t SP, d_t d3) { if constexpr (PAMM_CURR_SEV_LEVEL >= PAMM_SEVERITY_LEVEL::Core) { auto Key = std::make_pair(SP, d3); auto FindND = FSummaryReuse.find(Key); @@ -1416,17 +1366,11 @@ class IDESolver return EndsummaryTab.get(SP, d3).cellSet(); } - std::map - incoming(d_t d1, // NOLINT - keep close to algorithm notion - n_t SP) { + std::map incoming(d_t d1, n_t SP) { return IncomingTab.get(SP, d1); } - void addIncoming(n_t SP, - d_t d3, // NOLINT - keep close to algorithm notion - n_t n, // NOLINT - keep close to algorithm notion - d_t d2 // NOLINT - keep close to algorithm notion - ) { + void addIncoming(n_t SP, d_t d3, n_t n, d_t d2) { IncomingTab.get(SP, d3)[n].insert(d2); } diff --git a/include/phasar/PhasarLLVM/DataFlowSolver/IfdsIde/Solver/PathEdge.h b/include/phasar/PhasarLLVM/DataFlowSolver/IfdsIde/Solver/PathEdge.h index 1137ede0ce..1b65f64752 100644 --- a/include/phasar/PhasarLLVM/DataFlowSolver/IfdsIde/Solver/PathEdge.h +++ b/include/phasar/PhasarLLVM/DataFlowSolver/IfdsIde/Solver/PathEdge.h @@ -48,8 +48,8 @@ template class PathEdge { [[nodiscard]] D factAtTarget() const { return DTarget; } friend std::ostream &operator<<(std::ostream &OS, const PathEdge &Edge) { - return OS << "<" << Edge.dSource << "> -> <" << Edge.target << "," - << Edge.dTarget << ">"; + return OS << "<" << Edge.DSource << "> -> <" << Edge.Target << "," + << Edge.DTarget << ">"; } }; From 346d9b8e52db2df43fdd701c2e7bca882f87701a Mon Sep 17 00:00:00 2001 From: Philipp Schubert Date: Wed, 5 Jan 2022 10:40:23 +0100 Subject: [PATCH 5/5] check and remove fixmes --- .../DataFlowSolver/IfdsIde/Solver/IDESolver.h | 54 +++++++------------ 1 file changed, 18 insertions(+), 36 deletions(-) diff --git a/include/phasar/PhasarLLVM/DataFlowSolver/IfdsIde/Solver/IDESolver.h b/include/phasar/PhasarLLVM/DataFlowSolver/IfdsIde/Solver/IDESolver.h index f4d484d004..846f728853 100644 --- a/include/phasar/PhasarLLVM/DataFlowSolver/IfdsIde/Solver/IDESolver.h +++ b/include/phasar/PhasarLLVM/DataFlowSolver/IfdsIde/Solver/IDESolver.h @@ -565,9 +565,7 @@ class IDESolver // , create new caller-side jump functions to the return // sites because we have observed a potentially new incoming // edge into - for (const TableCell &Entry : endSummary( - SP, - d3)) { // TODO/FIXME: does the reference break the solver? + for (const TableCell &Entry : endSummary(SP, d3)) { n_t eP = Entry.getRowKey(); d_t d4 = Entry.getColumnKey(); EdgeFunctionPtrType fCalleeSummary = Entry.getValue(); @@ -721,8 +719,7 @@ class IDESolver if (!LookupResults) { continue; } - for (const auto &Entry : - LookupResults->get()) { // TODO/FIXME: does the & break the solver? + for (const auto &Entry : LookupResults->get()) { d_t dPrime = Entry.first; EdgeFunctionPtrType fPrime = Entry.second; n_t SP = Stmt; @@ -1037,8 +1034,7 @@ class IDESolver // line 21.1 of Naeem/Lhotak/Rodriguez // register end-summary addEndSummary(SP, d1, n, d2, f); - for (const auto &Entry : - incoming(d1, SP)) { // FIXME: does & break the solver? + for (const auto &Entry : incoming(d1, SP)) { Inc[Entry.first] = Container{Entry.second}; } } @@ -1046,7 +1042,7 @@ class IDESolver printIncomingTab(); // for each incoming call edge already processed //(see processCall(..)) - for (const auto &Entry : Inc) { // TODO/FIXME: does & break the solver? + for (const auto &Entry : Inc) { // line 22 n_t c = Entry.first; // for each return site @@ -1102,9 +1098,7 @@ class IDESolver // return site using the composed function auto RevLookupResult = JumpFn->reverseLookup(c, d4); if (RevLookupResult) { - for (const auto &ValAndFunc : - RevLookupResult - ->get()) { // TODO/FIXME: does & break the solver? + for (const auto &ValAndFunc : RevLookupResult->get()) { EdgeFunctionPtrType f3 = ValAndFunc.second; if (!f3->equal_to(AllTop)) { d_t d3 = ValAndFunc.first; @@ -1378,18 +1372,15 @@ class IDESolver #ifdef DYNAMIC_LOG if (boost::log::core::get()->get_logging_enabled()) { BOOST_LOG_SEV(lg::get(), DEBUG) << "Start of incomingtab entry"; - for (const auto &Cell : - IncomingTab.cellSet()) { // TODO/FIXME: does & break the solver? + for (const auto &Cell : IncomingTab.cellSet()) { BOOST_LOG_SEV(lg::get(), DEBUG) << "sP: " << IDEProblem.NtoString(Cell.getRowKey()); BOOST_LOG_SEV(lg::get(), DEBUG) << "d3: " << IDEProblem.DtoString(Cell.getColumnKey()); - for (const auto &Entry : - Cell.getValue()) { // TODO/FIXME: does & break the solver? + for (const auto &Entry : Cell.getValue()) { BOOST_LOG_SEV(lg::get(), DEBUG) << " n: " << IDEProblem.NtoString(Entry.first); - for (const auto &Fact : - Entry.second) { // TODO/FIXME: does & break the solver? + for (const auto &Fact : Entry.second) { BOOST_LOG_SEV(lg::get(), DEBUG) << " d2: " << IDEProblem.DtoString(Fact); } @@ -1406,15 +1397,12 @@ class IDESolver #ifdef DYNAMIC_LOG if (boost::log::core::get()->get_logging_enabled()) { BOOST_LOG_SEV(lg::get(), DEBUG) << "Start of endsummarytab entry"; - for (const auto &Cell : - EndsummaryTab.cellVec()) { // TODO/FIXME: does & break the solver? + for (const auto &Cell : EndsummaryTab.cellVec()) { BOOST_LOG_SEV(lg::get(), DEBUG) << "sP: " << IDEProblem.NtoString(Cell.getRowKey()); BOOST_LOG_SEV(lg::get(), DEBUG) << "d1: " << IDEProblem.DtoString(Cell.getColumnKey()); - for (const auto &InnerCell : - Cell.getValue() - .cellVec()) { // TODO/FIXME: does & break the solver? + for (const auto &InnerCell : Cell.getValue().cellVec()) { BOOST_LOG_SEV(lg::get(), DEBUG) << " eP: " << IDEProblem.NtoString(InnerCell.getRowKey()); BOOST_LOG_SEV(lg::get(), DEBUG) @@ -1444,7 +1432,7 @@ class IDESolver sort(Cells.begin(), Cells.end(), [&Stmtless](auto Lhs, auto Rhs) { return Stmtless(Lhs.getRowKey(), Rhs.getRowKey()); }); - for (const auto &Cell : Cells) { // TODO/FIXME: does & break the solver? + for (const auto &Cell : Cells) { auto Edge = std::make_pair(Cell.getRowKey(), Cell.getColumnKey()); std::string N2Label = IDEProblem.NtoString(Edge.second); std::cout << "\nN1: " << IDEProblem.NtoString(Edge.first) << '\n' @@ -1470,7 +1458,7 @@ class IDESolver sort(Cells.begin(), Cells.end(), [&Stmtless](auto Lhs, auto Rhs) { return Stmtless(Lhs.getRowKey(), Rhs.getRowKey()); }); - for (const auto &Cell : Cells) { // TODO/FIXME: does & break the solver? + for (const auto &Cell : Cells) { auto Edge = std::make_pair(Cell.getRowKey(), Cell.getColumnKey()); std::string N2Label = IDEProblem.NtoString(Edge.second); std::cout << "\nN1: " << IDEProblem.NtoString(Edge.first) << '\n' @@ -1514,9 +1502,7 @@ class IDESolver // d1 --> d2-Set // Case 1: d1 in d2-Set // Case 2: d1 not in d2-Set, i.e., d1 was killed. d2-Set could be empty. - for (const auto &Cell : - ComputedIntraPathEdges - .cellSet()) { // TODO/FIXME: does & break the solver? + for (const auto &Cell : ComputedIntraPathEdges.cellSet()) { auto Edge = std::make_pair(Cell.getRowKey(), Cell.getColumnKey()); LOG_IF_ENABLE(BOOST_LOG_SEV(lg::get(), DEBUG) << "N1: " << IDEProblem.NtoString(Edge.first); @@ -1557,9 +1543,7 @@ class IDESolver LOG_IF_ENABLE(BOOST_LOG_SEV(lg::get(), DEBUG) << "=============================================="; BOOST_LOG_SEV(lg::get(), DEBUG) << "INTER PATH EDGES"); - for (const auto &Cell : - ComputedInterPathEdges - .cellSet()) { // TODO/FIXME: does & break the solver? + for (const auto &Cell : ComputedInterPathEdges.cellSet()) { auto Edge = std::make_pair(Cell.getRowKey(), Cell.getColumnKey()); LOG_IF_ENABLE(BOOST_LOG_SEV(lg::get(), DEBUG) << "N1: " << IDEProblem.NtoString(Edge.first); @@ -1646,8 +1630,7 @@ class IDESolver } LOG_IF_ENABLE(BOOST_LOG_SEV(lg::get(), DEBUG) << "SUMMARY REUSE"); std::size_t TotalSummaryReuse = 0; - for (const auto &Entry : - FSummaryReuse) { // TODO/FIXME: does & break the solver? + for (const auto &Entry : FSummaryReuse) { LOG_IF_ENABLE(BOOST_LOG_SEV(lg::get(), DEBUG) << "N1: " << IDEProblem.NtoString(Entry.first.first); BOOST_LOG_SEV(lg::get(), DEBUG) @@ -1726,7 +1709,7 @@ class IDESolver sort(Cells.begin(), Cells.end(), [&Stmtless](auto Lhs, auto Rhs) { return Stmtless(Lhs.getRowKey(), Rhs.getRowKey()); }); - for (const auto &Cell : Cells) { // TODO/FIXME: does & break the solver? + for (const auto &Cell : Cells) { auto Edge = std::make_pair(Cell.getRowKey(), Cell.getColumnKey()); std::string N1Label = IDEProblem.NtoString(Edge.first); std::string N2Label = IDEProblem.NtoString(Edge.second); @@ -1756,8 +1739,7 @@ class IDESolver DOTFactSubGraph *D1FSG = nullptr; unsigned D1FactId = 0; unsigned D2FactId = 0; - for (const auto &D1ToD2Set : - Cell.getValue()) { // TODO/FIXME: does & break the solver? + for (const auto &D1ToD2Set : Cell.getValue()) { auto D1Fact = D1ToD2Set.first; LOG_IF_ENABLE(BOOST_LOG_SEV(lg::get(), DEBUG) << "d1: " << IDEProblem.DtoString(D1Fact)); @@ -1826,7 +1808,7 @@ class IDESolver sort(Cells.begin(), Cells.end(), [&Stmtless](auto Lhs, auto Rhs) { return Stmtless(Lhs.getRowKey(), Rhs.getRowKey()); }); - for (const auto &Cell : Cells) { // TODO/FIXME: does & break the solver? + for (const auto &Cell : Cells) { auto Edge = std::make_pair(Cell.getRowKey(), Cell.getColumnKey()); std::string N1Label = IDEProblem.NtoString(Edge.first); std::string N2Label = IDEProblem.NtoString(Edge.second);