Skip to content

Commit

Permalink
dev: update AnalysisPrinterBase, integrate and fix tests
Browse files Browse the repository at this point in the history
  • Loading branch information
sritejakv committed Feb 14, 2024
1 parent ca7565b commit 54af9e6
Show file tree
Hide file tree
Showing 11 changed files with 61 additions and 71 deletions.
8 changes: 3 additions & 5 deletions include/phasar/PhasarLLVM/Utils/SourceMgrPrinter.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,9 @@ class SourceMgrPrinter : public AnalysisPrinterBase<AnalysisDomainTy> {
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()) {
Expand All @@ -47,7 +46,6 @@ class SourceMgrPrinter : public AnalysisPrinterBase<AnalysisDomainTy> {
}
}

private:
llvm::StringMap<unsigned> FileNameIDMap{};
llvm::SourceMgr SrcMgr{};
llvm::unique_function<std::string(DataFlowAnalysisType)> GetPrintMessage;
Expand Down
33 changes: 26 additions & 7 deletions include/phasar/Utils/AnalysisPrinterBase.h
Original file line number Diff line number Diff line change
@@ -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 <type_traits>

namespace psr {

template <typename AnalysisDomainTy> class AnalysisPrinterBase {
Expand All @@ -13,13 +16,22 @@ template <typename AnalysisDomainTy> 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 <typename L = l_t, typename = std::enable_if_t<!std::is_same_v<
std::decay_t<L>, psr::BinaryDomain>>>
void onResult(n_t Instr, d_t DfFact, l_t LatticeElement,
DataFlowAnalysisType AnalysisType) {
doOnResult(Instr, DfFact, LatticeElement, AnalysisType);
}

template <typename L = l_t, typename = std::enable_if_t<std::is_same_v<
std::decay_t<L>, 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;
Expand All @@ -28,6 +40,13 @@ template <typename AnalysisDomainTy> 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
Expand Down
9 changes: 4 additions & 5 deletions include/phasar/Utils/DefaultAnalysisPrinter.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,13 @@ class DefaultAnalysisPrinter : public AnalysisPrinterBase<AnalysisDomainTy> {
~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";
Expand All @@ -58,7 +58,6 @@ class DefaultAnalysisPrinter : public AnalysisPrinterBase<AnalysisDomainTy> {
}
}

private:
std::vector<Warning<AnalysisDomainTy>> AnalysisResults{};
MaybeUniquePtr<llvm::raw_ostream> OS = &llvm::outs();
};
Expand Down
8 changes: 3 additions & 5 deletions include/phasar/Utils/NullAnalysisPrinter.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,10 @@ class NullAnalysisPrinter final : public AnalysisPrinterBase<AnalysisDomainTy> {
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;
};

Expand Down
13 changes: 5 additions & 8 deletions include/phasar/Utils/OnTheFlyAnalysisPrinter.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,11 @@ class OnTheFlyAnalysisPrinter : public AnalysisPrinterBase<AnalysisDomainTy> {
OnTheFlyAnalysisPrinter<AnalysisDomainTy>() = default;
~OnTheFlyAnalysisPrinter<AnalysisDomainTy>() = 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";
Expand All @@ -41,11 +43,6 @@ class OnTheFlyAnalysisPrinter : public AnalysisPrinterBase<AnalysisDomainTy> {
}
}

void onFinalize() override{};

[[nodiscard]] bool isValid() const noexcept { return OS != nullptr; }

private:
MaybeUniquePtr<llvm::raw_ostream> OS = nullptr;
};
} // namespace psr
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
Expand Down Expand Up @@ -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);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ IFDSUninitializedVariables::getNormalFlowFunction(
!llvm::isa<llvm::CastInst>(Curr) &&
!llvm::isa<llvm::PHINode>(Curr)) {
UndefValueUses[Curr].insert(Operand);
Printer->onResult(Curr, Operand, BinaryDomain::TOP,
Printer->onResult(Curr, Operand,
DataFlowAnalysisType::IFDSUninitializedVariables);
}
return {Source, Curr};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ TEST_F(IDETaintAnalysisTest, XTaint09_1) {
TEST_F(IDETaintAnalysisTest, XTaint09) {
map<int, set<string>> Gt;

Gt[34] = {"33"};
Gt[25] = {"24"};

doAnalysis({PathToLLFiles + "xtaint09_cpp.ll"}, Gt, std::monostate{});
}
Expand Down
8 changes: 4 additions & 4 deletions unittests/Utils/AnalysisPrinterTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<int, std::set<std::string>> FoundLeak;
int SinkId = stoi(getMetaDataID(Instr));
std::set<std::string> LeakedValueIds;
Expand All @@ -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<int, std::set<std::string>> GroundTruth{};
};

Expand Down
8 changes: 4 additions & 4 deletions unittests/Utils/OnTheFlyAnalysisPrinterTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<int, std::set<std::string>> FoundLeak;
int SinkId = stoi(getMetaDataID(Instr));
std::set<std::string> LeakedValueIds;
Expand All @@ -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<int, std::set<std::string>> GroundTruth{};
};

Expand Down
37 changes: 8 additions & 29 deletions unittests/Utils/SourceMgrPrinterTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<LLVMIFDSAnalysisDomainDefault>::onResult(
Instr, DfFact, LatticeElement, AnalysisType);
findAndRemove(OS.str());
}

void onFinalize() override { EXPECT_TRUE(GroundTruth.empty()); }

private:
std::set<std::string> GroundTruth{};
std::string Str;
llvm::raw_string_ostream OS;
Expand Down

0 comments on commit 54af9e6

Please sign in to comment.