Skip to content

Commit 51a17e0

Browse files
committed
Add test
1 parent f1e0984 commit 51a17e0

File tree

5 files changed

+150
-10
lines changed

5 files changed

+150
-10
lines changed

include/phasar/PhasarLLVM/Pointer/FilteredLLVMAliasSet.h

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
#include "phasar/Pointer/AliasSetOwner.h"
1717
#include "phasar/Utils/AnalysisProperties.h"
1818
#include "phasar/Utils/MaybeUniquePtr.h"
19-
#include "phasar/Utils/StableVector.h"
2019

2120
#include "llvm/Support/ErrorHandling.h"
2221

@@ -53,9 +52,10 @@ class FilteredLLVMAliasSet {
5352

5453
FilteredLLVMAliasSet(const FilteredLLVMAliasSet &) = delete;
5554
FilteredLLVMAliasSet &operator=(const FilteredLLVMAliasSet &) = delete;
56-
FilteredLLVMAliasSet(FilteredLLVMAliasSet &&) = delete;
5755
FilteredLLVMAliasSet &operator=(FilteredLLVMAliasSet &&) = delete;
5856

57+
FilteredLLVMAliasSet(FilteredLLVMAliasSet &&) noexcept = default;
58+
5959
~FilteredLLVMAliasSet();
6060

6161
template <typename... ArgsT,
@@ -95,9 +95,9 @@ class FilteredLLVMAliasSet {
9595
llvm::report_fatal_error("Not Supported");
9696
}
9797

98-
void introduceAlias(const llvm::Value *V1, const llvm::Value *V2,
99-
const llvm::Instruction *I = nullptr,
100-
AliasResult Kind = AliasResult::MustAlias) {
98+
void introduceAlias(const llvm::Value * /*V1*/, const llvm::Value * /*V2*/,
99+
const llvm::Instruction * /*I*/ = nullptr,
100+
AliasResult /*Kind*/ = AliasResult::MustAlias) {
101101
llvm::report_fatal_error("Not Supported");
102102
}
103103

@@ -115,8 +115,7 @@ class FilteredLLVMAliasSet {
115115
FilteredLLVMAliasSet(MaybeUniquePtr<LLVMAliasSet, true> AS) noexcept;
116116

117117
MaybeUniquePtr<LLVMAliasSet, true> AS;
118-
AliasSetOwner<AliasSetTy>::memory_resource_type MRes;
119-
AliasSetOwner<AliasSetTy> Owner{&MRes};
118+
AliasSetOwner<AliasSetTy> Owner;
120119
llvm::DenseMap<std::pair<const llvm::Function *, v_t>, AliasSetPtrTy>
121120
AliasSetMap;
122121
};

lib/PhasarLLVM/DataFlow/IfdsIde/Problems/IFDSTaintAnalysis.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ void IFDSTaintAnalysis::populateWithMayAliases(
155155
container_type &Facts, const llvm::Instruction *Context) const {
156156
container_type Tmp = Facts;
157157
for (const auto *Fact : Facts) {
158-
auto Aliases = PT.getAliasSet(Fact);
158+
auto Aliases = PT.getAliasSet(Fact, Context);
159159
for (const auto *Alias : *Aliases) {
160160
if (canSkipAtContext(Alias, Context)) {
161161
continue;

lib/PhasarLLVM/Pointer/FilteredLLVMAliasSet.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,11 +112,13 @@ static void fillAliasSet(FilteredLLVMAliasSet::AliasSetTy &Set,
112112
}
113113

114114
FilteredLLVMAliasSet::FilteredLLVMAliasSet(LLVMAliasSet *AS) noexcept
115-
: AS(AS) {}
115+
: AS(AS), Owner(&AS->MRes) {}
116116

117117
FilteredLLVMAliasSet::FilteredLLVMAliasSet(
118118
MaybeUniquePtr<LLVMAliasSet, true> AS) noexcept
119-
: AS(std::move(AS)) {}
119+
: AS(std::move(AS)), Owner(&this->AS->MRes) {}
120+
121+
FilteredLLVMAliasSet::~FilteredLLVMAliasSet() = default;
120122

121123
AliasAnalysisType FilteredLLVMAliasSet::getAliasAnalysisType() const noexcept {
122124
return AS->getAliasAnalysisType();

unittests/PhasarLLVM/Pointer/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
set(ControlFlowSources
22
LLVMAliasSetTest.cpp
33
LLVMAliasSetSerializationTest.cpp
4+
FilteredLLVMAliasSetTest.cpp
45
)
56

67
foreach(TEST_SRC ${ControlFlowSources})
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
#include "phasar/PhasarLLVM/Pointer/FilteredLLVMAliasSet.h"
2+
3+
#include "phasar/ControlFlow/CallGraphAnalysisType.h"
4+
#include "phasar/DataFlow/IfdsIde/Solver/IFDSSolver.h"
5+
#include "phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h"
6+
#include "phasar/PhasarLLVM/DB/LLVMProjectIRDB.h"
7+
#include "phasar/PhasarLLVM/DataFlow/IfdsIde/Problems/IFDSTaintAnalysis.h"
8+
#include "phasar/PhasarLLVM/Pointer/LLVMAliasSet.h"
9+
#include "phasar/PhasarLLVM/TaintConfig/LLVMTaintConfig.h"
10+
#include "phasar/PhasarLLVM/Utils/LLVMShorthands.h"
11+
12+
#include "llvm/ADT/StringRef.h"
13+
#include "llvm/IR/InstrTypes.h"
14+
15+
#include "TestConfig.h"
16+
#include "gtest/gtest.h"
17+
18+
using namespace psr;
19+
20+
namespace {
21+
22+
static LLVMTaintConfig getDefaultConfig() {
23+
auto SourceCB = [](const llvm::Instruction *Inst) {
24+
std::set<const llvm::Value *> Ret;
25+
if (const auto *Call = llvm::dyn_cast<llvm::CallBase>(Inst);
26+
Call && Call->getCalledFunction() &&
27+
Call->getCalledFunction()->getName() == "_Z6sourcev") {
28+
Ret.insert(Call);
29+
}
30+
return Ret;
31+
};
32+
auto SinkCB = [](const llvm::Instruction *Inst) {
33+
std::set<const llvm::Value *> Ret;
34+
if (const auto *Call = llvm::dyn_cast<llvm::CallBase>(Inst);
35+
Call && Call->getCalledFunction() &&
36+
Call->getCalledFunction()->getName() == "_Z4sinki") {
37+
assert(Call->arg_size() > 0);
38+
Ret.insert(Call->getArgOperand(0));
39+
}
40+
return Ret;
41+
};
42+
return LLVMTaintConfig(std::move(SourceCB), std::move(SinkCB));
43+
}
44+
45+
static LLVMTaintConfig getDoubleFreeConfig() {
46+
auto SourceCB = [](const llvm::Instruction *Inst) {
47+
std::set<const llvm::Value *> Ret;
48+
if (const auto *Call = llvm::dyn_cast<llvm::CallBase>(Inst);
49+
Call && Call->getCalledFunction() &&
50+
Call->getCalledFunction()->getName() == "free") {
51+
Ret.insert(Call->getArgOperand(0));
52+
}
53+
return Ret;
54+
};
55+
56+
return LLVMTaintConfig(SourceCB, SourceCB);
57+
}
58+
59+
class TaintAnalysis : public ::testing::TestWithParam<std::string_view> {
60+
protected:
61+
static constexpr auto PathToLlFiles =
62+
PHASAR_BUILD_SUBFOLDER("taint_analysis/");
63+
const std::vector<std::string> EntryPoints = {"main"};
64+
65+
}; // Test Fixture
66+
67+
TEST_P(TaintAnalysis, LeaksWithAndWithoutAliasFilteringEqual) {
68+
69+
LLVMProjectIRDB IRDB(PathToLlFiles + GetParam());
70+
LLVMAliasSet AS(&IRDB, false);
71+
FilteredLLVMAliasSet FAS(&AS);
72+
LLVMBasedICFG ICF(&IRDB, CallGraphAnalysisType::OTF, EntryPoints, nullptr,
73+
&AS);
74+
75+
auto TSF = llvm::StringRef(GetParam()).startswith("double_free")
76+
? getDoubleFreeConfig()
77+
: getDefaultConfig();
78+
79+
IFDSTaintAnalysis TaintProblem(&IRDB, &AS, &TSF, EntryPoints);
80+
IFDSTaintAnalysis FilterTaintProblem(&IRDB, &FAS, &TSF, EntryPoints);
81+
82+
solveIFDSProblem(TaintProblem, ICF).dumpResults(ICF);
83+
solveIFDSProblem(FilterTaintProblem, ICF).dumpResults(ICF);
84+
85+
EXPECT_EQ(TaintProblem.Leaks.size(), FilterTaintProblem.Leaks.size());
86+
87+
for (const auto &[LeakInst, LeakFacts] : TaintProblem.Leaks) {
88+
const auto It = FilterTaintProblem.Leaks.find(LeakInst);
89+
90+
EXPECT_NE(It, FilterTaintProblem.Leaks.end())
91+
<< "Expected to find leak at " + llvmIRToString(LeakInst);
92+
93+
if (It == FilterTaintProblem.Leaks.end()) {
94+
continue;
95+
}
96+
97+
for (const auto *LeakFact : LeakFacts) {
98+
EXPECT_TRUE(It->second.count(LeakFact))
99+
<< "Expected to find leak-fact " + llvmIRToShortString(LeakFact) +
100+
" at " + llvmIRToString(LeakInst);
101+
}
102+
}
103+
}
104+
105+
static constexpr std::string_view TaintTestFiles[] = {
106+
// -- dummy-source-sink
107+
"dummy_source_sink/taint_01_cpp_dbg.ll",
108+
"dummy_source_sink/taint_01_cpp_m2r_dbg.ll",
109+
"dummy_source_sink/taint_02_cpp_dbg.ll",
110+
"dummy_source_sink/taint_03_cpp_dbg.ll",
111+
"dummy_source_sink/taint_04_cpp_dbg.ll",
112+
"dummy_source_sink/taint_05_cpp_dbg.ll",
113+
"dummy_source_sink/taint_06_cpp_m2r_dbg.ll",
114+
"dummy_source_sink/taint_exception_01_cpp_dbg.ll",
115+
"dummy_source_sink/taint_exception_01_cpp_m2r_dbg.ll",
116+
"dummy_source_sink/taint_exception_02_cpp_dbg.ll",
117+
"dummy_source_sink/taint_exception_03_cpp_dbg.ll",
118+
"dummy_source_sink/taint_exception_04_cpp_dbg.ll",
119+
"dummy_source_sink/taint_exception_05_cpp_dbg.ll",
120+
"dummy_source_sink/taint_exception_06_cpp_dbg.ll",
121+
"dummy_source_sink/taint_exception_07_cpp_dbg.ll",
122+
"dummy_source_sink/taint_exception_08_cpp_dbg.ll",
123+
"dummy_source_sink/taint_exception_09_cpp_dbg.ll",
124+
"dummy_source_sink/taint_exception_10_cpp_dbg.ll",
125+
// -- double-free
126+
"double_free_01_c.ll",
127+
"double_free_02_c.ll",
128+
};
129+
130+
INSTANTIATE_TEST_SUITE_P(InteractiveIDESolverTest, TaintAnalysis,
131+
::testing::ValuesIn(TaintTestFiles));
132+
133+
} // namespace
134+
135+
int main(int Argc, char **Argv) {
136+
::testing::InitGoogleTest(&Argc, Argv);
137+
return RUN_ALL_TESTS();
138+
}

0 commit comments

Comments
 (0)