Skip to content

Commit a427038

Browse files
fabianbs96MMory
andauthored
Fix and Simplify Initial Seeds (#600)
* Fix initial seeds not skipping debug instructions + add default seeds * Some cleanup in EntryPointUtils * minor --------- Co-authored-by: Martin Mory <mmo@mail.upb.de>
1 parent 900ae45 commit a427038

19 files changed

+189
-154
lines changed

include/phasar/DB/ProjectIRDBBase.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,15 @@ template <typename Derived> class ProjectIRDBBase {
158158
return static_cast<const Derived &>(*this);
159159
}
160160
};
161+
162+
template <typename DB>
163+
// NOLINTNEXTLINE(readability-identifier-naming)
164+
auto IRDBGetFunctionDef(const ProjectIRDBBase<DB> *IRDB) noexcept {
165+
return [IRDB](llvm::StringRef Name) {
166+
return IRDB->getFunctionDefinition(Name);
167+
};
168+
}
169+
161170
} // namespace psr
162171

163172
#endif // PHASAR_DB_PROJECTIRDBBASE_H
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
/******************************************************************************
2+
* Copyright (c) 2023 Fabian Schiebel.
3+
* All rights reserved. This program and the accompanying materials are made
4+
* available under the terms of LICENSE.txt.
5+
*
6+
* Contributors:
7+
* Fabian Schiebel and others
8+
*****************************************************************************/
9+
10+
#ifndef PHASAR_DATAFLOW_IFDSIDE_ENTRYPOINTUTILS_H
11+
#define PHASAR_DATAFLOW_IFDSIDE_ENTRYPOINTUTILS_H
12+
13+
#include "phasar/ControlFlow/CFGBase.h"
14+
#include "phasar/DB/ProjectIRDBBase.h"
15+
16+
#include "llvm/ADT/STLExtras.h"
17+
18+
#include <functional>
19+
20+
namespace psr {
21+
22+
namespace detail {
23+
template <typename EntryRange, typename C, typename HandlerFn>
24+
void forallStartingPoints(const EntryRange &EntryPoints, const CFGBase<C> &CFG,
25+
HandlerFn Handler) {
26+
for (const auto &EntryPointFn : EntryPoints) {
27+
if constexpr (std::is_convertible_v<std::decay_t<decltype(EntryPointFn)>,
28+
bool>) {
29+
if (!EntryPointFn) {
30+
continue;
31+
}
32+
}
33+
for (const auto &SP : CFG.getStartPointsOf(EntryPointFn)) {
34+
std::invoke(Handler, SP);
35+
}
36+
}
37+
}
38+
39+
template <typename EntryRange, typename C, typename ICFGorIRDB,
40+
typename HandlerFn>
41+
void forallStartingPoints(const EntryRange &EntryPoints, const ICFGorIRDB *ICDB,
42+
const CFGBase<C> &CFG, HandlerFn Handler) {
43+
44+
if (llvm::hasSingleElement(EntryPoints) &&
45+
*llvm::adl_begin(EntryPoints) == "__ALL__") {
46+
forallStartingPoints(ICDB->getAllFunctions(), CFG, std::move(Handler));
47+
} else {
48+
forallStartingPoints(llvm::map_range(EntryPoints,
49+
[ICDB](llvm::StringRef Name) {
50+
return ICDB->getFunction(Name);
51+
}),
52+
CFG, std::move(Handler));
53+
}
54+
}
55+
56+
} // namespace detail
57+
58+
template <typename EntryRange, typename C, typename DB, typename HandlerFn>
59+
void forallStartingPoints(const EntryRange &EntryPoints,
60+
const ProjectIRDBBase<DB> *IRDB,
61+
const CFGBase<C> &CFG, HandlerFn Handler) {
62+
return detail::forallStartingPoints(EntryPoints, IRDB, CFG,
63+
std::move(Handler));
64+
}
65+
66+
template <typename EntryRange, typename I, typename HandlerFn>
67+
void forallStartingPoints(const EntryRange &EntryPoints, const I *ICF,
68+
HandlerFn Handler) {
69+
detail::forallStartingPoints(EntryPoints, ICF, *ICF, std::move(Handler));
70+
}
71+
72+
template <typename EntryRange, typename C, typename DB, typename SeedsT,
73+
typename D, typename L>
74+
void addSeedsForStartingPoints(const EntryRange &EntryPoints,
75+
const ProjectIRDBBase<DB> *IRDB,
76+
const CFGBase<C> &CFG, SeedsT &Seeds,
77+
const D &ZeroValue, const L &BottomValue) {
78+
forallStartingPoints(EntryPoints, IRDB, CFG,
79+
[&Seeds, &ZeroValue, &BottomValue](const auto &SP) {
80+
Seeds.addSeed(SP, ZeroValue, BottomValue);
81+
});
82+
}
83+
84+
template <typename EntryRange, typename I, typename SeedsT, typename D,
85+
typename L>
86+
void addSeedsForStartingPoints(const EntryRange &EntryPoints, const I *ICF,
87+
SeedsT &Seeds, const D &ZeroValue,
88+
const L &BottomValue) {
89+
forallStartingPoints(EntryPoints, ICF,
90+
[&Seeds, &ZeroValue, &BottomValue](const auto &SP) {
91+
Seeds.addSeed(SP, ZeroValue, BottomValue);
92+
});
93+
}
94+
} // namespace psr
95+
96+
#endif // PHASAR_DATAFLOW_IFDSIDE_ENTRYPOINTUTILS_H

