Skip to content

GCC Compatibility #787

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: development
Choose a base branch
from
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
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@ class LLVMZeroValue : public llvm::GlobalVariable {
LLVMZeroValue(llvm::Module &Mod);

static constexpr llvm::StringLiteral LLVMZeroValueInternalName = "zero_value";
static bool isZeroValueHelper(const llvm::Value *V) noexcept {
// Need this helper function to make gcc happy;
// Gcc thinks that LLVMZeroValue is incomplete within the below lambda, so
// it cannot compare a LLVMZeroValue* with a Value*
return V == getInstance();
}

public:
LLVMZeroValue(const LLVMZeroValue &Z) = delete;
Expand All @@ -53,7 +59,7 @@ class LLVMZeroValue : public llvm::GlobalVariable {

// NOLINTNEXTLINE(readability-identifier-naming)
static constexpr auto isLLVMZeroValue = [](const llvm::Value *V) noexcept {
return V == getInstance();
return isZeroValueHelper(V);
Comment on lines 61 to +62
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the underlying reason to have a lambda here instead of a normal static member?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The original reason was to make it easier to pass this as callback to other functions, such as in here or here.

Not sure whether it is worth it in the end though.

};
};
} // 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 @@ -18,6 +18,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 @@ -43,7 +44,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 @@ -195,8 +196,7 @@ class IDETypeStateAnalysis
}

[[no_unique_address]] std::conditional_t<HasJoinLatticeTraits<l_t>,
EmptyType, l_t>
BotElement{};
EmptyType, l_t> BotElement{};

static EdgeFunction<l_t> join(EdgeFunctionRef<TSEdgeFunctionComposer> This,
const EdgeFunction<l_t> &OtherFunction) {
Expand All @@ -212,7 +212,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
10 changes: 5 additions & 5 deletions include/phasar/PhasarLLVM/HelperAnalysisConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,17 @@
#define PHASAR_PHASARLLVM_HELPERANALYSISCONFIG_H

#include "phasar/ControlFlow/CallGraphAnalysisType.h"
#include "phasar/ControlFlow/CallGraphData.h"
#include "phasar/PhasarLLVM/Pointer/LLVMAliasSetData.h"
#include "phasar/Pointer/AliasAnalysisType.h"
#include "phasar/Utils/Soundness.h"

#include "nlohmann/json.hpp"

#include <optional>

namespace psr {
struct HelperAnalysisConfig {
std::optional<nlohmann::json> PrecomputedPTS = std::nullopt;
std::optional<nlohmann::json> PrecomputedCG = std::nullopt;
std::optional<LLVMAliasSetData> PrecomputedPTS = std::nullopt;
std::optional<CallGraphData> PrecomputedCG = std::nullopt;
AliasAnalysisType PTATy = AliasAnalysisType::CFLAnders;
CallGraphAnalysisType CGTy = CallGraphAnalysisType::OTF;
Soundness SoundnessLevel = Soundness::Soundy;
Expand All @@ -31,7 +31,7 @@ struct HelperAnalysisConfig {
/// existing llvm::Module
bool PreprocessExistingModule = true;

HelperAnalysisConfig &&withCGType(CallGraphAnalysisType CGTy) &&noexcept {
HelperAnalysisConfig &&withCGType(CallGraphAnalysisType CGTy) && noexcept {
this->CGTy = CGTy;
return std::move(*this);
}
Expand Down
Loading
Loading