Skip to content

Commit 224f5f6

Browse files
authored
Merge pull request #429 from secure-software-engineering/f-fixStartPointsDbg
fix corner case in LLVMBasedCFG::getStartPointsOf
2 parents 023e31f + cce26a4 commit 224f5f6

3 files changed

Lines changed: 44 additions & 90 deletions

File tree

include/phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -188,14 +188,6 @@ class LLVMBasedICFG
188188

189189
~LLVMBasedICFG() override;
190190

191-
// Re-override getSuccsOf and getPredsOf from LLVMBasedCFG to incorporate
192-
// information about global ctors and globale dtors
193-
[[nodiscard]] std::vector<const llvm::Instruction *>
194-
getPredsOf(const llvm::Instruction *Inst) const override;
195-
196-
[[nodiscard]] std::vector<const llvm::Instruction *>
197-
getSuccsOf(const llvm::Instruction *Inst) const override;
198-
199191
[[nodiscard]] const llvm::Function *getFirstGlobalCtorOrNull() const;
200192

201193
[[nodiscard]] const llvm::Function *getLastGlobalDtorOrNull() const;

lib/PhasarLLVM/ControlFlow/LLVMBasedCFG.cpp

Lines changed: 40 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "llvm/IR/InstIterator.h"
2727
#include "llvm/IR/Instruction.h"
2828
#include "llvm/IR/Instructions.h"
29+
#include "llvm/IR/IntrinsicInst.h"
2930
#include "llvm/Support/Casting.h"
3031