include/phasar/DataFlow/IfdsIde/IDETabulationProblem.h

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,13 @@
77
* Philipp Schubert, Fabian Schiebel and others
88
*****************************************************************************/
99

10-
#ifndef PHASAR_PHASARLLVM_DATAFLOWSOLVER_IFDSIDE_IDETABULATIONPROBLEM_H_
11-
#define PHASAR_PHASARLLVM_DATAFLOWSOLVER_IFDSIDE_IDETABULATIONPROBLEM_H_
10+
#ifndef PHASAR_DATAFLOW_IFDSIDE_IDETABULATIONPROBLEM_H_
11+
#define PHASAR_DATAFLOW_IFDSIDE_IDETABULATIONPROBLEM_H_
1212

1313
#include "phasar/ControlFlow/ICFGBase.h"
1414
#include "phasar/DB/ProjectIRDBBase.h"
1515
#include "phasar/DataFlow/IfdsIde/EdgeFunctions.h"
16+
#include "phasar/DataFlow/IfdsIde/EntryPointUtils.h"
1617
#include "phasar/DataFlow/IfdsIde/FlowFunctions.h"
1718
#include "phasar/DataFlow/IfdsIde/IFDSIDESolverConfig.h"
1819
#include "phasar/DataFlow/IfdsIde/InitialSeeds.h"
@@ -21,7 +22,10 @@
2122
#include "phasar/Utils/Printer.h"
2223
#include "phasar/Utils/Soundness.h"
2324

25+
#include "llvm/ADT/StringRef.h"
26+
2427
#include <cassert>
28+
#include <functional>
2529
#include <memory>
2630
#include <optional>
2731
#include <set>
@@ -125,6 +129,22 @@ class IDETabulationProblem : public FlowFunctions<AnalysisDomainTy, Container>,
125129
return generateFlow(std::move(FactToGenerate), getZeroValue());
126130
}
127131

132+
/// Seeds that just start with ZeroValue and bottomElement() at the starting
133+
/// points of each EntryPoint function.
134+
/// Takes the __ALL__ EntryPoint into account.
135+
template <
136+
typename CC = typename AnalysisDomainTy::c_t,
137+
typename = std::enable_if_t<std::is_nothrow_default_constructible_v<CC>>>
138+
[[nodiscard]] InitialSeeds<n_t, d_t, l_t> createDefaultSeeds() {
139+
InitialSeeds<n_t, d_t, l_t> Seeds;
140+
CC C{};
141+
142+
addSeedsForStartingPoints(EntryPoints, IRDB, C, Seeds, getZeroValue(),
143+
this->bottomElement());
144+
145+
return Seeds;
146+
}
147+
128148
const ProjectIRDBBase<db_t> *IRDB{};
129149
std::vector<std::string> EntryPoints;
130150
std::optional<d_t> ZeroValue;

include/phasar/PhasarLLVM/ControlFlow/LLVMBasedCFG.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,11 @@ template <typename Derived> class LLVMBasedCFGImpl : public CFGBase<Derived> {
4949
}
5050

