Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
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
2 changes: 2 additions & 0 deletions .clang-tidy
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,12 @@ Checks: '-*,
-cppcoreguidelines-init-variables,
-cppcoreguidelines-macro-usage,
-cppcoreguidelines-avoid-do-while,
-cppcoreguidelines-avoid-c-arrays,
bugprone-*,
-bugprone-easily-swappable-parameters,
modernize-*,
-modernize-use-trailing-return-type,
-modernize-avoid-c-arrays,
performance-*,
clang-analyzer-*
'
Expand Down
5 changes: 1 addition & 4 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,8 @@ doc/*
log/*
**/*/logs/

# CMake build dir
build/*

# MS VS Code
.vscode/*
.vscode/

# Eclipse
.cproject
Expand Down
12 changes: 12 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,18 @@ endif()
include(add_llvm)
add_llvm()

# SVF
option(PHASAR_USE_SVF "Use SVF for more options in alias analysis (default is OFF)" OFF)
if(PHASAR_USE_SVF)
find_package(SVF REQUIRED CONFIG)
message(STATUS "Found SVF ${SVF_VERSION}")

if (NOT PHASAR_USE_Z3)
message(WARNING "SVF requires Z3. Set PHASAR_USE_Z3=ON")
set(PHASAR_USE_Z3 ON)
endif()
endif()

# Z3 Solver
if(PHASAR_IN_TREE)
set (PHASAR_USE_Z3 OFF)
Expand Down
2 changes: 2 additions & 0 deletions config.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,6 @@

#cmakedefine PHASAR_HAS_SQLITE

#cmakedefine PHASAR_USE_SVF

#endif /* PHASAR_CONFIG_CONFIG_H */
21 changes: 11 additions & 10 deletions include/phasar/ControlFlow/CFGBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#define PHASAR_CONTROLFLOW_CFGBASE_H

#include "phasar/Utils/ByRef.h"
#include "phasar/Utils/CRTPUtils.h"
#include "phasar/Utils/TypeTraits.h"