3132
#include "nlohmann/json.hpp"
@@ -47,47 +48,60 @@ LLVMBasedCFG::getFunctionOf(const llvm::Instruction *Inst) const {
4748

4849
vector<const llvm::Instruction *>
4950
LLVMBasedCFG::getPredsOf(const llvm::Instruction *I) const {
50-
vector<const llvm::Instruction *> Preds;
5151
if (!IgnoreDbgInstructions) {
52-
if (I->getPrevNode()) {
53-
Preds.push_back(I->getPrevNode());
52+
if (auto *PrevInst = I->getPrevNode()) {
53+
return {PrevInst};
5454
}
5555
} else {
56-
if (I->getPrevNonDebugInstruction()) {
57-
Preds.push_back(I->getPrevNonDebugInstruction());
56+
if (auto *PrevNonDbgInst =
57+
I->getPrevNonDebugInstruction(false /*Only debug instructions*/)) {
58+
return {PrevNonDbgInst};
5859
}
5960
}
6061
// If we do not have a predecessor yet, look for basic blocks which
6162
// lead to our instruction in question!
62-
if (Preds.empty()) {
63-
std::transform(llvm::pred_begin(I->getParent()),
64-
llvm::pred_end(I->getParent()), back_inserter(Preds),
65-
[](const llvm::BasicBlock *BB) {
66-
assert(BB && "BB under analysis was not well formed.");
67-
return BB->getTerminator();
68-
});
69-
}
63+
64+
std::vector<const llvm::Instruction *> Preds;
65+
std::transform(llvm::pred_begin(I->getParent()),
66+
llvm::pred_end(I->getParent()), back_inserter(Preds),
67+
[](const llvm::BasicBlock *BB) {
68+
assert(BB && "BB under analysis was not well formed.");
69+
const llvm::Instruction *Pred = BB->getTerminator();
70+
if (llvm::isa<llvm::DbgInfoIntrinsic>(Pred)) {
71+
Pred = Pred->getPrevNonDebugInstruction(
72+
false /*Only debug instructions*/);
73+
}
74+
return Pred;
75+
});
76+
7077
return Preds;
7178
}
7279

7380
vector<const llvm::Instruction *>
7481
LLVMBasedCFG::getSuccsOf(const llvm::Instruction *I) const {
75-
vector<const llvm::Instruction *> Successors;
82+
std::vector<const llvm::Instruction *> Successors;
7683
// case we wish to consider LLVM's debug instructions
7784
if (!IgnoreDbgInstructions) {
78-
if (I->getNextNode()) {
79-
Successors.push_back(I->getNextNode());
85+
if (auto *NextInst = I->getNextNode()) {
86+
return {NextInst};
8087
}
8188
} else {
82-
if (I->getNextNonDebugInstruction()) {
83-
Successors.push_back(I->getNextNonDebugInstruction());
89+
if (auto *NextNonDbgInst =
90+
I->getNextNonDebugInstruction(false /*Only debug instructions*/)) {
91+
Successors.push_back(NextNonDbgInst);
8492
}
8593
}
8694
if (I->isTerminator()) {
8795
Successors.reserve(I->getNumSuccessors() + Successors.size());
8896
std::transform(llvm::succ_begin(I), llvm::succ_end(I),
89-
back_inserter(Successors),
90-
[](const llvm::BasicBlock *BB) { return &BB->front(); });
97+
back_inserter(Successors), [](const llvm::BasicBlock *BB) {
98+
const llvm::Instruction *Succ = &BB->front();
99+
if (llvm::isa<llvm::DbgInfoIntrinsic>(Succ)) {
100+
Succ = Succ->getNextNonDebugInstruction(
101+
false /*Only debug instructions*/);
102+
}
103+
return Succ;
104+
});
91105
}
92106
return Successors;
93107
}
@@ -135,7 +149,12 @@ LLVMBasedCFG::getStartPointsOf(const llvm::Function *Fun) const {
135149
return {};
136150
}
137151
if (!Fun->isDeclaration()) {
138-
return {&Fun->front().front()};
152+
auto *EntryInst = &Fun->front().front();
153+
if (IgnoreDbgInstructions && llvm::isa<llvm::DbgInfoIntrinsic>(EntryInst)) {
154+
return {EntryInst->getNextNonDebugInstruction(
155+
false /*Only debug instructions*/)};
156+
}
157+
return {EntryInst};
139158
} else {
140159
LOG_IF_ENABLE(BOOST_LOG_SEV(lg::get(), DEBUG)
141160
<< "Could not get starting points of '"

lib/PhasarLLVM/ControlFlow/LLVMBasedICFG.cpp

Lines changed: 4 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -444,65 +444,6 @@ const llvm::Function *LLVMBasedICFG::getFunction(const string &Fun) const {
444444
return IRDB.getFunction(Fun);
445445
}
446446

447-
std::vector<const llvm::Instruction *>
448-
LLVMBasedICFG::getPredsOf(const llvm::Instruction *Inst) const {
449-
if (!IgnoreDbgInstructions) {
450-
if (Inst->getPrevNode()) {
451-
return {Inst->getPrevNode()};
452-
}
453-
} else {
454-
if (Inst->getPrevNonDebugInstruction()) {
455-
return {Inst->getPrevNonDebugInstruction()};
456-
}
457-
}
458-
// If we do not have a predecessor yet, look for basic blocks which
459-
// lead to our instruction in question!
460-
461-
vector<const llvm::Instruction *> Preds;
462-
std::transform(llvm::pred_begin(Inst->getParent()),
463-
llvm::pred_end(Inst->getParent()), back_inserter(Preds),
464-
[](const llvm::BasicBlock *BB) {
465-
assert(BB && "BB under analysis was not well formed.");
466-
return BB->getTerminator();
467-
});
468-
469-
/// TODO: Add function-local static variable initialization workaround here
470-
471-
return Preds;
472-
}
473-
474-
std::vector<const llvm::Instruction *>
475-
LLVMBasedICFG::getSuccsOf(const llvm::Instruction *Inst) const {
476-
477-
vector<const llvm::Instruction *> Successors;
478-
// case we wish to consider LLVM's debug instructions
479-
if (!IgnoreDbgInstructions) {
480-
if (Inst->getNextNode()) {
481-
Successors.push_back(Inst->getNextNode());
482-
}
483-
} else {
484-
if (Inst->getNextNonDebugInstruction()) {
485-
Successors.push_back(Inst->getNextNonDebugInstruction());
486-
}
487-
}
488-
if (Successors.empty()) {
489-
if (const auto *Branch = llvm::dyn_cast<llvm::BranchInst>(Inst);
490-
Branch && isStaticVariableLazyInitializationBranch(Branch)) {
491-
// Skip the "already initialized" case, such that the analysis is always
492-
// aware of the initialized value.
493-
Successors.push_back(&Branch->getSuccessor(0)->front());
494-
495-
} else {
496-
Successors.reserve(Inst->getNumSuccessors() + Successors.size());
497-
std::transform(llvm::succ_begin(Inst), llvm::succ_end(Inst),
498-
std::back_inserter(Successors),
499-
[](const llvm::BasicBlock *BB) { return &BB->front(); });
500-
}
501-
}
502-
503-
return Successors;
504-
}
505-
506447
const llvm::Function *LLVMBasedICFG::getFirstGlobalCtorOrNull() const {
507448
auto it = GlobalCtors.begin();
508449
if (it != GlobalCtors.end()) {
@@ -701,11 +642,13 @@ LLVMBasedICFG::getReturnSitesOfCallAt(const llvm::Instruction *N) const {
701642
auto *UnwindSucc = &Invoke->getUnwindDest()->front();
702643
if (!IgnoreDbgInstructions &&
703644
llvm::isa<llvm::DbgInfoIntrinsic>(NormalSucc)) {
704-
NormalSucc = NormalSucc->getNextNonDebugInstruction();
645+
NormalSucc = NormalSucc->getNextNonDebugInstruction(
646+
false /*Only debug instructions*/);
705647
}
706648
if (!IgnoreDbgInstructions &&
707649
llvm::isa<llvm::DbgInfoIntrinsic>(UnwindSucc)) {
708-
UnwindSucc = UnwindSucc->getNextNonDebugInstruction();
650+
UnwindSucc = UnwindSucc->getNextNonDebugInstruction(
651+
false /*Only debug instructions*/);
709652
}
710653
if (NormalSucc != nullptr) {
711654
ReturnSites.insert(NormalSucc);

0 commit comments

Comments
 (0)