Skip to content

Commit

Permalink
expose getNonPureVirtualVFTEntry as namespace-scope function + fix bu…
Browse files Browse the repository at this point in the history
…ild with LLVM 14
  • Loading branch information
fabianbs96 committed Dec 15, 2024
1 parent 2ff4f78 commit b6a3f65
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 17 deletions.
22 changes: 21 additions & 1 deletion include/phasar/PhasarLLVM/ControlFlow/Resolver/Resolver.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,29 @@ class LLVMVFTableProvider;
class LLVMTypeHierarchy;
enum class CallGraphAnalysisType;

/// Assuming that `CallSite` is a virtual call through a vtable, retrieves the
/// index in the vtable of the virtual function called.
[[nodiscard]] std::optional<unsigned>
getVFTIndex(const llvm::CallBase *CallSite);

/// Assuming that `CallSite` is a vall to a non-static member function,
/// retrieves the type of the receiver. Returns nullptr, if the receiver-type
/// could not be extracted
[[nodiscard]] const llvm::StructType *
getReceiverType(const llvm::CallBase *CallSite);

/// Assuming that `CallSite` is a virtual call, where `Idx` is retrieved through
/// `getVFTIndex()` and `T` through `getReceiverType()`
[[nodiscard]] const llvm::Function *
getNonPureVirtualVFTEntry(const llvm::StructType *T, unsigned Idx,
const llvm::CallBase *CallSite,
const psr::LLVMVFTableProvider &VTP);

[[nodiscard]] std::string getReceiverTypeName(const llvm::CallBase *CallSite);

/// Checks whether the signature of `DestFun` matches the required withature of
/// `CallSite`, such that `DestFun` qualifies as callee-candidate, if `CallSite`
/// is an indirect/virtual call.
[[nodiscard]] bool isConsistentCall(const llvm::CallBase *CallSite,
const llvm::Function *DestFun);

Expand All @@ -59,7 +74,12 @@ class Resolver {

const llvm::Function *
getNonPureVirtualVFTEntry(const llvm::StructType *T, unsigned Idx,
const llvm::CallBase *CallSite);
const llvm::CallBase *CallSite) {
if (!VTP) {
return nullptr;
}
return psr::getNonPureVirtualVFTEntry(T, Idx, CallSite, *VTP);
}

public:
using FunctionSetTy = llvm::SmallDenseSet<const llvm::Function *, 4>;
Expand Down
32 changes: 16 additions & 16 deletions lib/PhasarLLVM/ControlFlow/Resolver/Resolver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,22 @@ const llvm::StructType *psr::getReceiverType(const llvm::CallBase *CallSite) {
return nullptr;
}

const llvm::Function *
psr::getNonPureVirtualVFTEntry(const llvm::StructType *T, unsigned Idx,
const llvm::CallBase *CallSite,
const LLVMVFTableProvider &VTP) {

if (const auto *VT = VTP.getVFTableOrNull(T)) {
const auto *Target = VT->getFunction(Idx);
if (Target && Target->getName() != LLVMTypeHierarchy::PureVirtualCallName &&
isConsistentCall(CallSite, Target)) {
return Target;
}
}

return nullptr;
}

std::string psr::getReceiverTypeName(const llvm::CallBase *CallSite) {
const auto *RT = getReceiverType(CallSite);
if (RT) {
Expand Down Expand Up @@ -134,22 +150,6 @@ Resolver::Resolver(const LLVMProjectIRDB *IRDB, const LLVMVFTableProvider *VTP)
assert(VTP != nullptr);
}

const llvm::Function *
Resolver::getNonPureVirtualVFTEntry(const llvm::StructType *T, unsigned Idx,
const llvm::CallBase *CallSite) {
if (!VTP) {
return nullptr;
}
if (const auto *VT = VTP->getVFTableOrNull(T)) {
const auto *Target = VT->getFunction(Idx);
if (Target && Target->getName() != LLVMTypeHierarchy::PureVirtualCallName &&
isConsistentCall(CallSite, Target)) {
return Target;
}
}
return nullptr;
}

void Resolver::preCall(const llvm::Instruction *Inst) {}

void Resolver::handlePossibleTargets(const llvm::CallBase *CallSite,
Expand Down

0 comments on commit b6a3f65

Please sign in to comment.