Skip to content
Open
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
c5fea5b
Add AliasIterator
fabianbs96 Jun 17, 2025
36ab054
Add alias() check as optional member to AliasIterator
fabianbs96 Jun 18, 2025
14fc564
Integrate AliasIterator into Default[IFDS/IDE]AliasAwareFlowFunctions
fabianbs96 Jun 18, 2025
035fdf5
Some restructure
fabianbs96 Jun 18, 2025
e1373dd
Add PointsToIterator and integrate it with SVFBasedPointsToInfo
fabianbs96 Jun 19, 2025
9bfe0b1
Integrate reachableAllocationSites with PointsToIterator
fabianbs96 Jun 19, 2025
9502cec
Merge branch 'development' into f-AliasIterator
fabianbs96 Jun 25, 2025
5a59e29
Add boilerplate + some comments
fabianbs96 Jun 25, 2025
e2e8ab2
Start adding SVFAliasInfo for SVF-DDA(WIP)
fabianbs96 Jun 25, 2025
baa5777
Fill missing functions for SVFAliasInfoImpl
fabianbs96 Jun 26, 2025
43674b0
minor
fabianbs96 Jun 28, 2025
20ebcfb
Fix FilteredLLVMAliasSet
fabianbs96 Jun 28, 2025
3477d40
Merge branch 'development' into f-AliasIterator
fabianbs96 Jul 25, 2025
d4b61a7
Fix example
fabianbs96 Jul 25, 2025
91dd1d0
Merge branch 'development' into f-AliasIterator
fabianbs96 Jul 27, 2025
d6a435c
Fix some bugs in aliasiterator and pointstoiterator
fabianbs96 Aug 3, 2025
c006029
minor fix
fabianbs96 Aug 9, 2025
8eb01d8
Remove AliasIterator::alias as it is probably not needed and makes th…
fabianbs96 Aug 12, 2025
1ec91ac
Add FilteredLLVMAliasIterator
fabianbs96 Aug 12, 2025
6496724
Implement FilteredLLVMAliasSet in terms of FilteredLLVMAliasIterator
fabianbs96 Aug 12, 2025
34fb428
Add CachedLLVMAliasIterator and implement FilteredLLVMAliasSet in ter…
fabianbs96 Aug 12, 2025
8d9bc1e
Make AliasIterator more convenient to use by reducing the requirement…
fabianbs96 Aug 15, 2025
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
19 changes: 10 additions & 9 deletions examples/how-to/07-write-ifds-analysis/simple.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@

