Skip to content
Open
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
4 changes: 2 additions & 2 deletions include/phasar/ControlFlow/CallGraphBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ template <typename Derived> class CallGraphBase : public CRTPBase<Derived> {
/// NOTE: This function is typically called in a hot part of the analysis and
/// should therefore be very fast
[[nodiscard]] decltype(auto) getCalleesOfCallAt(ByConstRef<n_t> Inst) const
noexcept(noexcept(self().getCalleesOfCallAtImpl(Inst))) {
noexcept(noexcept(this->self().getCalleesOfCallAtImpl(Inst))) {
static_assert(
is_iterable_over_v<decltype(self().getCalleesOfCallAtImpl(Inst)), f_t>);
return self().getCalleesOfCallAtImpl(Inst);
Expand All @@ -47,7 +47,7 @@ template <typename Derived> class CallGraphBase : public CRTPBase<Derived> {
/// call the given function induced by the used call-graph.
[[nodiscard]] decltype(auto) getCallersOf(ByConstRef<f_t> Fun) const {
static_assert(
is_iterable_over_v<decltype(self().getCallersOfImpl(Fun)), n_t>);
is_iterable_over_v<decltype(this->self().getCallersOfImpl(Fun)), n_t>);
return self().getCallersOfImpl(Fun);
}
};
Expand Down
21 changes: 16 additions & 5 deletions include/phasar/DataFlow/IfdsIde/EdgeFunction.h
Original file line number Diff line number Diff line change
Expand Up @@ -442,21 +442,32 @@ class [[clang::trivial_abi]] EdgeFunction final : EdgeFunctionBase {
typename = std::enable_if_t<
!std::is_same_v<EdgeFunction, std::decay_t<ConcreteEF>> &&
IsEdgeFunction<ConcreteEF>>>
[[nodiscard]] friend bool operator==(EdgeFunctionRef<ConcreteEF> LHS,
const EdgeFunction &RHS) noexcept {
if (!RHS.template isa<ConcreteEF>()) {
[[nodiscard]] bool equals(EdgeFunctionRef<ConcreteEF> Other) const noexcept {
// NOTE: Workaround issue in g++ that does not allow transitive friends: If
// putting this code in the operator== below, we cannot access
// Other.Instance, although it is friended...
if (!isa<ConcreteEF>()) {
return false;
}
if (LHS.Instance == RHS.EF) {
if (Other.Instance == EF) {
return true;
}
if constexpr (IsEqualityComparable<ConcreteEF>) {
return *LHS == *getPtr<ConcreteEF>(RHS.EF);
return *Other == *getPtr<ConcreteEF>(EF);
} else {
return true;
}
}

template <typename ConcreteEF,
typename = std::enable_if_t<
!std::is_same_v<EdgeFunction, std::decay_t<ConcreteEF>> &&
IsEdgeFunction<ConcreteEF>>>
[[nodiscard]] friend bool operator==(EdgeFunctionRef<ConcreteEF> LHS,
const EdgeFunction &RHS) noexcept {
return RHS.equals(LHS);
}

template <typename ConcreteEF,
typename = std::enable_if_t<
!std::is_same_v<EdgeFunction, std::decay_t<ConcreteEF>> &&
Expand Down
2 changes: 1 addition & 1 deletion include/phasar/DataFlow/IfdsIde/FlowFunctions.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ template <typename D, typename Container = std::set<D>> class FlowFunction {
template <typename FF> struct IsFlowFunction {
template <typename D, typename Container>
static std::true_type test(const FlowFunction<D, Container> &);
static std::false_type test(...) {}
static std::false_type test(...);

static constexpr bool value = // NOLINT
std::is_same_v<std::true_type,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ class LLVMBasedBackwardICFG : public LLVMBasedBackwardCFG,
LLVMBasedBackwardICFG(LLVMBasedICFG *ForwardICFG);

private:
using typename ICFGBase::f_t;
using typename ICFGBase::n_t;

[[nodiscard]] FunctionRange getAllFunctionsImpl() const;
[[nodiscard]] f_t getFunctionImpl(llvm::StringRef Fun) const;

Expand Down
3 changes: 3 additions & 0 deletions include/phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ class LLVMBasedICFG : public LLVMBasedCFG, public ICFGBase<LLVMBasedICFG> {
friend ICFGBase;

public:
using typename ICFGBase::f_t;
using typename ICFGBase::n_t;

// For backward compatibility
static constexpr llvm::StringLiteral GlobalCRuntimeModelName =
GlobalCtorsDtorsModel::ModelName;
Expand Down
2 changes: 2 additions & 0 deletions include/phasar/PhasarLLVM/ControlFlow/SparseLLVMBasedCFG.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ class SparseLLVMBasedCFG : public LLVMBasedCFG,
friend struct SVFGCache;
friend SparseCFGBase<SparseLLVMBasedCFG>;

using typename LLVMBasedCFG::n_t;

public:
using vgraph_t =
llvm::SmallDenseMap<const llvm::Instruction *, const llvm::Instruction *>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ class SparseLLVMBasedICFG
friend SparseLLVMBasedCFGProvider<SparseLLVMBasedICFG>;

public:
using typename LLVMBasedICFG::f_t;
using typename LLVMBasedICFG::n_t;

/// Constructor that delegates all arguments to the ctor of LLVMBasedICFG
explicit SparseLLVMBasedICFG(LLVMProjectIRDB *IRDB,
CallGraphAnalysisType CGType,
Expand All @@ -47,7 +50,7 @@ class SparseLLVMBasedICFG
LLVMAliasInfoRef PT);

explicit SparseLLVMBasedICFG(LLVMProjectIRDB *IRDB,
const nlohmann::json &SerializedCG,
const CallGraphData &SerializedCG,
LLVMAliasInfoRef PT);

~SparseLLVMBasedICFG();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ class SparseLLVMBasedICFGView
friend SparseLLVMBasedCFGProvider<SparseLLVMBasedICFGView>;

public:
using typename LLVMBasedCFG::f_t;
using typename LLVMBasedCFG::n_t;

explicit SparseLLVMBasedICFGView(const LLVMBasedICFG *ICF,
LLVMAliasInfoRef PT);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,10 @@ class DefaultAliasAwareIDEProblem
protected detail::IDEAliasAwareDefaultFlowFunctionsImpl {
public:
using typename IDETabulationProblem<AnalysisDomainTy>::db_t;
using typename IDETabulationProblem<AnalysisDomainTy>::n_t;
using typename IDETabulationProblem<AnalysisDomainTy>::f_t;
using typename IDETabulationProblem<AnalysisDomainTy>::d_t;
using typename IDETabulationProblem<AnalysisDomainTy>::FlowFunctionPtrType;

using detail::IDEAliasAwareDefaultFlowFunctionsImpl::getAliasInfo;

Expand Down Expand Up @@ -110,6 +114,11 @@ class DefaultAliasAwareIFDSProblem
: public IFDSTabulationProblem<LLVMAnalysisDomainDefault>,
protected detail::IDEAliasAwareDefaultFlowFunctionsImpl {
public:
using typename IFDSTabulationProblem::d_t;
using typename IFDSTabulationProblem::f_t;
using typename IFDSTabulationProblem::FlowFunctionPtrType;
using typename IFDSTabulationProblem::n_t;

/// Constructs an IFDSTabulationProblem with the usual arguments + alias
/// information.
///
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ class DefaultNoAliasIDEProblem
public:
using IDETabulationProblem<AnalysisDomainTy>::IDETabulationProblem;

using typename IDETabulationProblem<AnalysisDomainTy>::f_t;
using typename IDETabulationProblem<AnalysisDomainTy>::FlowFunctionPtrType;
using typename IDETabulationProblem<AnalysisDomainTy>::n_t;

[[nodiscard]] FlowFunctionPtrType getNormalFlowFunction(n_t Curr,
n_t Succ) override {
return getNormalFlowFunctionImpl(Curr, Succ);
Expand Down Expand Up @@ -89,6 +93,12 @@ class DefaultNoAliasIFDSProblem
public:
using IFDSTabulationProblem::IFDSTabulationProblem;

using typename IFDSTabulationProblem::d_t;
using typename IFDSTabulationProblem::f_t;
using typename IFDSTabulationProblem::FlowFunctionPtrType;
using typename IFDSTabulationProblem::l_t;
using typename IFDSTabulationProblem::n_t;

[[nodiscard]] FlowFunctionPtrType getNormalFlowFunction(n_t Curr,
n_t Succ) override {
return getNormalFlowFunctionImpl(Curr, Succ);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ class DefaultReachableAllocationSitesIDEProblem
protected detail::IDEReachableAllocationSitesDefaultFlowFunctionsImpl {
public:
using typename IDETabulationProblem<AnalysisDomainTy>::db_t;
using typename IDETabulationProblem<AnalysisDomainTy>::d_t;
using typename IDETabulationProblem<AnalysisDomainTy>::f_t;
using typename IDETabulationProblem<AnalysisDomainTy>::n_t;
using typename IDETabulationProblem<AnalysisDomainTy>::FlowFunctionPtrType;

/// Constructs an IDETabulationProblem with the usual arguments + alias
/// information.
Expand Down Expand Up @@ -109,6 +113,12 @@ class DefaultReachableAllocationSitesIFDSProblem
: public IFDSTabulationProblem<LLVMIFDSAnalysisDomainDefault>,
protected detail::IDEReachableAllocationSitesDefaultFlowFunctionsImpl {
public:
using typename IFDSTabulationProblem::d_t;
using typename IFDSTabulationProblem::db_t;
using typename IFDSTabulationProblem::f_t;
using typename IFDSTabulationProblem::FlowFunctionPtrType;
using typename IFDSTabulationProblem::n_t;

/// Constructs an IFDSTabulationProblem with the usual arguments + alias
/// information.
///
Expand Down
20 changes: 15 additions & 5 deletions include/phasar/PhasarLLVM/DataFlow/IfdsIde/LLVMZeroValue.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
#ifndef PHASAR_PHASARLLVM_DATAFLOW_IFDSIDE_LLVMZEROVALUE_H
#define PHASAR_PHASARLLVM_DATAFLOW_IFDSIDE_LLVMZEROVALUE_H

#include "phasar/Utils/Fn.h"

#include "llvm/ADT/StringRef.h"
#include "llvm/IR/GlobalVariable.h"

Expand All @@ -36,6 +38,9 @@ class LLVMZeroValue : public llvm::GlobalVariable {
LLVMZeroValue(llvm::Module &Mod);

static constexpr llvm::StringLiteral LLVMZeroValueInternalName = "zero_value";
static bool isZeroValueImpl(const llvm::Value *V) noexcept {
return V == getInstance();
}

public:
LLVMZeroValue(const LLVMZeroValue &Z) = delete;
Expand All @@ -48,13 +53,18 @@ class LLVMZeroValue : public llvm::GlobalVariable {
return LLVMZeroValueInternalName;
}

// Do not specify a destructor (at all)!
static const LLVMZeroValue *getInstance();
/// Gets the singleton instance of the special zero value (aka. Λ).
[[nodiscard]] static const LLVMZeroValue *getInstance();

/// Checks, whether the given llvm::Value * is the special zero-value (aka.
/// Λ).
///
/// You can use this as follows:
/// \code
/// return strongUpdateStore(Store, LLVMZeroValue::isLLVMZeroValue);
/// \endcode
// NOLINTNEXTLINE(readability-identifier-naming)
static constexpr auto isLLVMZeroValue = [](const llvm::Value *V) noexcept {
return V == getInstance();
};
static constexpr auto isLLVMZeroValue = fn<isZeroValueImpl>;
};
} // namespace psr

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -969,17 +969,6 @@ class IDEInstInteractionAnalysisT

[[nodiscard]] bool isConstant() const noexcept { return true; }

friend llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
const IIAAKillOrReplaceEF &EF) {
OS << "EF: (IIAAKillOrReplaceEF)<->";
if (EF.isKillAll()) {
OS << "(KillAll";
} else {
IDEInstInteractionAnalysisT::printEdgeFactImpl(OS, EF.Replacement);
}
return OS << ")";
}

[[nodiscard]] bool isKillAll() const noexcept {
if (auto *RSet = std::get_if<BitVectorSet<e_t>>(&Replacement)) {
return RSet->empty();
Expand All @@ -993,6 +982,20 @@ class IDEInstInteractionAnalysisT
}
};

// Note: Having this operator a friend of the IDEInstInteractionAnalysisT
// (instead of IIAAKillOrReplaceEF) is required for gcc; otherwise, it cannot
// call the protected function printEdgeFactImpl.
friend llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
const IIAAKillOrReplaceEF &EF) {
OS << "EF: (IIAAKillOrReplaceEF)<->";
if (EF.isKillAll()) {
OS << "(KillAll";
} else {
IDEInstInteractionAnalysisT::printEdgeFactImpl(OS, EF.Replacement);
}
return OS << ")";
}

// Edge function that adds the given labels to existing labels
// add all labels provided by Data.
struct IIAAAddLabelsEF {
Expand All @@ -1018,19 +1021,22 @@ class IDEInstInteractionAnalysisT
return Data == Other.Data;
}

friend llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
const IIAAAddLabelsEF &EF) {
OS << "EF: (IIAAAddLabelsEF: ";
IDEInstInteractionAnalysisT::printEdgeFactImpl(OS, EF.Data);
return OS << ")";
}

// NOLINTNEXTLINE(readability-identifier-naming) -- needed for ADL
friend llvm::hash_code hash_value(const IIAAAddLabelsEF &EF) {
return hash_value(EF.Data);
}
};

// Note: Having this operator a friend of the IDEInstInteractionAnalysisT
// (instead of IIAAAddLabelsEF) is required for gcc; otherwise, it cannot
// call the protected function printEdgeFactImpl.
friend llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
const IIAAAddLabelsEF &EF) {
OS << "EF: (IIAAAddLabelsEF: ";
IDEInstInteractionAnalysisT::printEdgeFactImpl(OS, EF.Data);
return OS << ")";
}

const auto &getData(const EdgeFunction<l_t> &EF) {
if (const auto *AddLabels = llvm::dyn_cast<IIAAAddLabelsEF>(EF)) {
return AddLabels->Data;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "phasar/PhasarLLVM/DataFlow/IfdsIde/LLVMZeroValue.h"
#include "phasar/PhasarLLVM/Domain/LLVMAnalysisDomain.h"
#include "phasar/PhasarLLVM/Pointer/LLVMAliasInfo.h"
#include "phasar/PhasarLLVM/Utils/LLVMShorthands.h"
#include "phasar/Utils/JoinLattice.h"
#include "phasar/Utils/Logger.h"
#include "phasar/Utils/Printer.h"
Expand All @@ -41,7 +42,7 @@ namespace detail {
class IDETypeStateAnalysisBaseCommon : public LLVMAnalysisDomainDefault {
public:
using container_type = std::set<d_t>;
using FlowFunctionPtrType = FlowFunctionPtrType<d_t, container_type>;
using FlowFunctionPtrType = psr::FlowFunctionPtrType<d_t, container_type>;
};

class IDETypeStateAnalysisBase
Expand Down Expand Up @@ -217,7 +218,7 @@ class IDETypeStateAnalysis
};

struct TSEdgeFunction {
using l_t = l_t;
using l_t = IDETypeStateAnalysis::l_t;
const TypeStateDescriptionTy *TSD{};
// XXX: Do we really need a string here? Can't we just use an integer or sth
// else that is cheap?
Expand Down
13 changes: 6 additions & 7 deletions include/phasar/PhasarLLVM/HelperAnalyses.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,12 @@
#define PHASAR_PHASARLLVM_HELPERANALYSES_H

#include "phasar/ControlFlow/CallGraphAnalysisType.h"
#include "phasar/ControlFlow/CallGraphData.h"
#include "phasar/PhasarLLVM/HelperAnalysisConfig.h"

#include "nlohmann/json.hpp"
#include "phasar/PhasarLLVM/Pointer/LLVMAliasSetData.h"

#include <memory>
#include <optional>
#include <set>
#include <vector>

namespace llvm {
Expand All @@ -34,10 +33,10 @@ class LLVMAliasSet;
class HelperAnalyses { // NOLINT(cppcoreguidelines-special-member-functions)
public:
explicit HelperAnalyses(std::string IRFile,
std::optional<nlohmann::json> PrecomputedPTS,
std::optional<LLVMAliasSetData> PrecomputedPTS,
AliasAnalysisType PTATy, bool AllowLazyPTS,
std::vector<std::string> EntryPoints,
std::optional<nlohmann::json> PrecomputedCG,
std::optional<CallGraphData> PrecomputedCG,
CallGraphAnalysisType CGTy, Soundness SoundnessLevel,
bool AutoGlobalSupport) noexcept;

Expand Down Expand Up @@ -75,12 +74,12 @@ class HelperAnalyses { // NOLINT(cppcoreguidelines-special-member-functions)
std::string IRFile;

// PTS
std::optional<nlohmann::json> PrecomputedPTS;
std::optional<LLVMAliasSetData> PrecomputedPTS;
AliasAnalysisType PTATy{};
bool AllowLazyPTS{};

// ICF
std::optional<nlohmann::json> PrecomputedCG;
std::optional<CallGraphData> PrecomputedCG;
std::vector<std::string> EntryPoints;
CallGraphAnalysisType CGTy{};
Soundness SoundnessLevel{};
Expand Down
Loading
Loading