5151
protected:
52-
LLVMBasedCFGImpl(bool IgnoreDbgInstructions = true) noexcept
52+
LLVMBasedCFGImpl() noexcept = default;
53+
LLVMBasedCFGImpl(bool IgnoreDbgInstructions) noexcept
5354
: IgnoreDbgInstructions(IgnoreDbgInstructions) {}
5455

55-
bool IgnoreDbgInstructions = false;
56+
bool IgnoreDbgInstructions = true;
5657

5758
[[nodiscard]] f_t getFunctionOfImpl(n_t Inst) const noexcept;
5859
[[nodiscard]] llvm::SmallVector<n_t, 2> getPredsOfImpl(n_t Inst) const;
@@ -99,7 +100,8 @@ class LLVMBasedCFG : public detail::LLVMBasedCFGImpl<LLVMBasedCFG> {
99100
friend class LLVMBasedBackwardCFG;
100101

101102
public:
102-
LLVMBasedCFG(bool IgnoreDbgInstructions = true) noexcept
103+
LLVMBasedCFG() noexcept = default;
104+
LLVMBasedCFG(bool IgnoreDbgInstructions) noexcept
103105
: detail::LLVMBasedCFGImpl<LLVMBasedCFG>(IgnoreDbgInstructions) {}
104106

105107
[[nodiscard]] nlohmann::json exportCFGAsJson(const llvm::Function *F) const;

include/phasar/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEInstInteractionAnalysis.h

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -620,21 +620,18 @@ class IDEInstInteractionAnalysisT
620620

621621
inline InitialSeeds<n_t, d_t, l_t> initialSeeds() override {
622622
InitialSeeds<n_t, d_t, l_t> Seeds;
623-
std::set<const llvm::Function *> EntryPointFuns;
624-
for (const auto &EntryPoint : this->EntryPoints) {
625-
EntryPointFuns.insert(this->IRDB->getFunctionDefinition(EntryPoint));
626-
}
627-
// Set initial seeds at the required entry points and generate the global
628-
// variables using generalized initial seeds
629-
for (const auto *EntryPointFun : EntryPointFuns) {
623+
624+
forallStartingPoints(this->EntryPoints, ICF, [this, &Seeds](n_t SP) {
625+
// Set initial seeds at the required entry points and generate the global
626+
// variables using generalized initial seeds
627+
630628
// Generate zero value at the entry points
631-
Seeds.addSeed(&EntryPointFun->front().front(), this->getZeroValue(),
632-
bottomElement());
629+
Seeds.addSeed(SP, this->getZeroValue(), bottomElement());
633630
// Generate formal parameters of entry points, e.g. main(). Formal
634631
// parameters will otherwise cause trouble by overriding alloca
635632
// instructions without being valid data-flow facts themselves.
636-
for (const auto &Arg : EntryPointFun->args()) {
637-
Seeds.addSeed(&EntryPointFun->front().front(), &Arg, Bottom{});
633+
for (const auto &Arg : SP->getFunction()->args()) {
634+
Seeds.addSeed(SP, &Arg, Bottom{});
638635
}
639636
// Generate all global variables using generalized initial seeds
640637

@@ -648,10 +645,11 @@ class IDEInstInteractionAnalysisT
648645
InitialValues =
649646
BitVectorSet<e_t>(EdgeFacts.begin(), EdgeFacts.end());
650647
}
651-
Seeds.addSeed(&EntryPointFun->front().front(), GV, InitialValues);
648+
Seeds.addSeed(SP, GV, InitialValues);
652649
}
653650
}
654-
}
651+
});
652+
655653
return Seeds;
656654
}
657655

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

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
#include "phasar/DataFlow/IfdsIde/EdgeFunctionUtils.h"
1313
#include "phasar/DataFlow/IfdsIde/FlowFunctions.h"
14+
#include "phasar/DataFlow/IfdsIde/IDETabulationProblem.h"
1415
#include "phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h"
1516
#include "phasar/PhasarLLVM/DataFlow/IfdsIde/Problems/ExtendedTaintAnalysis/GenEdgeFunction.h"
1617
#include "phasar/PhasarLLVM/DataFlow/IfdsIde/Problems/ExtendedTaintAnalysis/Helpers.h"
@@ -48,18 +49,8 @@ IDEExtendedTaintAnalysis::initialSeeds() {
4849
}
4950
}
5051