namespace {

void populateWithMayAliases(psr::LLVMAliasInfoRef AS,
std::set<const llvm::Value *> &Facts);
void populateWithMayAliases(psr::LLVMAliasIteratorRef AS,
std::set<const llvm::Value *> &Facts,
const llvm::Instruction *At);

/// To create a custom IFDS analysis, we must create a subclass of the
/// IFDSTabulationProblem.
Expand All @@ -23,7 +24,7 @@ class ExampleTaintAnalysis : public psr::DefaultAliasAwareIFDSProblem {
/// The last parameter of the base-ctor denotes the special zero-value of the
/// IFDS problem. We use LLVMZeroValue for this.
explicit ExampleTaintAnalysis(const psr::LLVMProjectIRDB *IRDB,
psr::LLVMAliasInfoRef AS,
psr::LLVMAliasIteratorRef AS,
const psr::LLVMTaintConfig *Config,
std::vector<std::string> EntryPoints)
: psr::DefaultAliasAwareIFDSProblem(IRDB, AS, std::move(EntryPoints),
Expand Down Expand Up @@ -63,8 +64,8 @@ class ExampleTaintAnalysis : public psr::DefaultAliasAwareIFDSProblem {
}

// Since our analysis is alias-aware, we must handle aliasing here:
populateWithMayAliases(getAliasInfo(), Gen);
populateWithMayAliases(getAliasInfo(), Leak);
populateWithMayAliases(getAliasInfo(), Gen, CallSite);
populateWithMayAliases(getAliasInfo(), Leak, CallSite);

// We have special behavior to communicate to the analysis solver, so create
// a flow-function that captures this behavior:
Expand Down Expand Up @@ -101,12 +102,12 @@ class ExampleTaintAnalysis : public psr::DefaultAliasAwareIFDSProblem {
};

// For all given facts, we add their aliases:
void populateWithMayAliases(psr::LLVMAliasInfoRef AS,
std::set<const llvm::Value *> &Facts) {
void populateWithMayAliases(psr::LLVMAliasIteratorRef AS,
std::set<const llvm::Value *> &Facts,
const llvm::Instruction *At) {
auto Tmp = Facts;
for (const auto *Fact : Facts) {
auto Aliases = AS.getAliasSet(Fact);
Tmp.insert(Aliases->begin(), Aliases->end());
AS.forallAliasesOf(Fact, At, [&](const auto *Alias) { Tmp.insert(Alias); });
}

Facts = std::move(Tmp);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,13 @@ class IDEAliasAwareDefaultFlowFunctionsImpl

using IDENoAliasDefaultFlowFunctionsImpl::isFunctionModeled;

[[nodiscard]] constexpr LLVMAliasInfoRef getAliasInfo() const noexcept {
[[nodiscard]] constexpr LLVMAliasIteratorRef getAliasInfo() const noexcept {
return AS;
}

constexpr IDEAliasAwareDefaultFlowFunctionsImpl(LLVMAliasInfoRef AS) noexcept
: AS(AS) {
assert(AS && "You must provide an alias information handle!");
}
constexpr IDEAliasAwareDefaultFlowFunctionsImpl(
LLVMAliasIteratorRef AS) noexcept
: AS(AS) {}

[[nodiscard]] FlowFunctionPtrType getNormalFlowFunctionImpl(n_t Curr,
n_t /*Succ*/);
Expand All @@ -54,8 +53,8 @@ class IDEAliasAwareDefaultFlowFunctionsImpl
using IDENoAliasDefaultFlowFunctionsImpl::getCallFlowFunctionImpl;
using IDENoAliasDefaultFlowFunctionsImpl::getCallToRetFlowFunctionImpl;

protected:
LLVMAliasInfoRef AS;
private:
LLVMAliasIteratorRef AS;
};
} // namespace detail

Expand All @@ -74,7 +73,7 @@ class DefaultAliasAwareIDEProblem
/// \note It is useful to use an instance of FilteredAliasSet for the alias
/// information to lower suprious aliases
explicit DefaultAliasAwareIDEProblem(
const ProjectIRDBBase<db_t> *IRDB, LLVMAliasInfoRef AS,
const ProjectIRDBBase<db_t> *IRDB, LLVMAliasIteratorRef AS,
std::vector<std::string> EntryPoints,
std::optional<d_t>
ZeroValue) noexcept(std::is_nothrow_move_constructible_v<d_t>)
Expand Down Expand Up @@ -116,7 +115,7 @@ class DefaultAliasAwareIFDSProblem
/// \note It is useful to use an instance of FilteredAliasSet for the alias
/// information to lower suprious aliases
explicit DefaultAliasAwareIFDSProblem(
const ProjectIRDBBase<db_t> *IRDB, LLVMAliasInfoRef AS,
const ProjectIRDBBase<db_t> *IRDB, LLVMAliasIteratorRef AS,
std::vector<std::string> EntryPoints,
d_t ZeroValue) noexcept(std::is_nothrow_move_constructible_v<d_t>)
: IFDSTabulationProblem(IRDB, std::move(EntryPoints), ZeroValue),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

#include "phasar/PhasarLLVM/DataFlow/IfdsIde/DefaultNoAliasIDEProblem.h"
#include "phasar/PhasarLLVM/Pointer/LLVMAliasInfo.h"
#include "phasar/PhasarLLVM/Pointer/LLVMPointsToInfo.h"

// Forward declaration of types for which we only use its pointer or ref type
namespace llvm {
Expand All @@ -34,15 +35,14 @@ class IDEReachableAllocationSitesDefaultFlowFunctionsImpl

using IDENoAliasDefaultFlowFunctionsImpl::isFunctionModeled;

[[nodiscard]] constexpr LLVMAliasInfoRef getAliasInfo() const noexcept {
[[nodiscard]] constexpr LLVMPointsToIteratorRef
getPointsToInfo() const noexcept {
return AS;
}

constexpr IDEReachableAllocationSitesDefaultFlowFunctionsImpl(
LLVMAliasInfoRef AS) noexcept
: AS(AS) {
assert(AS && "You must provide an alias information handle!");
}
LLVMPointsToIteratorRef AS) noexcept
: AS(AS) {}

[[nodiscard]] FlowFunctionPtrType getNormalFlowFunctionImpl(n_t Curr,
n_t /*Succ*/);
Expand All @@ -56,7 +56,7 @@ class IDEReachableAllocationSitesDefaultFlowFunctionsImpl
using IDENoAliasDefaultFlowFunctionsImpl::getCallToRetFlowFunctionImpl;

protected:
LLVMAliasInfoRef AS;
LLVMPointsToIteratorRef AS;
};
} // namespace detail

Expand All @@ -73,7 +73,7 @@ class DefaultReachableAllocationSitesIDEProblem
/// \note It is useful to use an instance of FilteredAliasSet for the alias
/// information to lower suprious aliases
explicit DefaultReachableAllocationSitesIDEProblem(
const ProjectIRDBBase<db_t> *IRDB, LLVMAliasInfoRef AS,
const ProjectIRDBBase<db_t> *IRDB, LLVMPointsToIteratorRef AS,
std::vector<std::string> EntryPoints,
std::optional<d_t>
ZeroValue) noexcept(std::is_nothrow_move_constructible_v<d_t>)
Expand Down Expand Up @@ -115,7 +115,7 @@ class DefaultReachableAllocationSitesIFDSProblem
/// \note It is useful to use an instance of FilteredAliasSet for the alias
/// information to lower suprious aliases
explicit DefaultReachableAllocationSitesIFDSProblem(
const ProjectIRDBBase<db_t> *IRDB, LLVMAliasInfoRef AS,
const ProjectIRDBBase<db_t> *IRDB, LLVMPointsToIteratorRef AS,
std::vector<std::string> EntryPoints,
d_t ZeroValue) noexcept(std::is_nothrow_move_constructible_v<d_t>)
: IFDSTabulationProblem(IRDB, std::move(EntryPoints), ZeroValue),
Expand Down
5 changes: 5 additions & 0 deletions include/phasar/PhasarLLVM/Pointer.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,15 @@
#ifndef PHASAR_PHASARLLVM_POINTER_H
#define PHASAR_PHASARLLVM_POINTER_H

#include "phasar/Config/phasar-config.h" // for PHASAR_USE_SVF
#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/LLVMPointsToUtils.h"

#ifdef PHASAR_USE_SVF
#include "phasar/PhasarLLVM/Pointer/SVF/SVFPointsToSet.h"
#endif

#endif // PHASAR_PHASARLLVM_POINTER_H
129 changes: 129 additions & 0 deletions include/phasar/PhasarLLVM/Pointer/CachedLLVMAliasIterator.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
/******************************************************************************
* 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_CACHEDLLVMALIASITERATOR_H
#define PHASAR_PHASARLLVM_POINTER_CACHEDLLVMALIASITERATOR_H

#include "phasar/PhasarLLVM/Pointer/LLVMAliasInfo.h"
#include "phasar/Pointer/AliasAnalysisType.h"
#include "phasar/Pointer/AliasInfoTraits.h"
#include "phasar/Pointer/AliasSetOwner.h"

#include "llvm/IR/Function.h"

namespace psr {

class CachedLLVMAliasIterator;

template <>
struct AliasInfoTraits<CachedLLVMAliasIterator>
: DefaultAATraits<const llvm::Value *, const llvm::Instruction *> {};

/// \brief A wrapper over a LLVMAliasIteratorRef that adds caching to make it
/// conform to the LLVMAliasInfoRef interface
///
/// \note Currently assumes that the underlying alias information is
/// flow-insensitive and the granularity of different alias-information per
/// instruction is actually at function-level
class CachedLLVMAliasIterator {
public:
using alias_traits_t = AliasInfoTraits<CachedLLVMAliasIterator>;
using n_t = alias_traits_t::n_t;
using v_t = alias_traits_t::v_t;
using AliasSetTy = alias_traits_t::AliasSetTy;
using AliasSetPtrTy = alias_traits_t::AliasSetPtrTy;
using AllocationSiteSetPtrTy = alias_traits_t::AllocationSiteSetPtrTy;

CachedLLVMAliasIterator(LLVMAliasIteratorRef AS) noexcept;

// --- API Functions:

[[nodiscard]] inline bool isInterProcedural() const noexcept {
return false; // No idea, so be conservative here
};

[[nodiscard]] AliasAnalysisType getAliasAnalysisType() const noexcept {
return AliasAnalysisType::Invalid; // No idea
}

[[nodiscard]] AliasResult alias(const llvm::Value *V1, const llvm::Value *V2,
const llvm::Instruction *I);

[[nodiscard]] AliasSetPtrTy getAliasSet(const llvm::Value *V,
const llvm::Instruction *I);

[[nodiscard]] AllocationSiteSetPtrTy
getReachableAllocationSites(const llvm::Value *V, bool IntraProcOnly = false,
const llvm::Instruction *I = nullptr);

// Checks if PotentialValue is in the reachable allocation sites of V.
[[nodiscard]] bool isInReachableAllocationSites(
const llvm::Value *V, const llvm::Value *PotentialValue,
bool IntraProcOnly = false, const llvm::Instruction *I = nullptr);

void mergeWith(const CachedLLVMAliasIterator & /*OtherPTI*/) {
llvm::report_fatal_error("Not Supported");
}

void introduceAlias(const llvm::Value * /*V1*/, const llvm::Value * /*V2*/,
const llvm::Instruction * /*I*/ = nullptr,
AliasResult /*Kind*/ = AliasResult::MustAlias) {
llvm::report_fatal_error("Not Supported");
}

void print(llvm::raw_ostream &OS = llvm::outs()) const;

[[nodiscard]] nlohmann::json getAsJson() const;

void printAsJson(llvm::raw_ostream &OS = llvm::outs()) const;

[[nodiscard]] AnalysisProperties getAnalysisProperties() const noexcept {
return AnalysisProperties::None;
}

[[nodiscard]] LLVMAliasIteratorRef getUnderlying() const noexcept {
return AS;
}

private:
struct ReachableAllocationSitesKey {
llvm::PointerIntPair<const llvm::Function *, 1, bool> FunAndIntraProcOnly;
v_t Value{};
};

struct ReachableAllocationSitesKeyDMI {
inline static ReachableAllocationSitesKey getEmptyKey() noexcept {
return {{}, llvm::DenseMapInfo<v_t>::getEmptyKey()};
}
inline static ReachableAllocationSitesKey getTombstoneKey() noexcept {
return {{}, llvm::DenseMapInfo<v_t>::getTombstoneKey()};
}
inline static auto getHashValue(ReachableAllocationSitesKey Key) noexcept {
return llvm::hash_combine(Key.FunAndIntraProcOnly.getOpaqueValue(),
Key.Value);
}
inline static bool isEqual(ReachableAllocationSitesKey Key1,
ReachableAllocationSitesKey Key2) noexcept {
return Key1.FunAndIntraProcOnly == Key2.FunAndIntraProcOnly &&
Key1.Value == Key2.Value;
}
};

LLVMAliasIteratorRef AS;
AliasSetOwner<AliasSetTy>::memory_resource_type MRes;
AliasSetOwner<AliasSetTy> Owner;
llvm::DenseMap<std::pair<const llvm::Function *, v_t>, AliasSetPtrTy>
AliasSetMap;
llvm::DenseMap<ReachableAllocationSitesKey, std::unique_ptr<AliasSetTy>,
ReachableAllocationSitesKeyDMI>
ReachableAllocationSitesMap;
};
} // namespace psr