namespace psr {
Expand All @@ -22,7 +23,12 @@ template <typename T> struct CFGTraits {
// using f_t
};

template <typename Derived> class CFGBase {
template <typename Derived> class CFGBase : public CRTPBase<Derived> {
friend Derived;

protected:
using CRTPBase<Derived>::self;

public:
using n_t = typename CFGTraits<Derived>::n_t;
using f_t = typename CFGTraits<Derived>::f_t;
Expand Down Expand Up @@ -129,19 +135,14 @@ template <typename Derived> class CFGBase {
void print(ByConstRef<f_t> Fun, llvm::raw_ostream &OS) const {
self().printImpl(Fun, OS);
}

protected:
Derived &self() noexcept { return static_cast<Derived &>(*this); }
const Derived &self() const noexcept {
return static_cast<const Derived &>(*this);
}
};

template <typename ICF, typename Domain>
// NOLINTNEXTLINE(readability-identifier-naming)
PSR_CONCEPT is_cfg_v = is_crtp_base_of_v<CFGBase, ICF>
&&std::is_same_v<typename ICF::n_t, typename Domain::n_t>
&&std::is_same_v<typename ICF::f_t, typename Domain::f_t>;
PSR_CONCEPT is_cfg_v =
is_crtp_base_of_v<CFGBase, ICF> &&
std::is_same_v<typename ICF::n_t, typename Domain::n_t> &&
std::is_same_v<typename ICF::f_t, typename Domain::f_t>;

} // namespace psr

Expand Down
11 changes: 5 additions & 6 deletions include/phasar/ControlFlow/CallGraphBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#define PHASAR_CONTROLFLOW_CALLGRAPHBASE_H

#include "phasar/Utils/ByRef.h"
#include "phasar/Utils/CRTPUtils.h"
#include "phasar/Utils/TypeTraits.h"

namespace psr {
Expand All @@ -22,7 +23,10 @@ template <typename T> struct CGTraits {
/// Base class of all CallGraph implementations within phasar (currently only
/// CallGraph<N, F>).
/// Only represents the data, not how to create it.
template <typename Derived> class CallGraphBase {
template <typename Derived> class CallGraphBase : public CRTPBase<Derived> {
friend Derived;
using CRTPBase<Derived>::self;

public:
using n_t = typename CGTraits<Derived>::n_t;
using f_t = typename CGTraits<Derived>::f_t;
Expand All @@ -46,11 +50,6 @@ template <typename Derived> class CallGraphBase {
is_iterable_over_v<decltype(self().getCallersOfImpl(Fun)), n_t>);
return self().getCallersOfImpl(Fun);
}

private:
const Derived &self() const noexcept {
return static_cast<const Derived &>(*this);
}
};
} // namespace psr

Expand Down
23 changes: 9 additions & 14 deletions include/phasar/ControlFlow/ICFGBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

#include "phasar/ControlFlow/CFGBase.h"
#include "phasar/ControlFlow/CallGraphBase.h"
#include "phasar/Utils/CRTPUtils.h"
#include "phasar/Utils/TypeTraits.h"

#include "llvm/ADT/StringRef.h"
Expand All @@ -20,16 +21,14 @@
#include <type_traits>

namespace psr {
template <typename Derived> class ICFGBase {
template <typename Derived> class ICFGBase : public CRTPBase<Derived> {
friend Derived;
using CRTPBase<Derived>::self;

public:
using n_t = typename CFGTraits<Derived>::n_t;
using f_t = typename CFGTraits<Derived>::f_t;

ICFGBase() noexcept {
static_assert(is_crtp_base_of_v<CFGBase, Derived>,
"An ICFG must also be a CFG");
}

/// Returns an iterable range of all function definitions or declarations in
/// the ICFG
[[nodiscard]] decltype(auto) getAllFunctions() const {
Expand Down Expand Up @@ -113,20 +112,16 @@ template <typename Derived> class ICFGBase {
[[nodiscard]] size_t getNumCallSites() const noexcept {
return self().getNumCallSitesImpl();
}

private:
const Derived &self() const noexcept {
return static_cast<const Derived &>(*this);
}
};

/// True, iff ICF is a proper instantiation of ICFGBase with n_t and f_t taken
/// from the given analysis-Domain
template <typename ICF, typename Domain>
// NOLINTNEXTLINE(readability-identifier-naming)
PSR_CONCEPT is_icfg_v = is_crtp_base_of_v<ICFGBase, ICF>
&&std::is_same_v<typename ICF::n_t, typename Domain::n_t>
&&std::is_same_v<typename ICF::f_t, typename Domain::f_t>;
PSR_CONCEPT is_icfg_v =
is_crtp_base_of_v<ICFGBase, ICF> &&
std::is_same_v<typename ICF::n_t, typename Domain::n_t> &&
std::is_same_v<typename ICF::f_t, typename Domain::f_t>;

} // namespace psr

Expand Down
1 change: 0 additions & 1 deletion include/phasar/PhasarLLVM/ControlFlow/LLVMBasedCFG.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ template <> struct CFGTraits<LLVMBasedBackwardCFG> : CFGTraits<LLVMBasedCFG> {};

namespace detail {
template <typename Derived> class LLVMBasedCFGImpl : public CFGBase<Derived> {
friend CFGBase<Derived>;
friend class LLVMBasedBackwardCFG;

public:
Expand Down
2 changes: 1 addition & 1 deletion include/phasar/PhasarLLVM/Pointer.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@
#ifndef PHASAR_PHASARLLVM_POINTER_H
#define PHASAR_PHASARLLVM_POINTER_H

#include "phasar/PhasarLLVM/Pointer/AliasAnalysisView.h"
#include "phasar/PhasarLLVM/Pointer/FilteredLLVMAliasSet.h"
#include "phasar/PhasarLLVM/Pointer/LLVMAliasInfo.h"
#include "phasar/PhasarLLVM/Pointer/LLVMAliasSet.h"
#include "phasar/PhasarLLVM/Pointer/LLVMBasedAliasAnalysis.h"
#include "phasar/PhasarLLVM/Pointer/LLVMPointsToUtils.h"

#endif // PHASAR_PHASARLLVM_POINTER_H
99 changes: 99 additions & 0 deletions include/phasar/PhasarLLVM/Pointer/AliasAnalysisView.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
/******************************************************************************
* Copyright (c) 2025 Fabian Schiebel.
* All rights reserved. This program and the accompanying materials are made
* available under the terms of LICENSE.txt.
*
* Contributors:
* Fabian Schiebel and others
*****************************************************************************/

#ifndef PHASAR_PHASARLLVM_POINTER_ALIASANALYSISVIEW_H
#define PHASAR_PHASARLLVM_POINTER_ALIASANALYSISVIEW_H

#include "phasar/Pointer/AliasAnalysisType.h"
#include "phasar/Pointer/AliasResult.h"

#include <memory>
#include <type_traits>

namespace llvm {
class Value;
class DataLayout;
class Function;
} // namespace llvm

namespace psr {
class LLVMProjectIRDB;

class FunctionAliasView {
public:
template <typename T>
using AliasCallbackTy = AliasResult (*)(T *, const llvm::Value *,
const llvm::Value *,
const llvm::DataLayout &);

[[nodiscard]] AliasResult alias(const llvm::Value *V, const llvm::Value *Rep,
const llvm::DataLayout &DL) {
return Alias(Context, V, Rep, DL);
}

template <
typename T, typename AliasFn,
typename = std::enable_if_t<std::is_empty_v<AliasFn> &&
std::is_default_constructible_v<AliasFn>>>
constexpr FunctionAliasView(T *Context, AliasFn /*Alias*/) noexcept
: Context(Context), Alias(&callAlias<T, AliasFn>) {}

private:
template <typename T, typename AliasFn>
static AliasResult callAlias(void *Context, const llvm::Value *V1,
const llvm::Value *V2,
const llvm::DataLayout &DL) {
return AliasFn{}(static_cast<T *>(Context), V1, V2, DL);
}

void *Context{};
AliasCallbackTy<void> Alias{};
};

class AliasAnalysisView {
public:
constexpr AliasAnalysisView(AliasAnalysisType PATy) noexcept : PATy(PATy) {}

virtual ~AliasAnalysisView() = default;

[[nodiscard]] FunctionAliasView getAAResults(const llvm::Function *F) {
assert(F != nullptr);
return doGetAAResults(F);
}

void erase(llvm::Function *F) noexcept {
assert(F != nullptr);
doErase(F);
}

void clear() noexcept { doClear(); }

[[nodiscard]] constexpr AliasAnalysisType
getPointerAnalysisType() const noexcept {
return PATy;
};

[[nodiscard]] static std::unique_ptr<AliasAnalysisView>
create(LLVMProjectIRDB &IRDB, bool UseLazyEvaluation, AliasAnalysisType PATy);

private:
static std::unique_ptr<AliasAnalysisView>
createLLVMBasedAnalysis(LLVMProjectIRDB &IRDB, bool UseLazyEvaluation,
AliasAnalysisType PATy);

virtual FunctionAliasView doGetAAResults(const llvm::Function *F) = 0;
virtual void doErase(llvm::Function *F) noexcept = 0;
virtual void doClear() noexcept = 0;

AliasAnalysisType PATy{};
};

} // namespace psr

#endif // PHASAR_PHASARLLVM_POINTER_ALIASANALYSISVIEW_H
8 changes: 4 additions & 4 deletions include/phasar/PhasarLLVM/Pointer/LLVMAliasSet.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
#ifndef PHASAR_PHASARLLVM_POINTER_LLVMALIASSET_H
#define PHASAR_PHASARLLVM_POINTER_LLVMALIASSET_H

#include "phasar/PhasarLLVM/Pointer/AliasAnalysisView.h"
#include "phasar/PhasarLLVM/Pointer/LLVMAliasSetData.h"
#include "phasar/PhasarLLVM/Pointer/LLVMBasedAliasAnalysis.h"
#include "phasar/Pointer/AliasInfoBase.h"
#include "phasar/Pointer/AliasInfoTraits.h"
#include "phasar/Pointer/AliasResult.h"
Expand Down Expand Up @@ -69,7 +69,7 @@ class LLVMAliasSet : public AnalysisPropertiesMixin<LLVMAliasSet>,
};

[[nodiscard]] inline AliasAnalysisType getAliasAnalysisType() const noexcept {
return PTA.getPointerAnalysisType();
return PTA->getPointerAnalysisType();
};

[[nodiscard]] AliasResult alias(const llvm::Value *V1, const llvm::Value *V2,
Expand Down Expand Up @@ -143,12 +143,12 @@ class LLVMAliasSet : public AnalysisPropertiesMixin<LLVMAliasSet>,
const llvm::GlobalObject *VG) const;

/// Utility function used by computeFunctionsAliasSet(...)
void addPointer(llvm::AAResults &AA, const llvm::DataLayout &DL,
void addPointer(FunctionAliasView AA, const llvm::DataLayout &DL,
const llvm::Value *V, std::vector<const llvm::Value *> &Reps);

[[nodiscard]] static BoxedPtr<AliasSetTy> getEmptyAliasSet();

LLVMBasedAliasAnalysis PTA;
std::unique_ptr<AliasAnalysisView> PTA;
llvm::DenseSet<const llvm::Function *> AnalyzedFunctions;

AliasSetOwner<AliasSetTy>::memory_resource_type MRes;
Expand Down
55 changes: 55 additions & 0 deletions include/phasar/PhasarLLVM/Pointer/SVF/SVFPointsToSet.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/******************************************************************************
* Copyright (c) 2025 Fabian Schiebel.
* All rights reserved. This program and the accompanying materials are made
* available under the terms of LICENSE.txt.
*
* Contributors:
* Fabian Schiebel and others
*****************************************************************************/
#ifndef PHASAR_PHASARLLVM_POINTER_SVF_SVFPOINTSTOSET_H
#define PHASAR_PHASARLLVM_POINTER_SVF_SVFPOINTSTOSET_H

#include "phasar/Config/phasar-config.h"
#include "phasar/Pointer/PointsToInfo.h"

#include "llvm/ADT/DenseSet.h"
#include "llvm/IR/Value.h"

#ifndef PHASAR_USE_SVF
#error \
"Don't include SVFPointsToSet.h when PhASAR is not configured to include SVF. Set the cmake variable PHASAR_USE_SVF and retry."
#endif

namespace psr {
class LLVMProjectIRDB;
class SVFPointsToInfo;

struct SVFPointsToInfoTraits {
using v_t = const llvm::Value *;
using n_t = const llvm::Instruction *;
using o_t = uint32_t;

// TODO: Use a more efficient representation; maybe even one that does not
// require an expensive transformation from SVF::PointsTo
using PointsToSetTy = llvm::SmallDenseSet<o_t>;

// No special pointer type
using PointsToSetPtrTy = PointsToSetTy;
};

using SVFBasedPointsToInfo = PointsToInfo<SVFPointsToInfoTraits>;
using SVFBasedPointsToInfoRef = PointsToInfoRef<SVFPointsToInfoTraits>;

/// Use SVF to perform a VersionedFlowSensitive pointer analysis and return the
/// results compatible to psr::PointsToInfo and psr::PointsToInfoRef
[[nodiscard]] SVFBasedPointsToInfo
createSVFVFSPointsToInfo(LLVMProjectIRDB &IRDB);

/// Use SVF to perform a ContextDDA pointer analysis and return the
/// results compatible to psr::PointsToInfo and psr::PointsToInfoRef
[[nodiscard]] SVFBasedPointsToInfo
createSVFDDAPointsToInfo(LLVMProjectIRDB &IRDB);

} // namespace psr

#endif // PHASAR_PHASARLLVM_POINTER_SVF_SVFPOINTSTOSET_H
Loading
Loading