Skip to content

Commit a8f7b78

Browse files
author
Martin Mory
committed
incorporated review feedback, get rid of negative return values of getVFTIndex()
1 parent b8cb1b9 commit a8f7b78

10 files changed

Lines changed: 60 additions & 44 deletions

File tree

include/phasar/PhasarLLVM/ControlFlow/Resolver/Resolver.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,15 @@ class Function;
2929
class StructType;
3030
} // namespace llvm
3131

32+
namespace std {
33+
template <class T> class optional;
34+
}
35+
3236
namespace psr {
3337
class ProjectIRDB;
3438
class LLVMTypeHierarchy;
3539

36-
int getVFTIndex(const llvm::CallBase *CallSite);
40+
std::optional<unsigned> getVFTIndex(const llvm::CallBase *CallSite);
3741

3842
const llvm::StructType *getReceiverType(const llvm::CallBase *CallSite);
3943

include/phasar/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.h

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,18 @@ class LLVMTypeHierarchy
8888
using out_edge_iterator = boost::graph_traits<bidigraph_t>::out_edge_iterator;
8989
using in_edge_iterator = boost::graph_traits<bidigraph_t>::in_edge_iterator;
9090

91+
static const std::string StructPrefix;
92+
93+
static const std::string ClassPrefix;
94+
95+
static const std::string VTablePrefix;
96+
97+
static const std::string VTablePrefixDemang;
98+
99+
static const std::string TypeInfoPrefix;
100+
101+
static const std::string TypeInfoPrefixDemang;
102+
91103
private:
92104
bidigraph_t TypeGraph;
93105
std::unordered_map<const llvm::StructType *, vertex_t> TypeVertexMap;
@@ -102,18 +114,6 @@ class LLVMTypeHierarchy
102114
// map from clearname to vtable variable
103115
std::unordered_map<std::string, const llvm::GlobalVariable *> ClearNameTVMap;
104116

105-
static const std::string StructPrefix;
106-
107-
static const std::string ClassPrefix;
108-
109-
static const std::string VTablePrefix;
110-
111-
static const std::string VTablePrefixDemang;
112-
113-
static const std::string TypeInfoPrefix;
114-
115-
static const std::string TypeInfoPrefixDemang;
116-
117117
static std::string removeStructOrClassPrefix(const llvm::StructType &T);
118118

119119
static std::string removeStructOrClassPrefix(const std::string &TypeName);

include/phasar/PhasarLLVM/TypeHierarchy/LLVMVFTable.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ class LLVMVFTable : public VFTable<const llvm::Function *> {
8787
};
8888

8989
[[nodiscard]] static std::vector<const llvm::Function *>
90-
getVFVectorFromIRVTable(const llvm::ConstantStruct *);
90+
getVFVectorFromIRVTable(const llvm::ConstantStruct &);
9191
};
9292

9393
} // namespace psr

lib/PhasarLLVM/ControlFlow/Resolver/CHAResolver.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ auto CHAResolver::resolveVirtualCall(const llvm::CallBase *CallSite)
3737
// Leading to SEGFAULT in Unittests. Error only when run in Debug mode
3838
// << llvmIRToString(CallSite));
3939

