diff --git a/CMakeLists.txt b/CMakeLists.txt index 58083e3b98..e11ae302d5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -82,6 +82,11 @@ option(PHASAR_BUILD_MODULES "Build C++20 modules for phasar" OFF) include(CheckCXXCompilerFlag) +if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + # Match clang's behavior, when handling naming collisions, such as "using l_t = l_t;" + string(APPEND CMAKE_CXX_FLAGS " -fpermissive") +endif() + # Handle memory issues with linking if (CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "GNU") string(APPEND CMAKE_CXX_FLAGS_DEBUG " -gsplit-dwarf") diff --git a/include/phasar/ControlFlow/CallGraphBase.h b/include/phasar/ControlFlow/CallGraphBase.h index 67bfb0cc94..1bc44b603c 100644 --- a/include/phasar/ControlFlow/CallGraphBase.h +++ b/include/phasar/ControlFlow/CallGraphBase.h @@ -37,7 +37,7 @@ template class CallGraphBase : public CRTPBase { /// NOTE: This function is typically called in a hot part of the analysis and /// should therefore be very fast [[nodiscard]] decltype(auto) getCalleesOfCallAt(ByConstRef Inst) const - noexcept(noexcept(self().getCalleesOfCallAtImpl(Inst))) { + noexcept(noexcept(this->self().getCalleesOfCallAtImpl(Inst))) { static_assert( is_iterable_over_v); return self().getCalleesOfCallAtImpl(Inst); @@ -47,7 +47,7 @@ template class CallGraphBase : public CRTPBase { /// call the given function induced by the used call-graph. [[nodiscard]] decltype(auto) getCallersOf(ByConstRef Fun) const { static_assert( - is_iterable_over_v); + is_iterable_over_vself().getCallersOfImpl(Fun)), n_t>); return self().getCallersOfImpl(Fun); } }; diff --git a/include/phasar/DataFlow/IfdsIde/EdgeFunction.h b/include/phasar/DataFlow/IfdsIde/EdgeFunction.h index 0559e17afe..5e06b89e12 100644 --- a/include/phasar/DataFlow/IfdsIde/EdgeFunction.h +++ b/include/phasar/DataFlow/IfdsIde/EdgeFunction.h @@ -442,21 +442,32 @@ class [[clang::trivial_abi]] EdgeFunction final : EdgeFunctionBase { typename = std::enable_if_t< !std::is_same_v> && IsEdgeFunction>> - [[nodiscard]] friend bool operator==(EdgeFunctionRef LHS, - const EdgeFunction &RHS) noexcept { - if (!RHS.template isa()) { + [[nodiscard]] bool equals(EdgeFunctionRef 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()) { return false; } - if (LHS.Instance == RHS.EF) { + if (Other.Instance == EF) { return true; } if constexpr (IsEqualityComparable) { - return *LHS == *getPtr(RHS.EF); + return *Other == *getPtr(EF); } else { return true; } } + template > && + IsEdgeFunction>> + [[nodiscard]] friend bool operator==(EdgeFunctionRef LHS, + const EdgeFunction &RHS) noexcept { + return RHS.equals(LHS); + } + template > && diff --git a/include/phasar/DataFlow/IfdsIde/FlowFunctions.h b/include/phasar/DataFlow/IfdsIde/FlowFunctions.h index 6e54fe3936..783a5a3e91 100644 --- a/include/phasar/DataFlow/IfdsIde/FlowFunctions.h +++ b/include/phasar/DataFlow/IfdsIde/FlowFunctions.h @@ -73,7 +73,7 @@ template > class FlowFunction { template struct IsFlowFunction { template static std::true_type test(const FlowFunction &); - static std::false_type test(...) {} + static std::false_type test(...); static constexpr bool value = // NOLINT std::is_same_v { friend ICFGBase; public: + using typename ICFGBase::f_t; + using typename ICFGBase::n_t; + // For backward compatibility static constexpr llvm::StringLiteral GlobalCRuntimeModelName = GlobalCtorsDtorsModel::ModelName; diff --git a/include/phasar/PhasarLLVM/ControlFlow/SparseLLVMBasedCFG.h b/include/phasar/PhasarLLVM/ControlFlow/SparseLLVMBasedCFG.h index 6524bfad04..b4e41c2c44 100644 --- a/include/phasar/PhasarLLVM/ControlFlow/SparseLLVMBasedCFG.h +++ b/include/phasar/PhasarLLVM/ControlFlow/SparseLLVMBasedCFG.h @@ -30,6 +30,8 @@ class SparseLLVMBasedCFG : public LLVMBasedCFG, friend struct SVFGCache; friend SparseCFGBase; + using typename LLVMBasedCFG::n_t; + public: using vgraph_t = llvm::SmallDenseMap; diff --git a/include/phasar/PhasarLLVM/ControlFlow/SparseLLVMBasedICFG.h b/include/phasar/PhasarLLVM/ControlFlow/SparseLLVMBasedICFG.h index d9a1d9a931..f2fc45c0b5 100644 --- a/include/phasar/PhasarLLVM/ControlFlow/SparseLLVMBasedICFG.h +++ b/include/phasar/PhasarLLVM/ControlFlow/SparseLLVMBasedICFG.h @@ -33,6 +33,9 @@ class SparseLLVMBasedICFG friend SparseLLVMBasedCFGProvider; 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, @@ -47,7 +50,7 @@ class SparseLLVMBasedICFG LLVMAliasInfoRef PT); explicit SparseLLVMBasedICFG(LLVMProjectIRDB *IRDB, - const nlohmann::json &SerializedCG, + const CallGraphData &SerializedCG, LLVMAliasInfoRef PT); ~SparseLLVMBasedICFG(); diff --git a/include/phasar/PhasarLLVM/ControlFlow/SparseLLVMBasedICFGView.h b/include/phasar/PhasarLLVM/ControlFlow/SparseLLVMBasedICFGView.h index 25b773d675..303bee8fb3 100644 --- a/include/phasar/PhasarLLVM/ControlFlow/SparseLLVMBasedICFGView.h +++ b/include/phasar/PhasarLLVM/ControlFlow/SparseLLVMBasedICFGView.h @@ -45,6 +45,9 @@ class SparseLLVMBasedICFGView friend SparseLLVMBasedCFGProvider; public: + using typename LLVMBasedCFG::f_t; + using typename LLVMBasedCFG::n_t; + explicit SparseLLVMBasedICFGView(const LLVMBasedICFG *ICF, LLVMAliasInfoRef PT); diff --git a/include/phasar/PhasarLLVM/DataFlow/IfdsIde/DefaultAliasAwareIDEProblem.h b/include/phasar/PhasarLLVM/DataFlow/IfdsIde/DefaultAliasAwareIDEProblem.h index aac4390f97..0f1214504d 100644 --- a/include/phasar/PhasarLLVM/DataFlow/IfdsIde/DefaultAliasAwareIDEProblem.h +++ b/include/phasar/PhasarLLVM/DataFlow/IfdsIde/DefaultAliasAwareIDEProblem.h @@ -65,6 +65,10 @@ class DefaultAliasAwareIDEProblem protected detail::IDEAliasAwareDefaultFlowFunctionsImpl { public: using typename IDETabulationProblem::db_t; + using typename IDETabulationProblem::n_t; + using typename IDETabulationProblem::f_t; + using typename IDETabulationProblem::d_t; + using typename IDETabulationProblem::FlowFunctionPtrType; using detail::IDEAliasAwareDefaultFlowFunctionsImpl::getAliasInfo; @@ -110,6 +114,11 @@ class DefaultAliasAwareIFDSProblem : public IFDSTabulationProblem, 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. /// diff --git a/include/phasar/PhasarLLVM/DataFlow/IfdsIde/DefaultNoAliasIDEProblem.h b/include/phasar/PhasarLLVM/DataFlow/IfdsIde/DefaultNoAliasIDEProblem.h index 3bb35b42ca..19c00ac008 100644 --- a/include/phasar/PhasarLLVM/DataFlow/IfdsIde/DefaultNoAliasIDEProblem.h +++ b/include/phasar/PhasarLLVM/DataFlow/IfdsIde/DefaultNoAliasIDEProblem.h @@ -59,6 +59,10 @@ class DefaultNoAliasIDEProblem public: using IDETabulationProblem::IDETabulationProblem; + using typename IDETabulationProblem::f_t; + using typename IDETabulationProblem::FlowFunctionPtrType; + using typename IDETabulationProblem::n_t; + [[nodiscard]] FlowFunctionPtrType getNormalFlowFunction(n_t Curr, n_t Succ) override { return getNormalFlowFunctionImpl(Curr, Succ); @@ -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); diff --git a/include/phasar/PhasarLLVM/DataFlow/IfdsIde/DefaultReachableAllocationSitesIDEProblem.h b/include/phasar/PhasarLLVM/DataFlow/IfdsIde/DefaultReachableAllocationSitesIDEProblem.h index eac661ccd4..2f127432c4 100644 --- a/include/phasar/PhasarLLVM/DataFlow/IfdsIde/DefaultReachableAllocationSitesIDEProblem.h +++ b/include/phasar/PhasarLLVM/DataFlow/IfdsIde/DefaultReachableAllocationSitesIDEProblem.h @@ -66,6 +66,10 @@ class DefaultReachableAllocationSitesIDEProblem protected detail::IDEReachableAllocationSitesDefaultFlowFunctionsImpl { public: using typename IDETabulationProblem::db_t; + using typename IDETabulationProblem::d_t; + using typename IDETabulationProblem::f_t; + using typename IDETabulationProblem::n_t; + using typename IDETabulationProblem::FlowFunctionPtrType; /// Constructs an IDETabulationProblem with the usual arguments + alias /// information. @@ -109,6 +113,12 @@ class DefaultReachableAllocationSitesIFDSProblem : public IFDSTabulationProblem, 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. /// diff --git a/include/phasar/PhasarLLVM/DataFlow/IfdsIde/LLVMZeroValue.h b/include/phasar/PhasarLLVM/DataFlow/IfdsIde/LLVMZeroValue.h index 729e3c44a5..875039e877 100644 --- a/include/phasar/PhasarLLVM/DataFlow/IfdsIde/LLVMZeroValue.h +++ b/include/phasar/PhasarLLVM/DataFlow/IfdsIde/LLVMZeroValue.h @@ -36,6 +36,10 @@ 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 + return V == getInstance(); + } public: LLVMZeroValue(const LLVMZeroValue &Z) = delete; @@ -53,7 +57,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); }; }; } // namespace psr diff --git a/include/phasar/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEInstInteractionAnalysis.h b/include/phasar/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEInstInteractionAnalysis.h index 4bfe3ecccd..799f6f13a6 100644 --- a/include/phasar/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEInstInteractionAnalysis.h +++ b/include/phasar/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEInstInteractionAnalysis.h @@ -942,6 +942,14 @@ class IDEInstInteractionAnalysisT inline l_t join(l_t Lhs, l_t Rhs) override { return joinImpl(Lhs, Rhs); } + struct IIAAKillOrReplaceEF; + struct IIAAAddLabelsEF; + // These friend declarations are needed to make gcc happy + friend llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, + const IIAAKillOrReplaceEF &EF); + friend llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, + const IIAAAddLabelsEF &EF); + // Provide some handy helper edge functions to improve reuse. // Edge function that kills all labels in a set (and may replaces them with diff --git a/include/phasar/PhasarLLVM/DataFlow/IfdsIde/Problems/IDETypeStateAnalysis.h b/include/phasar/PhasarLLVM/DataFlow/IfdsIde/Problems/IDETypeStateAnalysis.h index 35226bf2f7..19c593e8be 100644 --- a/include/phasar/PhasarLLVM/DataFlow/IfdsIde/Problems/IDETypeStateAnalysis.h +++ b/include/phasar/PhasarLLVM/DataFlow/IfdsIde/Problems/IDETypeStateAnalysis.h @@ -195,8 +195,7 @@ class IDETypeStateAnalysis } [[no_unique_address]] std::conditional_t, - EmptyType, l_t> - BotElement{}; + EmptyType, l_t> BotElement{}; static EdgeFunction join(EdgeFunctionRef This, const EdgeFunction &OtherFunction) { diff --git a/include/phasar/PhasarLLVM/HelperAnalyses.h b/include/phasar/PhasarLLVM/HelperAnalyses.h index 2c6f06000b..c3287ffe94 100644 --- a/include/phasar/PhasarLLVM/HelperAnalyses.h +++ b/include/phasar/PhasarLLVM/HelperAnalyses.h @@ -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 #include -#include #include namespace llvm { @@ -34,10 +33,10 @@ class LLVMAliasSet; class HelperAnalyses { // NOLINT(cppcoreguidelines-special-member-functions) public: explicit HelperAnalyses(std::string IRFile, - std::optional PrecomputedPTS, + std::optional PrecomputedPTS, AliasAnalysisType PTATy, bool AllowLazyPTS, std::vector EntryPoints, - std::optional PrecomputedCG, + std::optional PrecomputedCG, CallGraphAnalysisType CGTy, Soundness SoundnessLevel, bool AutoGlobalSupport) noexcept; @@ -75,12 +74,12 @@ class HelperAnalyses { // NOLINT(cppcoreguidelines-special-member-functions) std::string IRFile; // PTS - std::optional PrecomputedPTS; + std::optional PrecomputedPTS; AliasAnalysisType PTATy{}; bool AllowLazyPTS{}; // ICF - std::optional PrecomputedCG; + std::optional PrecomputedCG; std::vector EntryPoints; CallGraphAnalysisType CGTy{}; Soundness SoundnessLevel{}; diff --git a/include/phasar/PhasarLLVM/HelperAnalysisConfig.h b/include/phasar/PhasarLLVM/HelperAnalysisConfig.h index df59c41c52..be3427667b 100644 --- a/include/phasar/PhasarLLVM/HelperAnalysisConfig.h +++ b/include/phasar/PhasarLLVM/HelperAnalysisConfig.h @@ -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 namespace psr { struct HelperAnalysisConfig { - std::optional PrecomputedPTS = std::nullopt; - std::optional PrecomputedCG = std::nullopt; + std::optional PrecomputedPTS = std::nullopt; + std::optional PrecomputedCG = std::nullopt; AliasAnalysisType PTATy = AliasAnalysisType::CFLAnders; CallGraphAnalysisType CGTy = CallGraphAnalysisType::OTF; Soundness SoundnessLevel = Soundness::Soundy; @@ -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); } diff --git a/include/phasar/PhasarLLVM/Pointer/LLVMAliasSet.h b/include/phasar/PhasarLLVM/Pointer/LLVMAliasSet.h index eeffe7412a..5b99be1654 100644 --- a/include/phasar/PhasarLLVM/Pointer/LLVMAliasSet.h +++ b/include/phasar/PhasarLLVM/Pointer/LLVMAliasSet.h @@ -63,7 +63,7 @@ class LLVMAliasSet : public AnalysisPropertiesMixin, /// Loads alias sets from JSON explicit LLVMAliasSet(LLVMProjectIRDB *IRDB, - const nlohmann::json &SerializedPTS); + const LLVMAliasSetData &SerializedPTS); [[nodiscard]] inline bool isInterProcedural() const noexcept { return false; diff --git a/lib/AnalysisStrategy/Strategies.cpp b/lib/AnalysisStrategy/Strategies.cpp index 844b4e650c..9b99ef33be 100644 --- a/lib/AnalysisStrategy/Strategies.cpp +++ b/lib/AnalysisStrategy/Strategies.cpp @@ -10,6 +10,7 @@ #include "phasar/AnalysisStrategy/Strategies.h" #include "llvm/ADT/StringSwitch.h" +#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" namespace psr { @@ -24,6 +25,7 @@ std::string toString(const AnalysisStrategy &S) { case AnalysisStrategy::None: return "None"; } + llvm_unreachable("All alternatives should be handled by the switch above"); } AnalysisStrategy toAnalysisStrategy(llvm::StringRef S) { diff --git a/lib/ControlFlow/CallGraphAnalysisType.cpp b/lib/ControlFlow/CallGraphAnalysisType.cpp index 64473cc95e..e244e28a86 100644 --- a/lib/ControlFlow/CallGraphAnalysisType.cpp +++ b/lib/ControlFlow/CallGraphAnalysisType.cpp @@ -21,6 +21,7 @@ std::string psr::toString(CallGraphAnalysisType CGA) { case CallGraphAnalysisType::Invalid: return "Invalid"; } + llvm_unreachable("All alternatives should be handled by the switch above"); } psr::CallGraphAnalysisType psr::toCallGraphAnalysisType(llvm::StringRef S) { diff --git a/lib/PhasarLLVM/ControlFlow/SparseLLVMBasedICFG.cpp b/lib/PhasarLLVM/ControlFlow/SparseLLVMBasedICFG.cpp index ccaf80b2cf..2ef09c1a3d 100644 --- a/lib/PhasarLLVM/ControlFlow/SparseLLVMBasedICFG.cpp +++ b/lib/PhasarLLVM/ControlFlow/SparseLLVMBasedICFG.cpp @@ -1,5 +1,6 @@ #include "phasar/PhasarLLVM/ControlFlow/SparseLLVMBasedICFG.h" +#include "phasar/ControlFlow/CallGraphData.h" #include "phasar/PhasarLLVM/Pointer/LLVMAliasInfo.h" #include "SVFGCache.h" @@ -32,7 +33,7 @@ SparseLLVMBasedICFG::SparseLLVMBasedICFG(CallGraph CG, AliasAnalysis(PT) {} SparseLLVMBasedICFG::SparseLLVMBasedICFG(LLVMProjectIRDB *IRDB, - const nlohmann::json &SerializedCG, + const CallGraphData &SerializedCG, LLVMAliasInfoRef PT) : LLVMBasedICFG(IRDB, SerializedCG), SparseCFGCache(new SVFGCache{}), AliasAnalysis(PT) {} diff --git a/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEFeatureTaintAnalysis.cpp b/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEFeatureTaintAnalysis.cpp index 1941ba9ef6..729a493b67 100644 --- a/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEFeatureTaintAnalysis.cpp +++ b/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEFeatureTaintAnalysis.cpp @@ -357,11 +357,11 @@ struct IDEFeatureTaintAnalysis::GenerateEF { llvm::report_fatal_error("Implemented in 'combine'"); } - constexpr friend bool operator==(const GenerateEF &L, const GenerateEF &R) { + friend bool operator==(const GenerateEF &L, const GenerateEF &R) { return L.Facts == R.Facts; } - constexpr friend llvm::hash_code hash_value(const GenerateEF &EF) { + friend llvm::hash_code hash_value(const GenerateEF &EF) { return hash_value(EF.Facts); } }; diff --git a/lib/PhasarLLVM/HelperAnalyses.cpp b/lib/PhasarLLVM/HelperAnalyses.cpp index ce9b2f095f..721a313db3 100644 --- a/lib/PhasarLLVM/HelperAnalyses.cpp +++ b/lib/PhasarLLVM/HelperAnalyses.cpp @@ -3,6 +3,7 @@ #include "phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h" #include "phasar/PhasarLLVM/DB/LLVMProjectIRDB.h" #include "phasar/PhasarLLVM/Pointer/LLVMAliasSet.h" +#include "phasar/PhasarLLVM/Pointer/LLVMAliasSetData.h" #include "phasar/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.h" #include @@ -10,10 +11,10 @@ namespace psr { HelperAnalyses::HelperAnalyses(std::string IRFile, - std::optional PrecomputedPTS, + std::optional PrecomputedPTS, AliasAnalysisType PTATy, bool AllowLazyPTS, std::vector EntryPoints, - std::optional PrecomputedCG, + std::optional PrecomputedCG, CallGraphAnalysisType CGTy, Soundness SoundnessLevel, bool AutoGlobalSupport) noexcept diff --git a/lib/PhasarLLVM/Passes/GeneralStatisticsAnalysis.cpp b/lib/PhasarLLVM/Passes/GeneralStatisticsAnalysis.cpp index 4575fa59ea..9c96aafc28 100644 --- a/lib/PhasarLLVM/Passes/GeneralStatisticsAnalysis.cpp +++ b/lib/PhasarLLVM/Passes/GeneralStatisticsAnalysis.cpp @@ -323,7 +323,7 @@ template struct AlignNum { } }; template AlignNum(llvm::StringRef, T) -> AlignNum; -AlignNum(llvm::StringRef, size_t, size_t)->AlignNum; +AlignNum(llvm::StringRef, size_t, size_t) -> AlignNum; } // namespace llvm::raw_ostream &psr::operator<<(llvm::raw_ostream &OS, @@ -353,6 +353,8 @@ llvm::raw_ostream &psr::operator<<(llvm::raw_ostream &OS, << AlignNum("Debug Intrinsics", Statistics.DebugIntrinsics) << AlignNum("Switches", Statistics.Switches) << AlignNum("GetElementPtrs", Statistics.GetElementPtrs) + << AlignNum("Loads", Statistics.LoadInstructions) + << AlignNum("Stores", Statistics.StoreInstructions) << AlignNum("Phi Nodes", Statistics.PhiNodes) << AlignNum("LandingPads", Statistics.LandingPads) << AlignNum("Basic Blocks", Statistics.BasicBlocks) diff --git a/lib/PhasarLLVM/Pointer/LLVMAliasSet.cpp b/lib/PhasarLLVM/Pointer/LLVMAliasSet.cpp index 7b216842c2..d66b161618 100644 --- a/lib/PhasarLLVM/Pointer/LLVMAliasSet.cpp +++ b/lib/PhasarLLVM/Pointer/LLVMAliasSet.cpp @@ -97,7 +97,7 @@ LLVMAliasSet::LLVMAliasSet(LLVMProjectIRDB *IRDB, bool UseLazyEvaluation, } LLVMAliasSet::LLVMAliasSet(LLVMProjectIRDB *IRDB, - const nlohmann::json &SerializedPTS) + const LLVMAliasSetData &SerializedPTS) : PTA(AliasAnalysisView::create(*IRDB, true, AliasAnalysisType::Basic)) { assert(IRDB != nullptr); // Assume, we already have validated the json schema @@ -105,23 +105,19 @@ LLVMAliasSet::LLVMAliasSet(LLVMProjectIRDB *IRDB, PHASAR_LOG_LEVEL_CAT(DEBUG, "LLVMAliasSet", "Load precomputed points-to info from JSON"); - const auto &Sets = SerializedPTS.at("AliasSets"); - assert(Sets.is_array()); - const auto &Fns = SerializedPTS.at("AnalyzedFunctions"); - assert(Fns.is_array()); + const auto &Sets = SerializedPTS.AliasSets; + const auto &Fns = SerializedPTS.AnalyzedFunctions; /// Deserialize the AliasSets - an array of arrays (both are to be /// interpreted as sets of metadata-ids) Owner.reserve(Sets.size()); for (const auto &PtsJson : Sets) { - assert(PtsJson.is_array()); auto PTS = Owner.acquire(); for (const auto &Alias : PtsJson) { - const auto AliasStr = Alias.get(); - const auto *Inst = fromMetaDataId(*IRDB, AliasStr); + const auto *Inst = fromMetaDataId(*IRDB, Alias); if (!Inst) { - PHASAR_LOG_LEVEL(WARNING, "Invalid Value-Id: " << AliasStr); + PHASAR_LOG_LEVEL(WARNING, "Invalid Value-Id: " << Alias); continue; } @@ -135,12 +131,7 @@ LLVMAliasSet::LLVMAliasSet(LLVMProjectIRDB *IRDB, AnalyzedFunctions.reserve(Fns.size()); for (const auto &F : Fns) { - if (!F.is_string()) { - PHASAR_LOG_LEVEL(WARNING, "Invalid Function Name: " << F); - continue; - } - - const auto *IRFn = IRDB->getFunction(F.get()); + const auto *IRFn = IRDB->getFunction(F); if (!IRFn) { PHASAR_LOG_LEVEL(WARNING, "Function: " << F << " not in the IRDB"); diff --git a/lib/Utils/NlohmannLogging.cpp b/lib/Utils/NlohmannLogging.cpp index e84d97c44a..c145e9df5f 100644 --- a/lib/Utils/NlohmannLogging.cpp +++ b/lib/Utils/NlohmannLogging.cpp @@ -43,7 +43,7 @@ class LLVMOutputAdapter { llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const nlohmann::json &J) { // do the actual serialization - nlohmann::detail::serializer S(LLVMOutputAdapter(OS), ' '); + nlohmann::detail::serializer S{LLVMOutputAdapter(OS), ' '}; S.dump(J, true, false, 4); return OS; } diff --git a/tools/phasar-cli/phasar-cli.cpp b/tools/phasar-cli/phasar-cli.cpp index c3addbb994..0169441aae 100644 --- a/tools/phasar-cli/phasar-cli.cpp +++ b/tools/phasar-cli/phasar-cli.cpp @@ -10,8 +10,10 @@ #include "phasar/AnalysisStrategy/Strategies.h" #include "phasar/Config/Configuration.h" #include "phasar/ControlFlow/CallGraphAnalysisType.h" +#include "phasar/ControlFlow/CallGraphData.h" #include "phasar/PhasarLLVM/DB/LLVMProjectIRDB.h" #include "phasar/PhasarLLVM/HelperAnalyses.h" +#include "phasar/PhasarLLVM/Pointer/LLVMAliasSetData.h" #include "phasar/PhasarLLVM/Utils/DataFlowAnalysisType.h" #include "phasar/Pointer/AliasAnalysisType.h" #include "phasar/Utils/IO.h" @@ -442,16 +444,16 @@ int main(int Argc, const char **Argv) { SolverConfig.setComputePersistedSummaries(PersistedSummariesOpt); SolverConfig.setEmitESG(EmitESGAsDotOpt); - std::optional PrecomputedAliasSet; + std::optional PrecomputedAliasSet; if (!LoadPTAFromJsonOpt.empty()) { PHASAR_LOG_LEVEL(INFO, "Load AliasInfo from file: " << LoadCGFromJsonOpt); - PrecomputedAliasSet = readJsonFile(LoadPTAFromJsonOpt); + PrecomputedAliasSet = LLVMAliasSetData::deserializeJson(LoadPTAFromJsonOpt); } - std::optional PrecomputedCallGraph; + std::optional PrecomputedCallGraph; if (!LoadCGFromJsonOpt.empty()) { PHASAR_LOG_LEVEL(INFO, "Load CallGraph from file: " << LoadCGFromJsonOpt); - PrecomputedCallGraph = readJsonFile(LoadCGFromJsonOpt); + PrecomputedCallGraph = CallGraphData::deserializeJson(LoadCGFromJsonOpt); } if (EntryOpt.empty()) { diff --git a/unittests/PhasarLLVM/DataFlow/IfdsIde/DefaultFlowFunctionTest.cpp b/unittests/PhasarLLVM/DataFlow/IfdsIde/DefaultFlowFunctionTest.cpp index 619617ccd0..4edb035297 100644 --- a/unittests/PhasarLLVM/DataFlow/IfdsIde/DefaultFlowFunctionTest.cpp +++ b/unittests/PhasarLLVM/DataFlow/IfdsIde/DefaultFlowFunctionTest.cpp @@ -37,6 +37,10 @@ class IDEAliasImpl : public DefaultAliasAwareIFDSProblem { class IDENoAliasImpl : public DefaultNoAliasIFDSProblem { public: + using typename DefaultNoAliasIFDSProblem::d_t; + using typename DefaultNoAliasIFDSProblem::l_t; + using typename DefaultNoAliasIFDSProblem::n_t; + IDENoAliasImpl(LLVMProjectIRDB *IRDB) : DefaultNoAliasIFDSProblem(IRDB, {}, {}) {}; diff --git a/unittests/PhasarLLVM/Pointer/LLVMAliasSetSerializationTest.cpp b/unittests/PhasarLLVM/Pointer/LLVMAliasSetSerializationTest.cpp index 7d55448ea8..496aeff6b1 100644 --- a/unittests/PhasarLLVM/Pointer/LLVMAliasSetSerializationTest.cpp +++ b/unittests/PhasarLLVM/Pointer/LLVMAliasSetSerializationTest.cpp @@ -3,6 +3,7 @@ #include "phasar/PhasarLLVM/DB/LLVMProjectIRDB.h" #include "phasar/PhasarLLVM/Passes/ValueAnnotationPass.h" #include "phasar/PhasarLLVM/Pointer/LLVMAliasSet.h" +#include "phasar/PhasarLLVM/Pointer/LLVMAliasSetData.h" #include "phasar/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.h" #include "phasar/Utils/Logger.h" @@ -87,7 +88,8 @@ static void analyze(llvm::StringRef File, const GroundTruthTy &Gt, nlohmann::json PrintAsJsonSer = nlohmann::json::parse(SerString); checkSer(PrintAsJsonSer, Gt); - LLVMAliasSet PrintAsJsonDeser(&IRDB, PrintAsJsonSer); + LLVMAliasSet PrintAsJsonDeser(&IRDB, + LLVMAliasSetData::loadJsonString(SerString)); checkDeser(*IRDB.getModule(), PTS, PrintAsJsonDeser); }