51-
for (const auto &Ep : base_t::EntryPoints) {
52-
const auto *EntryFn = ICF->getFunction(Ep);
53-
54-
if (!EntryFn) {
55-
llvm::errs() << "WARNING: Entry-Function \"" << Ep
56-
<< "\" not contained in the module; skip it\n";
57-
continue;
58-
}
59-
60-
Seeds.addSeed(&EntryFn->front().front(), this->base_t::getZeroValue(),
61-
bottomElement());
62-
}
52+
addSeedsForStartingPoints(base_t::EntryPoints, ICF, Seeds,
53+
this->base_t::getZeroValue(), bottomElement());
6354

6455
if (Seeds.empty()) {
6556
llvm::errs() << "WARNING: No initial seeds specified, skip the analysis. "

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

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "phasar/DataFlow/IfdsIde/EdgeFunctionUtils.h"
1414
#include "phasar/DataFlow/IfdsIde/EdgeFunctions.h"
1515
#include "phasar/DataFlow/IfdsIde/FlowFunctions.h"
16+
#include "phasar/DataFlow/IfdsIde/IDETabulationProblem.h"
1617
#include "phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h"
1718
#include "phasar/PhasarLLVM/DB/LLVMProjectIRDB.h"
1819
#include "phasar/PhasarLLVM/DataFlow/IfdsIde/LLVMFlowFunctions.h"
@@ -226,24 +227,21 @@ IDEGeneralizedLCA::initialSeeds() {
226227
InitialSeeds<IDEGeneralizedLCA::n_t, IDEGeneralizedLCA::d_t,
227228
IDEGeneralizedLCA::l_t>
228229
Seeds;
229-
// For now, out only entrypoint is main:
230-
std::vector<std::string> EntryPoints = {"main"};
231-
for (auto &EntryPoint : EntryPoints) {
232-
std::set<IDEGeneralizedLCA::d_t> Globals;
233-
Seeds.addSeed(&ICF->getFunction(EntryPoint)->front().front(),
234-
getZeroValue(), bottomElement());
230+
231+
forallStartingPoints(EntryPoints, ICF, [this, &Seeds](n_t SP) {
232+
Seeds.addSeed(SP, getZeroValue(), bottomElement());
235233
for (const auto &G : IRDB->getModule()->globals()) {
236234
if (const auto *GV = llvm::dyn_cast<llvm::GlobalVariable>(&G)) {
237235
if (GV->hasInitializer()) {
238236
if (llvm::isa<llvm::ConstantInt>(GV->getInitializer()) ||
239237
llvm::isa<llvm::ConstantDataArray>(GV->getInitializer())) {
240-
Seeds.addSeed(&ICF->getFunction(EntryPoint)->front().front(), GV,
241-
bottomElement());
238+
Seeds.addSeed(SP, GV, bottomElement());
242239
}
243240
}
244241
}
245242
}
246-
}
243+
});
244+
247245
return Seeds;
248246
}
249247

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

Lines changed: 5 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "phasar/DataFlow/IfdsIde/EdgeFunctionUtils.h"
1313
#include "phasar/DataFlow/IfdsIde/EdgeFunctions.h"
1414
#include "phasar/DataFlow/IfdsIde/FlowFunctions.h"
15+
#include "phasar/DataFlow/IfdsIde/IDETabulationProblem.h"
1516
#include "phasar/DataFlow/IfdsIde/SolverResults.h"
1617
#include "phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h"
1718
#include "phasar/PhasarLLVM/DB/LLVMProjectIRDB.h"
@@ -384,43 +385,22 @@ InitialSeeds<IDELinearConstantAnalysis::n_t, IDELinearConstantAnalysis::d_t,
384385
IDELinearConstantAnalysis::l_t>
385386
IDELinearConstantAnalysis::initialSeeds() {
386387
InitialSeeds<n_t, d_t, l_t> Seeds;
387-
// The analysis' entry points
388-
std::set<const llvm::Function *> EntryPointFuns;
389-
390-
// Consider the user-defined entry point(s)
391-
if (EntryPoints.size() == 1U && EntryPoints.front() == "__ALL__") {
392-
// Consider all available function definitions as entry points
393-
for (const auto *Fun : IRDB->getAllFunctions()) {
394-
if (!Fun->isDeclaration()) {
395-
EntryPointFuns.insert(Fun);
396-
}
397-
}
398-
} else {
399-
// Consider the user specified entry points
400-
for (const auto &EntryPoint : EntryPoints) {
401-
EntryPointFuns.insert(IRDB->getFunctionDefinition(EntryPoint));
402-
}
403-
}
404388

405-
// std::set initial seeds at the required entry points and generate global
406-
// integer-typed variables using generalized initial seeds
407-
for (const auto *EntryPointFun : EntryPointFuns) {
408-
Seeds.addSeed(&EntryPointFun->front().front(), getZeroValue(),
409-
bottomElement());
389+
forallStartingPoints(EntryPoints, ICF, [this, &Seeds](n_t SP) {
390+
Seeds.addSeed(SP, getZeroValue(), bottomElement());
410391
// Generate global integer-typed variables using generalized initial seeds
411392

412393
for (const auto &G : IRDB->getModule()->globals()) {
413394
if (const auto *GV = llvm::dyn_cast<llvm::GlobalVariable>(&G)) {
414395
if (GV->hasInitializer()) {
415396
if (const auto *ConstInt =
416397
llvm::dyn_cast<llvm::ConstantInt>(GV->getInitializer())) {
417-
Seeds.addSeed(&EntryPointFun->front().front(), GV,
418-
ConstInt->getSExtValue());
398+
Seeds.addSeed(SP, GV, ConstInt->getSExtValue());
419399
}
420400
}
421401
}
422402
}
423-
}
403+
});
424404

425405
return Seeds;
426406
}

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

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
#include "phasar/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEProtoAnalysis.h"
1111

1212
#include "phasar/DataFlow/IfdsIde/EdgeFunctionUtils.h"
13+
#include "phasar/DataFlow/IfdsIde/IDETabulationProblem.h"
14+
#include "phasar/PhasarLLVM/ControlFlow/LLVMBasedCFG.h"
1315
#include "phasar/PhasarLLVM/DB/LLVMProjectIRDB.h"
1416
#include "phasar/PhasarLLVM/DataFlow/IfdsIde/LLVMZeroValue.h"
1517
#include "phasar/PhasarLLVM/Utils/LLVMShorthands.h"
@@ -68,14 +70,7 @@ InitialSeeds<IDEProtoAnalysis::n_t, IDEProtoAnalysis::d_t,
6870
IDEProtoAnalysis::l_t>
6971
IDEProtoAnalysis::initialSeeds() {
7072
PHASAR_LOG_LEVEL(DEBUG, "IDEProtoAnalysis::initialSeeds()");
71-
InitialSeeds<IDEProtoAnalysis::n_t, IDEProtoAnalysis::d_t,
72-
IDEProtoAnalysis::l_t>
73-
Seeds;
74-
for (const auto &EntryPoint : EntryPoints) {
75-
Seeds.addSeed(&IRDB->getFunction(EntryPoint)->front().front(),
76-
getZeroValue(), bottomElement());
77-
}
78-
return Seeds;
73+
return createDefaultSeeds();
7974
}
8075

8176
IDEProtoAnalysis::d_t IDEProtoAnalysis::createZeroValue() const {

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

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -101,16 +101,7 @@ IDESecureHeapPropagation::getSummaryFlowFunction(n_t /*CallSite*/,
101101
InitialSeeds<IDESecureHeapPropagation::n_t, IDESecureHeapPropagation::d_t,
102102
IDESecureHeapPropagation::l_t>
103103
IDESecureHeapPropagation::initialSeeds() {
104-
InitialSeeds<IDESecureHeapPropagation::n_t, IDESecureHeapPropagation::d_t,
105-
IDESecureHeapPropagation::l_t>
106-
Seeds;
107-
for (const auto &Entry : EntryPoints) {
108-
const auto *Fn = IRDB->getFunction(Entry);
109-
if (Fn && !Fn->isDeclaration()) {
110-
Seeds.addSeed(&Fn->front().front(), getZeroValue(), bottomElement());
111-
}
112-
}
113-
return Seeds;
104+
return createDefaultSeeds();
114105
}
115106

116107
IDESecureHeapPropagation::d_t

0 commit comments

Comments
 (0)