Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,13 @@ class PathSensitivityManagerMixin {
return pathsDagToAll(Inst, llvm::ArrayRef(&Fact, 1), Config, PFilter);
}

if (auto Next = Inst->getNextNonDebugInstruction()) {
if (auto Next =
#if LLVM_VERSION_MAJOR <= 18
Inst->getNextNonDebugInstruction()
#else
Inst->getNextNode()
#endif
) {
return pathsDagToAll(Next, llvm::ArrayRef(&Fact, 1), Config, PFilter);
}

Expand All @@ -203,9 +209,11 @@ class PathSensitivityManagerMixin {

for (const auto *BB : llvm::successors(Inst)) {
const auto *First = &BB->front();
#if LLVM_VERSION_MAJOR <= 18
if (llvm::isa<llvm::DbgInfoIntrinsic>(First)) {
First = First->getNextNonDebugInstruction();
}
#endif
if (ESG.getNodeOrNull(First, Fact)) {
return pathsDagToAll(First, llvm::ArrayRef(&Fact, 1), Config, PFilter);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,11 @@ auto SolverResultsBase<Derived, N, D, L>::resultsAtInLLVMSSA(
if (!Stmt->getNextNode()) {
auto GetStartRow = [this](const llvm::BasicBlock *BB) -> decltype(auto) {
const auto *First = &BB->front();
#if LLVM_VERSION_MAJOR <= 18
if (llvm::isa<llvm::DbgInfoIntrinsic>(First)) {
First = First->getNextNonDebugInstruction();
}
#endif
return self().Results.row(First);
};

Expand Down Expand Up @@ -111,9 +113,11 @@ auto SolverResultsBase<Derived, N, D, L>::resultAtInLLVMSSA(
auto GetStartVal = [this,
&Value](const llvm::BasicBlock *BB) -> decltype(auto) {
const auto *First = &BB->front();
#if LLVM_VERSION_MAJOR <= 18
if (llvm::isa<llvm::DbgInfoIntrinsic>(First)) {
First = First->getNextNonDebugInstruction();
}
#endif
return self().Results.get(First, Value);
};

Expand Down
6 changes: 6 additions & 0 deletions include/phasar/PhasarLLVM/Utils/LLVMShorthands.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ bool isHeapAllocatingFunction(const llvm::Function *F) noexcept;
///
/// \note This function is less useful in practice than you may think. Consider
/// using isConsistentCall() instead.
LLVM_DEPRECATED("With opaque pointers, this function is not very useful. Use "
"isConsistentCall() instead.",
"psr::isConsistentCall")
bool matchesSignature(const llvm::Function *F, const llvm::FunctionType *FType,
bool ExactMatch = true);

Expand All @@ -79,6 +82,9 @@ bool matchesSignature(const llvm::Function *F, const llvm::FunctionType *FType,
///
/// \note This function is less useful in practice than you may think. Consider
/// using isConsistentCall() instead.
LLVM_DEPRECATED("With opaque pointers, this function is not very useful. Use "
"isConsistentCall() instead.",
"psr::isConsistentCall")
bool matchesSignature(const llvm::FunctionType *FType1,
const llvm::FunctionType *FType2);

Expand Down
7 changes: 3 additions & 4 deletions lib/PhasarLLVM/ControlFlow/GlobalCtorsDtorsModel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -379,10 +379,9 @@ bool GlobalCtorsDtorsModel::isPhasarGenerated(
const llvm::Function &F) noexcept {
if (F.hasName()) {
llvm::StringRef FunctionName = F.getName();
return llvm::StringSwitch<bool>(FunctionName)
.Cases(ModelName, DtorModelName, DtorsCallerName, UserEntrySelectorName,
true)
.Default(false);
const auto Cases = {ModelName, DtorModelName, DtorsCallerName,
UserEntrySelectorName};
return llvm::is_contained(Cases, FunctionName);
}

return false;
Expand Down
31 changes: 29 additions & 2 deletions lib/PhasarLLVM/ControlFlow/LLVMBasedCFG.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@ auto detail::LLVMBasedCFGImpl<Derived>::getFunctionOfImpl(
template <typename Derived>
auto detail::LLVMBasedCFGImpl<Derived>::getPredsOfImpl(n_t I) const
-> llvm::SmallVector<n_t, 2> {
#if LLVM_VERSION_MAJOR > 18
if (const auto *PrevInst = I->getPrevNode()) {
return {PrevInst};
}
#else

if (!IgnoreDbgInstructions) {
if (const auto *PrevInst = I->getPrevNode()) {
return {PrevInst};
Expand All @@ -44,6 +50,7 @@ auto detail::LLVMBasedCFGImpl<Derived>::getPredsOfImpl(n_t I) const
return {PrevNonDbgInst};
}
}
#endif
// If we do not have a predecessor yet, look for basic blocks which
// lead to our instruction in question!

Expand All @@ -53,10 +60,12 @@ auto detail::LLVMBasedCFGImpl<Derived>::getPredsOfImpl(n_t I) const
[](const llvm::BasicBlock *BB) {
assert(BB && "BB under analysis was not well formed.");
const llvm::Instruction *Pred = BB->getTerminator();
#if LLVM_VERSION_MAJOR <= 18
if (llvm::isa<llvm::DbgInfoIntrinsic>(Pred)) {
Pred = Pred->getPrevNonDebugInstruction(
false /*Only debug instructions*/);
}
#endif
return Pred;
});

Expand All @@ -66,6 +75,11 @@ auto detail::LLVMBasedCFGImpl<Derived>::getPredsOfImpl(n_t I) const
template <typename Derived>
auto detail::LLVMBasedCFGImpl<Derived>::getSuccsOfImpl(n_t I) const
-> llvm::SmallVector<n_t, 2> {
#if LLVM_VERSION_MAJOR > 18
if (const auto *NextInst = I->getNextNode()) {
return {NextInst};
}
#else
// case we wish to consider LLVM's debug instructions
if (!IgnoreDbgInstructions) {
if (const auto *NextInst = I->getNextNode()) {
Expand All @@ -75,14 +89,18 @@ auto detail::LLVMBasedCFGImpl<Derived>::getSuccsOfImpl(n_t I) const
false /*Only debug instructions*/)) {
return {NextNonDbgInst};
}
#endif

if (const auto *Branch = llvm::dyn_cast<llvm::BranchInst>(I);
Branch && isStaticVariableLazyInitializationBranch(Branch)) {
// Skip the "already initialized" case, such that the analysis is always
// aware of the initialized value.
const auto *NextInst = &Branch->getSuccessor(0)->front();
#if LLVM_VERSION_MAJOR <= 18
if (IgnoreDbgInstructions && llvm::isa<llvm::DbgInfoIntrinsic>(NextInst)) {
NextInst = NextInst->getNextNonDebugInstruction(false);
}
#endif
return {NextInst};
}

Expand All @@ -93,10 +111,12 @@ auto detail::LLVMBasedCFGImpl<Derived>::getSuccsOfImpl(n_t I) const
[IgnoreDbgInstructions{IgnoreDbgInstructions}](
const llvm::BasicBlock *BB) {
const llvm::Instruction *Succ = &BB->front();
#if LLVM_VERSION_MAJOR <= 18
if (IgnoreDbgInstructions && llvm::isa<llvm::DbgInfoIntrinsic>(Succ)) {
Succ = Succ->getNextNonDebugInstruction(
false /*Only debug instructions*/);
}
#endif
return Succ;
});
return Successors;
Expand Down Expand Up @@ -133,10 +153,12 @@ auto detail::LLVMBasedCFGImpl<Derived>::getStartPointsOfImpl(f_t Fun) const
}
if (!Fun->isDeclaration()) {
const auto *EntryInst = &Fun->front().front();
#if LLVM_VERSION_MAJOR <= 18
if (IgnoreDbgInstructions && llvm::isa<llvm::DbgInfoIntrinsic>(EntryInst)) {
return {EntryInst->getNextNonDebugInstruction(
false /*Only debug instructions*/)};
}
#endif
return {EntryInst};
}
PHASAR_LOG_LEVEL_CAT(DEBUG, "LLVMBasedCFG",
Expand Down Expand Up @@ -170,8 +192,13 @@ bool detail::LLVMBasedCFGImpl<Derived>::isStartPointImpl(
if (Inst == FirstInst) {
return true;
}
return llvm::isa<llvm::DbgInfoIntrinsic>(FirstInst) &&
Inst == FirstInst->getNextNonDebugInstruction(false);
#if LLVM_VERSION_MAJOR <= 18
if (llvm::isa<llvm::DbgInfoIntrinsic>(FirstInst)) {
FirstInst = FirstInst->getNextNonDebugInstruction(false);
}
#endif

return Inst == FirstInst;
}

template <typename Derived>
Expand Down
5 changes: 5 additions & 0 deletions lib/PhasarLLVM/ControlFlow/LLVMBasedICFGExportsImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,12 @@ LLVMBasedICFG::exportICFGAsDot(bool WithSourceCodeInfo) const {
assert(BB && !BB->empty());
const auto *InterTo = &BB->front();

#if LLVM_VERSION_MAJOR <= 18
if (IgnoreDbgInstructions && llvm::isa<llvm::DbgInfoIntrinsic>(InterTo)) {
InterTo = InterTo->getNextNonDebugInstruction(false);
}
#endif

// createEdge(From, InterTo);
OS << intptr_t(CS) << "->" << intptr_t(InterTo) << ";\n";

Expand Down Expand Up @@ -238,9 +241,11 @@ struct GetIR {
llvm::BasicBlock::const_iterator End) {
assert(It != End);

#if LLVM_VERSION_MAJOR <= 18
if (It->isDebugOrPseudoInst()) {
return llvmIRToStableString(It->getNextNonDebugInstruction());
}
#endif

return llvmIRToStableString(&*It);
}
Expand Down
52 changes: 51 additions & 1 deletion lib/PhasarLLVM/ControlFlow/Resolver/Resolver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include "phasar/PhasarLLVM/Utils/LLVMShorthands.h"
#include "phasar/Utils/Logger.h"

#include "llvm/ADT/STLExtras.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DebugInfo.h"
#include "llvm/IR/DebugInfoMetadata.h"
Expand Down Expand Up @@ -146,9 +147,58 @@ bool psr::isConsistentCall(const llvm::CallBase *CallSite,
if (CallSite->arg_size() != DestFun->arg_size() && !DestFun->isVarArg()) {
return false;
}
if (!matchesSignature(DestFun, CallSite->getFunctionType(), false)) {

for (const auto &[Param, ArgOp] :
llvm::zip_first(DestFun->args(), CallSite->args())) {

const auto *ParamTy = Param.getType();
const auto *ArgTy = ArgOp->getType();

if (ParamTy == ArgTy) {
// Trivial equality
continue;
}

if (ParamTy->getTypeID() != ArgTy->getTypeID()) {
// Trivial non-equality, e.g. PointerType and IntegerType
return false;
}

if (ParamTy->isPointerTy()) {
if (Param.hasByValAttr() !=
CallSite->isByValArgument(ArgOp.getOperandNo())) {
return false;
}

const auto *ParamSRetTy = Param.getParamStructRetType();
const auto *ArgSRetTy =
CallSite->getParamStructRetType(ArgOp.getOperandNo());
if ((ParamSRetTy != nullptr) != (ArgSRetTy != nullptr)) {
return false;
}

if (ParamSRetTy && ArgSRetTy) {
// TODO: For better precision, compare the sret types as well
// Trivial non-equality, e.g. PointerType and IntegerType
if (ParamSRetTy->getTypeID() != ArgSRetTy->getTypeID()) {
// Trivial non-equality, e.g. PointerType and IntegerType
return false;
}
}
}

if (ParamTy->isStructTy()) {
// Copied comment from struct-case in isTypeMatchForFunctionArgument():
// > Well, we could do sanity checks here, but if the analysed code is
// > insane we would miss callees, so we don't do that.

continue;
}

// Types are non-equal and we could not find a reason to treat the same
return false;
}

return true;
}

Expand Down
15 changes: 15 additions & 0 deletions lib/PhasarLLVM/ControlFlow/SVFGCache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@

#include "llvm/IR/IntrinsicInst.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/ModRef.h"

using namespace psr;

#if LLVM_VERSION_MAJOR <= 20
static bool isNonPointerType(const llvm::Type *Ty) {
if (const auto *Struct = llvm::dyn_cast<llvm::StructType>(Ty)) {
for (const auto *ElemTy : Struct->elements()) {
Expand All @@ -24,6 +26,7 @@ static bool isNonPointerType(const llvm::Type *Ty) {
}
return Ty->isSingleValueType();
}
#endif

static bool isNonAddressTakenVariable(const llvm::Value *Val) {
const auto *Alloca = llvm::dyn_cast<llvm::AllocaInst>(Val);
Expand All @@ -41,10 +44,20 @@ static bool isNonAddressTakenVariable(const llvm::Value *Val) {
if (Call->paramHasAttr(ArgNo, llvm::Attribute::StructRet)) {
continue;
}
#if LLVM_VERSION_MAJOR <= 20
if (Call->paramHasAttr(ArgNo, llvm::Attribute::NoCapture) &&
isNonPointerType(Call->getType())) {
continue;
}
#else
auto Captures = Call->getCaptureInfo(ArgNo);
auto CComp = Captures.getOtherComponents() | Captures.getRetComponents();
if (llvm::capturesAnyProvenance(CComp) ||
(llvm::capturesAddress(CComp) &&
!llvm::capturesAddressIsNullOnly(CComp))) {
return false;
}
#endif
return false;
}
}
Expand Down Expand Up @@ -134,9 +147,11 @@ static void buildSparseCFG(const LLVMBasedCFG &CFG,
// -- Initialization

const auto *Entry = &Fun->getEntryBlock().front();
#if LLVM_VERSION_MAJOR <= 18
if (llvm::isa<llvm::DbgInfoIntrinsic>(Entry)) {
Entry = Entry->getNextNonDebugInstruction();
}
#endif

for (const auto *Succ : CFG.getSuccsOf(Entry)) {
WL.emplace_back(Entry, Succ);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,16 +42,25 @@ AbstractMemoryLocationImpl::AbstractMemoryLocationImpl(
const llvm::Value *Baseptr, llvm::ArrayRef<ptrdiff_t> Offsets,
unsigned Lifetime) noexcept
: AbstractMemoryLocationStorage(Baseptr, Lifetime, Offsets.size()) {
memcpy(this->getTrailingObjects<ptrdiff_t>(), Offsets.data(),
Offsets.size() * sizeof(ptrdiff_t));
memcpy(this->getTrailingObjects
#if LLVM_VERSION_MAJOR <= 20
<ptrdiff_t>
#endif
(),
Offsets.data(), Offsets.size() * sizeof(ptrdiff_t));
}

bool AbstractMemoryLocationImpl::isZero() const {
return LLVMZeroValue::isLLVMZeroValue(Baseptr);
}

llvm::ArrayRef<ptrdiff_t> AbstractMemoryLocationImpl::offsets() const {
return llvm::ArrayRef(this->getTrailingObjects<ptrdiff_t>(), NumOffsets);
return llvm::ArrayRef(this->getTrailingObjects
#if LLVM_VERSION_MAJOR <= 20
<ptrdiff_t>
#endif
(),
NumOffsets);
}

auto AbstractMemoryLocationImpl::computeOffset(const llvm::DataLayout &DL,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -422,7 +422,7 @@ auto IFDSTaintAnalysis::getSummaryFlowFunction([[maybe_unused]] n_t CallSite,
// $sSS1poiyS2S_SStFZ is Swift's String append method
// if concat a tainted string with something else the
// result should be tainted
if (DestFun->getName().equals("$sSS1poiyS2S_SStFZ")) {
if (DestFun->getName() == "$sSS1poiyS2S_SStFZ") {
const auto *CS = llvm::cast<llvm::CallBase>(CallSite);

return generateFlowIf(CallSite, [CS](d_t Source) {
Expand Down
Loading
Loading