#endif // PHASAR_PHASARLLVM_POINTER_CACHEDALIASITERATOR_H
40 changes: 40 additions & 0 deletions include/phasar/PhasarLLVM/Pointer/FilteredLLVMAliasIterator.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/******************************************************************************
* 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_FILTEREDLLVMALIASITERATOR_H
#define PHASAR_PHASARLLVM_POINTER_FILTEREDLLVMALIASITERATOR_H

#include "phasar/PhasarLLVM/Pointer/LLVMAliasInfo.h"

#include "llvm/ADT/STLFunctionalExtras.h"

namespace psr {
class FilteredLLVMAliasIterator {
public:
using n_t = const llvm::Instruction *;
using v_t = const llvm::Value *;

constexpr FilteredLLVMAliasIterator(LLVMAliasIteratorRef Underlying) noexcept
: Underlying(Underlying) {}

void forallAliasesOf(const llvm::Value *V, const llvm::Function *Fun,
llvm::function_ref<void(const llvm::Value *)> WithAlias);
void forallAliasesOf(const llvm::Value *V, const llvm::Instruction *At,
llvm::function_ref<void(const llvm::Value *)> WithAlias);

[[nodiscard]] LLVMAliasIteratorRef getUnderlying() const noexcept {
return Underlying;
}

private:
LLVMAliasIteratorRef Underlying;
};
} // namespace psr

#endif // PHASAR_PHASARLLVM_POINTER_FILTEREDLLVMALIASITERATOR_H
Loading
Loading