40-
auto VFTIdx = getVFTIndex(CallSite);
41-
if (VFTIdx < 0) {
40+
auto RetrievedVtableIndex = getVFTIndex(CallSite);
41+
if (!RetrievedVtableIndex.has_value()) {
4242
// An error occured
4343
LOG_IF_ENABLE(
4444
BOOST_LOG_SEV(lg::get(), DEBUG)
@@ -50,8 +50,10 @@ auto CHAResolver::resolveVirtualCall(const llvm::CallBase *CallSite)
5050
return {};
5151
}
5252

53+
auto VtableIndex = RetrievedVtableIndex.value();
54+
5355
LOG_IF_ENABLE(BOOST_LOG_SEV(lg::get(), DEBUG)
54-
<< "Virtual function table entry is: " << VFTIdx);
56+
<< "Virtual function table entry is: " << VtableIndex);
5557

5658
const auto *ReceiverTy = getReceiverType(CallSite);
5759

@@ -62,7 +64,7 @@ auto CHAResolver::resolveVirtualCall(const llvm::CallBase *CallSite)
6264

6365
for (const auto &FallbackTy : FallbackTys) {
6466
const auto *Target =
65-
getNonPureVirtualVFTEntry(FallbackTy, VFTIdx, CallSite);
67+
getNonPureVirtualVFTEntry(FallbackTy, VtableIndex, CallSite);
6668
if (Target) {
6769
PossibleCallees.insert(Target);
6870
}

lib/PhasarLLVM/ControlFlow/Resolver/DTAResolver.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -161,8 +161,8 @@ auto DTAResolver::resolveVirtualCall(const llvm::CallBase *CallSite)
161161
LOG_IF_ENABLE(BOOST_LOG_SEV(lg::get(), DEBUG)
162162
<< "Call virtual function: " << llvmIRToString(CallSite));
163163

164-
auto VtableIndex = getVFTIndex(CallSite);
165-
if (VtableIndex < 0) {
164+
auto RetrievedVtableIndex = getVFTIndex(CallSite);
165+
if (!RetrievedVtableIndex.has_value()) {
166166
// An error occured
167167
LOG_IF_ENABLE(BOOST_LOG_SEV(lg::get(), DEBUG)
168168
<< "Error with resolveVirtualCall : impossible to retrieve "
@@ -171,6 +171,8 @@ auto DTAResolver::resolveVirtualCall(const llvm::CallBase *CallSite)
171171
return {};
172172
}
173173

174+
auto VtableIndex = RetrievedVtableIndex.value();
175+
174176
LOG_IF_ENABLE(BOOST_LOG_SEV(lg::get(), DEBUG)
175177
<< "Virtual function table entry is: " << VtableIndex);
176178

lib/PhasarLLVM/ControlFlow/Resolver/OTFResolver.cpp

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,8 @@ auto OTFResolver::resolveVirtualCall(const llvm::CallBase *CallSite)
9090
LOG_IF_ENABLE(BOOST_LOG_SEV(lg::get(), DEBUG)
9191
<< "Call virtual function: " << llvmIRToString(CallSite));
9292

93-
auto VtableIndex = getVFTIndex(CallSite);
94-
if (VtableIndex < 0) {
93+
auto RetrievedVtableIndex = getVFTIndex(CallSite);
94+
if (!RetrievedVtableIndex.has_value()) {
9595
// An error occured
9696
LOG_IF_ENABLE(BOOST_LOG_SEV(lg::get(), DEBUG)
9797
<< "Error with resolveVirtualCall : impossible to retrieve "
@@ -100,6 +100,8 @@ auto OTFResolver::resolveVirtualCall(const llvm::CallBase *CallSite)
100100
return {};
101101
}
102102

103+
auto VtableIndex = RetrievedVtableIndex.value();
104+
103105
LOG_IF_ENABLE(BOOST_LOG_SEV(lg::get(), DEBUG)
104106
<< "Virtual function table entry is: " << VtableIndex);
105107

@@ -113,12 +115,13 @@ auto OTFResolver::resolveVirtualCall(const llvm::CallBase *CallSite)
113115
auto PTS = PT.getPointsToSet(CallSite->getCalledOperand(), CallSite);
114116
for (const auto *P : *PTS) {
115117
if (auto *PGV = llvm::dyn_cast<llvm::GlobalVariable>(P)) {
116-
if (PGV->hasName() && PGV->getName().startswith("_ZTV") &&
118+
if (PGV->hasName() &&
119+
PGV->getName().startswith(LLVMTypeHierarchy::VTablePrefix) &&
117120
PGV->hasInitializer()) {
118121
if (auto *PCS = llvm::dyn_cast<llvm::ConstantStruct>(
119122
PGV->getInitializer())) {
120-
auto VFs = LLVMVFTable::getVFVectorFromIRVTable(PCS);
121-
if (VtableIndex < 0 || VtableIndex >= VFs.size()) {
123+
auto VFs = LLVMVFTable::getVFVectorFromIRVTable(*PCS);
124+
if (VtableIndex >= VFs.size()) {
122125
continue;
123126
}
124127
auto *Callee = VFs[VtableIndex];

lib/PhasarLLVM/ControlFlow/Resolver/RTAResolver.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,8 @@ auto RTAResolver::resolveVirtualCall(const llvm::CallBase *CallSite)
5656
LOG_IF_ENABLE(BOOST_LOG_SEV(lg::get(), DEBUG)
5757
<< "Call virtual function: " << llvmIRToString(CallSite));
5858

59-
auto VtableIndex = getVFTIndex(CallSite);
60-
if (VtableIndex < 0) {
59+
auto RetrievedVtableIndex = getVFTIndex(CallSite);
60+
if (!RetrievedVtableIndex.has_value()) {
6161
// An error occured
6262
LOG_IF_ENABLE(BOOST_LOG_SEV(lg::get(), DEBUG)
6363
<< "Error with resolveVirtualCall : impossible to retrieve "
@@ -66,6 +66,8 @@ auto RTAResolver::resolveVirtualCall(const llvm::CallBase *CallSite)
6666
return {};
6767
}
6868

69+
auto VtableIndex = RetrievedVtableIndex.value();
70+
6971
LOG_IF_ENABLE(BOOST_LOG_SEV(lg::get(), DEBUG)
7072
<< "Virtual function table entry is: " << VtableIndex);
7173

lib/PhasarLLVM/ControlFlow/Resolver/Resolver.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616

1717
#include <set>
18+
#include <optional>
1819

1920
#include "llvm/IR/Constants.h"
2021
#include "llvm/IR/DerivedTypes.h"
@@ -30,23 +31,23 @@ using namespace psr;
3031

3132
namespace psr {
3233

33-
int getVFTIndex(const llvm::CallBase *CallSite) {
34+
std::optional<unsigned> getVFTIndex(const llvm::CallBase *CallSite) {
3435
// deal with a virtual member function
3536
// retrieve the vtable entry that is called
3637
const auto *Load =
3738
llvm::dyn_cast<llvm::LoadInst>(CallSite->getCalledOperand());
3839
if (Load == nullptr) {
39-
return -1;
40+
return std::nullopt;
4041
}
4142
const auto *GEP =
4243
llvm::dyn_cast<llvm::GetElementPtrInst>(Load->getPointerOperand());
4344
if (GEP == nullptr) {
44-
return -2;
45+
return std::nullopt;
4546
}
4647
if (auto *CI = llvm::dyn_cast<llvm::ConstantInt>(GEP->getOperand(1))) {
4748
return CI->getZExtValue();
4849
}
49-
return -3;
50+
return std::nullopt;
5051
}
5152

5253
const llvm::StructType *getReceiverType(const llvm::CallBase *CallSite) {

lib/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ LLVMTypeHierarchy::getVirtualFunctions(const llvm::Module &M,
203203
}
204204
if (const auto *I =
205205
llvm::dyn_cast<llvm::ConstantStruct>(TI->getInitializer())) {
206-
VFS = LLVMVFTable::getVFVectorFromIRVTable(I);
206+
VFS = LLVMVFTable::getVFVectorFromIRVTable(*I);
207207
}
208208
}
209209
}

lib/PhasarLLVM/TypeHierarchy/LLVMVFTable.cpp

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -51,21 +51,23 @@ nlohmann::json LLVMVFTable::getAsJson() const {
5151
}
5252

5353
std::vector<const llvm::Function *>
54-
LLVMVFTable::getVFVectorFromIRVTable(const llvm::ConstantStruct *VT) {
54+
LLVMVFTable::getVFVectorFromIRVTable(const llvm::ConstantStruct &VT) {
5555
std::vector<const llvm::Function *> VFS;
56-
for (const auto &Op : VT->operands()) {
57-
if (auto *CA = llvm::dyn_cast<llvm::ConstantArray>(Op)) {
58-
for (auto It = CA->operands().begin() + 2; It != CA->operands().end();
59-
++It) {
60-
auto &COp = *It;
61-
if (auto *CE = llvm::dyn_cast<llvm::ConstantExpr>(COp)) {
62-
if (auto *BC = llvm::dyn_cast<llvm::BitCastOperator>(CE)) {
56+
for (const auto &Op : VT.operands()) {
57+
if (const auto *CA = llvm::dyn_cast<llvm::ConstantArray>(Op)) {
58+
// Start iterating at offset 2, because offset 0 is vbase offset, offset 1
59+
// is RTTI
60+
for (auto It = std::next(CA->operands().begin(), 2);
61+
It != CA->operands().end(); ++It) {
62+
const auto &COp = *It;
63+
if (const auto *CE = llvm::dyn_cast<llvm::ConstantExpr>(COp)) {
64+
if (const auto *BC = llvm::dyn_cast<llvm::BitCastOperator>(CE)) {
6365
// if the entry is a GlobalAlias, get its Aliasee
64-
auto *ENTRY = BC->getOperand(0);
65-
while (auto *GA = llvm::dyn_cast<llvm::GlobalAlias>(ENTRY)) {
66-
ENTRY = GA->getAliasee();
66+
auto *Entry = BC->getOperand(0);
67+
while (auto *GA = llvm::dyn_cast<llvm::GlobalAlias>(Entry)) {
68+
Entry = GA->getAliasee();
6769
}
68-
auto *F = llvm::dyn_cast<llvm::Function>(ENTRY);
70+
auto *F = llvm::dyn_cast<llvm::Function>(Entry);
6971
VFS.push_back(F);
7072
} else {
7173
VFS.push_back(nullptr);

0 commit comments

Comments
 (0)