From 54af9e6f39e91c8df121712c6c88d7d1f154ea0c Mon Sep 17 00:00:00 2001 From: Sriteja Kummita Date: Wed, 14 Feb 2024 12:13:02 +0100 Subject: [PATCH] dev: update AnalysisPrinterBase, integrate and fix tests --- .../PhasarLLVM/Utils/SourceMgrPrinter.h | 8 ++-- include/phasar/Utils/AnalysisPrinterBase.h | 33 +++++++++++++---- include/phasar/Utils/DefaultAnalysisPrinter.h | 9 ++--- include/phasar/Utils/NullAnalysisPrinter.h | 8 ++-- .../phasar/Utils/OnTheFlyAnalysisPrinter.h | 13 +++---- .../IfdsIde/Problems/IFDSTaintAnalysis.cpp | 4 +- .../Problems/IFDSUninitializedVariables.cpp | 2 +- .../Problems/IDEExtendedTaintAnalysisTest.cpp | 2 +- unittests/Utils/AnalysisPrinterTest.cpp | 8 ++-- .../Utils/OnTheFlyAnalysisPrinterTest.cpp | 8 ++-- unittests/Utils/SourceMgrPrinterTest.cpp | 37 ++++--------------- 11 files changed, 61 insertions(+), 71 deletions(-) diff --git a/include/phasar/PhasarLLVM/Utils/SourceMgrPrinter.h b/include/phasar/PhasarLLVM/Utils/SourceMgrPrinter.h index 4848b43a8..5cb4768f7 100644 --- a/include/phasar/PhasarLLVM/Utils/SourceMgrPrinter.h +++ b/include/phasar/PhasarLLVM/Utils/SourceMgrPrinter.h @@ -29,10 +29,9 @@ class SourceMgrPrinter : public AnalysisPrinterBase { llvm::raw_ostream &OS = llvm::errs()) : GetPrintMessage(std::move(PrintMessage)), OS(&OS) {} - void onInitialize() override {} - void onFinalize() override {} - void onResult(n_t Instr, d_t /*DfFact*/, l_t /*Lattice*/, - DataFlowAnalysisType AnalysisType) override { +private: + void doOnResult(n_t Instr, d_t /*DfFact*/, l_t /*Lattice*/, + DataFlowAnalysisType AnalysisType) override { auto BufIdOpt = getSourceBufId(getFilePathFromIR(Instr), FileNameIDMap, SrcMgr); if (BufIdOpt.has_value()) { @@ -47,7 +46,6 @@ class SourceMgrPrinter : public AnalysisPrinterBase { } } -private: llvm::StringMap FileNameIDMap{}; llvm::SourceMgr SrcMgr{}; llvm::unique_function GetPrintMessage; diff --git a/include/phasar/Utils/AnalysisPrinterBase.h b/include/phasar/Utils/AnalysisPrinterBase.h index a2eda5d99..a1ca6aee3 100644 --- a/include/phasar/Utils/AnalysisPrinterBase.h +++ b/include/phasar/Utils/AnalysisPrinterBase.h @@ -1,10 +1,13 @@ #ifndef PHASAR_PHASARLLVM_UTILS_ANALYSISPRINTERBASE_H #define PHASAR_PHASARLLVM_UTILS_ANALYSISPRINTERBASE_H +#include "phasar/Domain/BinaryDomain.h" #include "phasar/PhasarLLVM/Utils/DataFlowAnalysisType.h" #include "llvm/Support/raw_ostream.h" +#include + namespace psr { template class AnalysisPrinterBase { @@ -13,13 +16,22 @@ template class AnalysisPrinterBase { using l_t = typename AnalysisDomainTy::l_t; public: - /// TODO: use non-virtual function to call virtual function with default - /// parameters + - /// TODO: templace magic - #include "memory_resource" - virtual void onResult(n_t /*Instr*/, d_t /*DfFact*/, l_t /*LatticeElement*/, - DataFlowAnalysisType /*AnalysisType*/) = 0; - virtual void onInitialize() = 0; - virtual void onFinalize() = 0; + template , psr::BinaryDomain>>> + void onResult(n_t Instr, d_t DfFact, l_t LatticeElement, + DataFlowAnalysisType AnalysisType) { + doOnResult(Instr, DfFact, LatticeElement, AnalysisType); + } + + template , psr::BinaryDomain>>> + void onResult(n_t Instr, d_t DfFact, DataFlowAnalysisType AnalysisType) { + doOnResult(Instr, DfFact, psr::BinaryDomain::BOTTOM, AnalysisType); + } + + void onInitialize() { doOnInitialize(); } + + void onFinalize() { doOnFinalize(); } AnalysisPrinterBase() = default; virtual ~AnalysisPrinterBase() = default; @@ -28,6 +40,13 @@ template class AnalysisPrinterBase { AnalysisPrinterBase(AnalysisPrinterBase &&) = delete; AnalysisPrinterBase &operator=(AnalysisPrinterBase &&) = delete; + +private: + virtual void doOnResult(n_t /*Instr*/, d_t /*DfFact*/, l_t /*LatticeElement*/, + DataFlowAnalysisType /*AnalysisType*/) = 0; + + virtual void doOnInitialize() {} + virtual void doOnFinalize() {} }; } // namespace psr diff --git a/include/phasar/Utils/DefaultAnalysisPrinter.h b/include/phasar/Utils/DefaultAnalysisPrinter.h index da601e7d0..fcf4aeb13 100644 --- a/include/phasar/Utils/DefaultAnalysisPrinter.h +++ b/include/phasar/Utils/DefaultAnalysisPrinter.h @@ -39,13 +39,13 @@ class DefaultAnalysisPrinter : public AnalysisPrinterBase { ~DefaultAnalysisPrinter() override = default; DefaultAnalysisPrinter(llvm::raw_ostream &OS = llvm::outs()) : OS(&OS) {} - void onResult(n_t Instr, d_t DfFact, l_t Lattice, - DataFlowAnalysisType AnalysisType) override { +private: + void doOnResult(n_t Instr, d_t DfFact, l_t Lattice, + DataFlowAnalysisType AnalysisType) override { AnalysisResults.emplace_back(Instr, DfFact, Lattice, AnalysisType); } - void onInitialize() override{}; - void onFinalize() override { + void doOnFinalize() override { for (const auto &Iter : AnalysisResults) { *OS << "\nAt IR statement: " << NToString(Iter.Instr) << "\n"; @@ -58,7 +58,6 @@ class DefaultAnalysisPrinter : public AnalysisPrinterBase { } } -private: std::vector> AnalysisResults{}; MaybeUniquePtr OS = &llvm::outs(); }; diff --git a/include/phasar/Utils/NullAnalysisPrinter.h b/include/phasar/Utils/NullAnalysisPrinter.h index 7e07fd271..8527cc3c8 100644 --- a/include/phasar/Utils/NullAnalysisPrinter.h +++ b/include/phasar/Utils/NullAnalysisPrinter.h @@ -17,12 +17,10 @@ class NullAnalysisPrinter final : public AnalysisPrinterBase { return &Instance; } - void onInitialize() override{}; - void onResult(n_t /*Instr*/, d_t /*DfFact*/, l_t /*Lattice*/, - DataFlowAnalysisType /*AnalysisType*/) override{}; - void onFinalize() override{}; - private: + void doOnResult(n_t /*Instr*/, d_t /*DfFact*/, l_t /*Lattice*/, + DataFlowAnalysisType /*AnalysisType*/) override{}; + NullAnalysisPrinter() = default; }; diff --git a/include/phasar/Utils/OnTheFlyAnalysisPrinter.h b/include/phasar/Utils/OnTheFlyAnalysisPrinter.h index 72400bb07..08be84dda 100644 --- a/include/phasar/Utils/OnTheFlyAnalysisPrinter.h +++ b/include/phasar/Utils/OnTheFlyAnalysisPrinter.h @@ -30,9 +30,11 @@ class OnTheFlyAnalysisPrinter : public AnalysisPrinterBase { OnTheFlyAnalysisPrinter() = default; ~OnTheFlyAnalysisPrinter() = default; - void onInitialize() override{}; - void onResult(n_t Instr, d_t DfFact, l_t LatticeElement, - DataFlowAnalysisType /*AnalysisType*/) override { + [[nodiscard]] bool isValid() const noexcept { return OS != nullptr; } + +private: + void doOnResult(n_t Instr, d_t DfFact, l_t LatticeElement, + DataFlowAnalysisType /*AnalysisType*/) override { assert(isValid()); *OS << "\nAt IR statement: " << NToString(Instr) << "\n"; *OS << "\tFact: " << DToString(DfFact) << "\n"; @@ -41,11 +43,6 @@ class OnTheFlyAnalysisPrinter : public AnalysisPrinterBase { } } - void onFinalize() override{}; - - [[nodiscard]] bool isValid() const noexcept { return OS != nullptr; } - -private: MaybeUniquePtr OS = nullptr; }; } // namespace psr diff --git a/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/IFDSTaintAnalysis.cpp b/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/IFDSTaintAnalysis.cpp index a8c37bde4..a39fbee4b 100644 --- a/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/IFDSTaintAnalysis.cpp +++ b/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/IFDSTaintAnalysis.cpp @@ -411,7 +411,7 @@ auto IFDSTaintAnalysis::getSummaryFlowFunction([[maybe_unused]] n_t CallSite, CallSite](d_t Source) -> container_type { if (Leak.count(Source)) { if (Leaks[CallSite].insert(Source).second) { - Printer->onResult(CallSite, Source, topElement(), + Printer->onResult(CallSite, Source, DataFlowAnalysisType::IFDSTaintAnalysis); } } @@ -439,7 +439,7 @@ auto IFDSTaintAnalysis::getSummaryFlowFunction([[maybe_unused]] n_t CallSite, if (Leak.count(Source)) { if (Leaks[CallSite].insert(Source).second) { - Printer->onResult(CallSite, Source, topElement(), + Printer->onResult(CallSite, Source, DataFlowAnalysisType::IFDSTaintAnalysis); } } diff --git a/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/IFDSUninitializedVariables.cpp b/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/IFDSUninitializedVariables.cpp index 0640f4e8a..68e360b35 100644 --- a/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/IFDSUninitializedVariables.cpp +++ b/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/IFDSUninitializedVariables.cpp @@ -204,7 +204,7 @@ IFDSUninitializedVariables::getNormalFlowFunction( !llvm::isa(Curr) && !llvm::isa(Curr)) { UndefValueUses[Curr].insert(Operand); - Printer->onResult(Curr, Operand, BinaryDomain::TOP, + Printer->onResult(Curr, Operand, DataFlowAnalysisType::IFDSUninitializedVariables); } return {Source, Curr}; diff --git a/unittests/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEExtendedTaintAnalysisTest.cpp b/unittests/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEExtendedTaintAnalysisTest.cpp index 806cb58e2..4862f1274 100644 --- a/unittests/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEExtendedTaintAnalysisTest.cpp +++ b/unittests/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEExtendedTaintAnalysisTest.cpp @@ -208,7 +208,7 @@ TEST_F(IDETaintAnalysisTest, XTaint09_1) { TEST_F(IDETaintAnalysisTest, XTaint09) { map> Gt; - Gt[34] = {"33"}; + Gt[25] = {"24"}; doAnalysis({PathToLLFiles + "xtaint09_cpp.ll"}, Gt, std::monostate{}); } diff --git a/unittests/Utils/AnalysisPrinterTest.cpp b/unittests/Utils/AnalysisPrinterTest.cpp index 976d27217..34a110d53 100644 --- a/unittests/Utils/AnalysisPrinterTest.cpp +++ b/unittests/Utils/AnalysisPrinterTest.cpp @@ -43,8 +43,9 @@ class GroundTruthCollector } } - void onResult(n_t Instr, d_t DfFact, l_t /*LatticeElement*/, - DataFlowAnalysisType /*AnalysisType*/) override { +private: + void doOnResult(n_t Instr, d_t DfFact, l_t /*LatticeElement*/, + DataFlowAnalysisType /*AnalysisType*/) override { llvm::DenseMap> FoundLeak; int SinkId = stoi(getMetaDataID(Instr)); std::set LeakedValueIds; @@ -53,9 +54,8 @@ class GroundTruthCollector findAndRemove(FoundLeak, GroundTruth); } - void onFinalize() override { EXPECT_TRUE(GroundTruth.empty()); } + void doOnFinalize() override { EXPECT_TRUE(GroundTruth.empty()); } -private: llvm::DenseMap> GroundTruth{}; }; diff --git a/unittests/Utils/OnTheFlyAnalysisPrinterTest.cpp b/unittests/Utils/OnTheFlyAnalysisPrinterTest.cpp index 5632c614c..51d793ec1 100644 --- a/unittests/Utils/OnTheFlyAnalysisPrinterTest.cpp +++ b/unittests/Utils/OnTheFlyAnalysisPrinterTest.cpp @@ -37,8 +37,9 @@ class GroundTruthCollector } } - void onResult(n_t Instr, d_t DfFact, l_t /*LatticeElement*/, - DataFlowAnalysisType /*AnalysisType*/) override { +private: + void doOnResult(n_t Instr, d_t DfFact, l_t /*LatticeElement*/, + DataFlowAnalysisType /*AnalysisType*/) override { llvm::DenseMap> FoundLeak; int SinkId = stoi(getMetaDataID(Instr)); std::set LeakedValueIds; @@ -47,9 +48,8 @@ class GroundTruthCollector findAndRemove(FoundLeak, GroundTruth); } - void onFinalize() override { EXPECT_TRUE(GroundTruth.empty()); } + void doOnFinalize() override { EXPECT_TRUE(GroundTruth.empty()); } -private: llvm::DenseMap> GroundTruth{}; }; diff --git a/unittests/Utils/SourceMgrPrinterTest.cpp b/unittests/Utils/SourceMgrPrinterTest.cpp index 1592e3a05..8fda92182 100644 --- a/unittests/Utils/SourceMgrPrinterTest.cpp +++ b/unittests/Utils/SourceMgrPrinterTest.cpp @@ -32,39 +32,18 @@ class GroundTruthCollector [](DataFlowAnalysisType) { return ""; }, OS), GroundTruth(GroundTruth), OS(Str){}; - std::string findSubString(const std::string &String) { - size_t LastSlashPos = String.rfind('/'); - if (LastSlashPos != std::string::npos) { - // Find the first space after the last '/' - size_t FirstSpacePos = String.find(' ', LastSlashPos); - - if (FirstSpacePos != std::string::npos) { - // Extract the substring from the last '/' to the first space after - // the last '/' - std::string Result = - String.substr(LastSlashPos + 1, FirstSpacePos - LastSlashPos - 2); - return Result; +private: + void doOnFinalize() override { + for (auto It = GroundTruth.begin(); It != GroundTruth.end();) { + if (OS.str().find(*It)) { + GroundTruth.erase(It++); + } else { + ++It; } - return ""; } - return ""; - } - - void findAndRemove(const std::string &SearchString) { - std::string SubString = findSubString(SearchString); - GroundTruth.erase(SubString); + EXPECT_TRUE(GroundTruth.empty()); } - void onResult(n_t Instr, d_t DfFact, l_t LatticeElement, - DataFlowAnalysisType AnalysisType) override { - SourceMgrPrinter::onResult( - Instr, DfFact, LatticeElement, AnalysisType); - findAndRemove(OS.str()); - } - - void onFinalize() override { EXPECT_TRUE(GroundTruth.empty()); } - -private: std::set GroundTruth{}; std::string Str; llvm::raw_string_ostream OS;