diff --git a/CMakeLists.txt b/CMakeLists.txt index 2b8d993810..72e0a73b99 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -38,12 +38,6 @@ else() set(PHASAR_BUILD_OPTIONAL_TARGETS_DEFAULT OFF) endif() -option(PHASAR_EXPERIMENTAL_CXX20 "Build phasar in C++20 mode. This is an experimental feature" OFF) -if(PHASAR_EXPERIMENTAL_CXX20) - message(DEPRECATION "The option PHASAR_EXPERIMENTAL_CXX20 is deprecated and will be removed in a future version of PhASAR. Use CMAKE_CXX_STANDARD=20 instead.") - set(CMAKE_CXX_STANDARD 20) -endif() - set(CMAKE_EXPORT_COMPILE_COMMANDS ON) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) diff --git a/Config.cmake.in b/Config.cmake.in index e531879c5d..fce796ba73 100644 --- a/Config.cmake.in +++ b/Config.cmake.in @@ -61,23 +61,9 @@ foreach(component ${phasar_FIND_COMPONENTS}) endforeach() if (NOT DEFINED phasar_FOUND OR phasar_FOUND EQUAL TRUE) - foreach(component ${phasar_FIND_COMPONENTS}) - # For backwards compatibility -- will be removed with next release - add_library(phasar::phasar_${component} ALIAS phasar::${component}) - endforeach() - if (NOT phasar_FIND_COMPONENTS) list(APPEND PHASAR_NEEDED_LIBS phasar::phasar) # Default target add_library(phasar ALIAS phasar::phasar) endif() - - function(phasar_config executable) - message(DEPRECATION "The function 'phasar_config' is deprecated. Use target_link_libraries(${executable} PUBLIC phasar::phasar) instead!") - - target_link_libraries(${executable} - PUBLIC - ${PHASAR_NEEDED_LIBS} - ) - endfunction() endif() diff --git a/examples/use-phasar-as-library/CMakeLists.txt b/examples/use-phasar-as-library/CMakeLists.txt index 5246e3b823..bacf370078 100644 --- a/examples/use-phasar-as-library/CMakeLists.txt +++ b/examples/use-phasar-as-library/CMakeLists.txt @@ -17,10 +17,7 @@ add_executable(myphasartool myphasartool.cpp ) -# Old way using phasar_config (deprecated): -# phasar_config(myphasartool) - -# New way using target_link_libraries: +# Link your tool against phasar: target_link_libraries(myphasartool phasar::llvm_ifdside) # If find_package did not specify components: diff --git a/include/phasar/AnalysisStrategy/AnalysisSetup.h b/include/phasar/AnalysisStrategy/AnalysisSetup.h index dcdfb6ee2e..975ed1c292 100644 --- a/include/phasar/AnalysisStrategy/AnalysisSetup.h +++ b/include/phasar/AnalysisStrategy/AnalysisSetup.h @@ -12,7 +12,7 @@ #include "phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h" #include "phasar/PhasarLLVM/Pointer/LLVMAliasSet.h" -#include "phasar/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.h" +#include "phasar/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.h" namespace psr { @@ -29,7 +29,7 @@ struct AnalysisSetup { struct DefaultAnalysisSetup : AnalysisSetup { using PointerAnalysisTy = LLVMAliasSet; using CallGraphAnalysisTy = LLVMBasedICFG; - using TypeHierarchyTy = LLVMTypeHierarchy; + using TypeHierarchyTy = DIBasedTypeHierarchy; }; } // namespace psr diff --git a/include/phasar/Config/Configuration.h b/include/phasar/Config/Configuration.h index 1d0f91b789..975e18aa58 100644 --- a/include/phasar/Config/Configuration.h +++ b/include/phasar/Config/Configuration.h @@ -68,29 +68,6 @@ class PhasarConfig { // NOLINTNEXTLINE(readability-identifier-naming) [[nodiscard]] static llvm::StringRef PhasarDirectory() noexcept; - /// Name of the file storing all standard header search paths used for - /// compilation. - [[nodiscard, deprecated("This ancient API is broken and should not be used " - "anymore")]] static constexpr llvm::StringRef - // NOLINTNEXTLINE(readability-identifier-naming) - HeaderSearchPathsFileName() noexcept { - return "standard_header_paths.conf"; - } - - /// Name of the compile_commands.json file (in case we wish to rename) - [[nodiscard, deprecated("This ancient API is broken and should not be used " - "anymore")]] static constexpr llvm::StringRef - // NOLINTNEXTLINE(readability-identifier-naming) - CompileCommandsJson() noexcept { - return "compile_commands.json"; - } - - /// Default Source- and Sink-Functions path - [[nodiscard, deprecated("This ancient API is broken and should not be used " - "anymore")]] static llvm::StringRef - // NOLINTNEXTLINE(readability-identifier-naming) - DefaultSourceSinkFunctionsPath() noexcept; - // Variables to be used in JSON export format /// Identifier for call graph export // NOLINTNEXTLINE(readability-identifier-naming) diff --git a/include/phasar/Config/Version.h b/include/phasar/Config/Version.h deleted file mode 100644 index c5017b860b..0000000000 --- a/include/phasar/Config/Version.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef PHASAR_CONFIG_VERSION_H -#define PHASAR_CONFIG_VERSION_H - -/// Note: This header is only left for backward compatibility and may be removed -/// in the future - -#pragma GCC warning( \ - "The header Version.h is deprecated. Use 'phasar/Config/phasar-config.h' instead") - -#include "phasar/Config/phasar-config.h" - -#endif diff --git a/include/phasar/ControlFlow/CFGBase.h b/include/phasar/ControlFlow/CFGBase.h index 0ec38d5dcb..6f0f1d610d 100644 --- a/include/phasar/ControlFlow/CFGBase.h +++ b/include/phasar/ControlFlow/CFGBase.h @@ -13,8 +13,6 @@ #include "phasar/Utils/ByRef.h" #include "phasar/Utils/TypeTraits.h" -#include "nlohmann/json.hpp" - namespace psr { enum class SpecialMemberFunctionType; @@ -131,10 +129,6 @@ template class CFGBase { void print(ByConstRef Fun, llvm::raw_ostream &OS) const { self().printImpl(Fun, OS); } - [[nodiscard, deprecated("Please use printAsJson() instead")]] nlohmann::json - getAsJson(ByConstRef Fun) const { - return self().getAsJsonImpl(Fun); - } protected: Derived &self() noexcept { return static_cast(*this); } diff --git a/include/phasar/ControlFlow/CallGraph.h b/include/phasar/ControlFlow/CallGraph.h index d73a1b5783..e2a03fec25 100644 --- a/include/phasar/ControlFlow/CallGraph.h +++ b/include/phasar/ControlFlow/CallGraph.h @@ -19,10 +19,7 @@ #include "llvm/IR/Function.h" -#include "nlohmann/json.hpp" - #include -#include #include #include @@ -105,27 +102,6 @@ class CallGraph : public CallGraphBase> { CGData.printAsJson(OS); } - /// Creates a JSON representation of this call-graph suitable for presistent - /// storage. - /// Use the ctor taking a json object for deserialization - template - [[nodiscard]] [[deprecated( - "Please use printAsJson() instead")]] nlohmann::json - getAsJson(FunctionIdGetter GetFunctionId, - InstIdGetter GetInstructionId) const { - nlohmann::json J; - - for (const auto &[Fun, Callers] : CallersOf) { - auto &JCallers = J[std::invoke(GetFunctionId, Fun)]; - - for (const auto &CS : *Callers) { - JCallers.push_back(std::invoke(GetInstructionId, CS)); - } - } - - return J; - } - template void printAsDot(llvm::raw_ostream &OS, FunctionLabelGetter GetFunctionLabel, diff --git a/include/phasar/ControlFlow/CallGraphAnalysisType.def b/include/phasar/ControlFlow/CallGraphAnalysisType.def index 3430b21c07..6576b08318 100644 --- a/include/phasar/ControlFlow/CallGraphAnalysisType.def +++ b/include/phasar/ControlFlow/CallGraphAnalysisType.def @@ -14,7 +14,6 @@ CALL_GRAPH_ANALYSIS_TYPE(NORESOLVE, "nores", "Don't resolve indirect- and virtual calls") CALL_GRAPH_ANALYSIS_TYPE(CHA, "cha", "Class hierarchy analysis") CALL_GRAPH_ANALYSIS_TYPE(RTA, "rta", "Rapid type analysis") -CALL_GRAPH_ANALYSIS_TYPE(DTA, "dta", "Declared type analysis") CALL_GRAPH_ANALYSIS_TYPE(VTA, "vta", "Variable type analysis") CALL_GRAPH_ANALYSIS_TYPE(OTF, "otf", "On-the-fly analysis based on points-to info (default)") diff --git a/include/phasar/ControlFlow/ICFGBase.h b/include/phasar/ControlFlow/ICFGBase.h index bbdd5b75f2..4ef63126d1 100644 --- a/include/phasar/ControlFlow/ICFGBase.h +++ b/include/phasar/ControlFlow/ICFGBase.h @@ -17,8 +17,6 @@ #include "llvm/ADT/StringRef.h" #include "llvm/Support/raw_ostream.h" -#include "nlohmann/json.hpp" - #include namespace psr { @@ -112,13 +110,6 @@ template class ICFGBase { self().printAsJsonImpl(OS); } - /// Returns the underlying call-graph as JSON - [[nodiscard]] [[deprecated( - "Please use printAsJson() instead")]] nlohmann::json - getAsJson() const { - return self().getAsJsonImpl(); - } - [[nodiscard]] size_t getNumCallSites() const noexcept { return self().getNumCallSitesImpl(); } diff --git a/include/phasar/DataFlow/IfdsIde/FlowFunctions.h b/include/phasar/DataFlow/IfdsIde/FlowFunctions.h index c416571c2f..2f3fa53f5c 100644 --- a/include/phasar/DataFlow/IfdsIde/FlowFunctions.h +++ b/include/phasar/DataFlow/IfdsIde/FlowFunctions.h @@ -29,7 +29,6 @@ #include #include #include -#include namespace psr { @@ -872,370 +871,6 @@ class FlowFunctions } }; -//////////////////////////////////////////////////////////////////////////////// -// Legacy Flow Functions -//////////////////////////////////////////////////////////////////////////////// - -template > -class [[deprecated("Use identityFlow() instead")]] Identity - : public FlowFunction { -public: - using typename FlowFunction::FlowFunctionType; - using typename FlowFunction::FlowFunctionPtrType; - - using typename FlowFunction::container_type; - - ~Identity() override = default; - Identity(const Identity &I) = delete; - Identity &operator=(const Identity &I) = delete; - // simply return what the user provides - container_type computeTargets(D Source) override { return {Source}; } - static std::shared_ptr getInstance() { - static std::shared_ptr Instance = - std::shared_ptr(new Identity); - return Instance; - } - -private: - Identity() = default; -}; - -template > -class [[deprecated("Use lambdaFlow() instead")]] LambdaFlow - : public FlowFunction { -public: - using typename FlowFunction::container_type; - - LambdaFlow(Fn && F) : Flow(std::move(F)) {} - LambdaFlow(const Fn &F) : Flow(F) {} - ~LambdaFlow() override = default; - container_type computeTargets(D Source) override { return Flow(Source); } - -private: - // std::function flow; - Fn Flow; -}; - -template > -typename FlowFunction::FlowFunctionPtrType makeLambdaFlow(Fn &&F) { - return std::make_shared, Container>>( - std::forward(F)); -} - -template > -class [[deprecated]] Compose : public FlowFunction { -public: - using typename FlowFunction::FlowFunctionType; - using typename FlowFunction::FlowFunctionPtrType; - - using typename FlowFunction::container_type; - - Compose(const std::vector &Funcs) : Funcs(Funcs) {} - - ~Compose() override = default; - - container_type computeTargets(D Source) override { - container_type Current{Source}; - for (const FlowFunctionPtrType &Func : Funcs) { - container_type Next; - for (const D &Fact : Current) { - container_type Target = Func->computeTargets(Fact); - Next.insert(Target.begin(), Target.end()); - } - Current = Next; - } - return Current; - } - - static FlowFunctionPtrType - compose(const std::vector &Funcs) { - std::vector Vec; - for (const FlowFunctionPtrType &Func : Funcs) { - if (Func != Identity::getInstance()) { - Vec.push_back(Func); - } - } - if (Vec.size() == 1) { // NOLINT(readability-container-size-empty) - return Vec[0]; - } - if (Vec.empty()) { - return Identity::getInstance(); - } - return std::make_shared(Vec); - } - -protected: - const std::vector Funcs; -}; - -//===----------------------------------------------------------------------===// -// Gen flow functions - -template > -class [[deprecated("Use generateFlow() instead")]] Gen - : public FlowFunction { - using typename FlowFunction::container_type; - -protected: - D GenValue; - D ZeroValue; - -public: - Gen(D GenValue, D ZeroValue) : GenValue(GenValue), ZeroValue(ZeroValue) {} - ~Gen() override = default; - - container_type computeTargets(D Source) override { - if (Source == ZeroValue) { - return {Source, GenValue}; - } - return {Source}; - } -}; - -/** - * @brief Generates the given value if the given predicate evaluates to true. - * @tparam D The type of data-flow facts to be generated. - */ -template > -class [[deprecated("Use generateFlowIf() instead")]] GenIf - : public FlowFunction { -public: - using typename FlowFunction::container_type; - - GenIf(D GenValue, std::function Predicate) - : GenValues({GenValue}), Predicate(std::move(Predicate)) {} - - GenIf(container_type GenValues, std::function Predicate) - : GenValues(std::move(GenValues)), Predicate(std::move(Predicate)) {} - - ~GenIf() override = default; - - container_type computeTargets(D Source) override { - if (Predicate(Source)) { - container_type ToGenerate; - ToGenerate.insert(Source); - ToGenerate.insert(GenValues.begin(), GenValues.end()); - return ToGenerate; - } - return {Source}; - } - -protected: - container_type GenValues; - std::function Predicate; -}; - -template > -class [[deprecated("Use generateManyFlows() instead")]] GenAll - : public FlowFunction { -public: - using typename FlowFunction::container_type; - - GenAll(container_type GenValues, D ZeroValue) - : GenValues(std::move(GenValues)), ZeroValue(ZeroValue) {} - ~GenAll() override = default; - container_type computeTargets(D Source) override { - if (Source == ZeroValue) { - GenValues.insert(Source); - return GenValues; - } - return {Source}; - } - -protected: - container_type GenValues; - D ZeroValue; -}; - -//===----------------------------------------------------------------------===// -// Kill flow functions - -template > -class [[deprecated("Use killFlow() instead")]] Kill - : public FlowFunction { -public: - using typename FlowFunction::container_type; - - Kill(D KillValue) : KillValue(KillValue) {} - ~Kill() override = default; - container_type computeTargets(D Source) override { - if (Source == KillValue) { - return {}; - } - return {Source}; - } - -protected: - D KillValue; -}; - -/// \brief Kills all facts for which the given predicate evaluates to true. -/// \tparam D The type of data-flow facts to be killed. -template > -class [[deprecated("Use killFlowIf instead")]] KillIf - : public FlowFunction { -public: - using typename FlowFunction::container_type; - - KillIf(std::function Predicate) : Predicate(std::move(Predicate)) {} - ~KillIf() override = default; - container_type computeTargets(D Source) override { - if (Predicate(Source)) { - return {}; - } - return {Source}; - } - -protected: - std::function Predicate; -}; - -template > -class [[deprecated("Use killManyFlows() instead")]] KillMultiple - : public FlowFunction { -public: - using typename FlowFunction::container_type; - - KillMultiple(std::set KillValues) : KillValues(std::move(KillValues)) {} - ~KillMultiple() override = default; - container_type computeTargets(D Source) override { - if (KillValues.find(Source) != KillValues.end()) { - return {}; - } - return {Source}; - } - -protected: - container_type KillValues; -}; - -template > -class [[deprecated("Use killAllFlows() instead")]] KillAll - : public FlowFunction { -public: - using typename FlowFunction::container_type; - - ~KillAll() override = default; - KillAll(const KillAll &K) = delete; - KillAll &operator=(const KillAll &K) = delete; - container_type computeTargets(D /*Source*/) override { - return container_type(); - } - - static std::shared_ptr> getInstance() { - static std::shared_ptr Instance = - std::shared_ptr(new KillAll); - return Instance; - } - -private: - KillAll() = default; -}; - -//===----------------------------------------------------------------------===// -// Gen-and-kill flow functions -template > -class [[deprecated( - "Use generateFlowAndKillAllOthers() instead")]] GenAndKillAllOthers - : public FlowFunction { -public: - using typename FlowFunction::container_type; - - GenAndKillAllOthers(D GenValue, D ZeroValue) - : GenValue(GenValue), ZeroValue(ZeroValue) {} - ~GenAndKillAllOthers() override = default; - container_type computeTargets(D Source) override { - if (Source == ZeroValue) { - return {ZeroValue, GenValue}; - } - return {}; - } - -private: - D GenValue; - D ZeroValue; -}; - -template > -class [[deprecated( - "Use generateManyFlowsAndKillAllOthers() instead")]] GenAllAndKillAllOthers - : public FlowFunction { -public: - using typename FlowFunction::container_type; - - GenAllAndKillAllOthers(const container_type &GenValues, D ZeroValue) - : GenValues(GenValues), ZeroValue(ZeroValue) {} - ~GenAllAndKillAllOthers() override = default; - container_type computeTargets(D Source) override { - if (Source == ZeroValue) { - GenValues.insert(Source); - return GenValues; - } - return {}; - } - -protected: - container_type GenValues; - D ZeroValue; -}; - -//===----------------------------------------------------------------------===// -// Miscellaneous flow functions - -template > -class [[deprecated("Use transferFlow() instead")]] Transfer - : public FlowFunction { -public: - using typename FlowFunction::container_type; - - Transfer(D ToValue, D FromValue) : ToValue(ToValue), FromValue(FromValue) {} - ~Transfer() override = default; - container_type computeTargets(D Source) override { - if (Source == FromValue) { - return {Source, ToValue}; - } - if (Source == ToValue) { - return {}; - } - return {Source}; - } - -protected: - D ToValue; - D FromValue; -}; - -template > -class [[deprecated("Use unionFlows() instead")]] Union - : public FlowFunction { -public: - using typename FlowFunction::container_type; - using typename FlowFunction::FlowFunctionType; - using typename FlowFunction::FlowFunctionPtrType; - - Union(const std::vector &FlowFuncs) - : FlowFuncs([&FlowFuncs]() { - if (FlowFuncs.empty()) { - return std::vector( - {Identity::getInstance()}); - } - return FlowFuncs; - }()) {} - - ~Union() override = default; - container_type computeTargets(D Source) override { - container_type Result; - for (const auto &FlowFunc : FlowFuncs) { - container_type Target = FlowFunc->computeTargets(Source); - Result.insert(Target.begin(), Target.end()); - } - return Result; - } - -protected: - const std::vector FlowFuncs; -}; - } // namespace psr #endif diff --git a/include/phasar/DataFlow/IfdsIde/SpecialSummaries.h b/include/phasar/DataFlow/IfdsIde/SpecialSummaries.h index 3154c52b33..41cb4d58e1 100644 --- a/include/phasar/DataFlow/IfdsIde/SpecialSummaries.h +++ b/include/phasar/DataFlow/IfdsIde/SpecialSummaries.h @@ -34,7 +34,9 @@ namespace psr { -template class SpecialSummaries { +template +class [[deprecated("This ancient API is not maintained and should not be used " + "anymore")]] SpecialSummaries { using FlowFunctionType = FlowFunction; using FlowFunctionPtrType = std::shared_ptr>; @@ -50,8 +52,8 @@ template class SpecialSummaries { // insert default flow and edge functions for (const auto &FunctionName : PhasarConfig::getPhasarConfig().specialFunctionNames()) { - SpecialFlowFunctions.insert( - std::make_pair(FunctionName, Identity::getInstance())); + // SpecialFlowFunctions.insert( + // std::make_pair(FunctionName, Identity::getInstance())); SpecialEdgeFunctions.insert( std::make_pair(FunctionName, EdgeIdentity{})); } @@ -95,8 +97,8 @@ template class SpecialSummaries { return SpecialFlowFunctions.count(Name); } - FlowFunctionPtrType - getSpecialFlowFunctionSummary(const llvm::Function *Func) { + FlowFunctionPtrType getSpecialFlowFunctionSummary( + const llvm::Function *Func) { return getSpecialFlowFunctionSummary(Func->getName()); } @@ -104,18 +106,18 @@ template class SpecialSummaries { return SpecialFlowFunctions[Name]; } - std::shared_ptr> - getSpecialEdgeFunctionSummary(const llvm::Function *Func) { + std::shared_ptr> getSpecialEdgeFunctionSummary( + const llvm::Function *Func) { return getSpecialEdgeFunctionSummary(Func->getName()); } - std::shared_ptr> - getSpecialEdgeFunctionSummary(const std::string &Name) { + std::shared_ptr> getSpecialEdgeFunctionSummary( + const std::string &Name) { return SpecialEdgeFunctions[Name]; } - friend llvm::raw_ostream & - operator<<(llvm::raw_ostream &OS, const SpecialSummaries &SpecialSumms) { + friend llvm::raw_ostream &operator<<( + llvm::raw_ostream &OS, const SpecialSummaries &SpecialSumms) { OS << "SpecialSummaries:\n"; for (auto &Entry : SpecialSumms.SpecialFunctionNames) { OS << Entry.first << " "; diff --git a/include/phasar/PhasarLLVM/ControlFlow/LLVMBasedBackwardICFG.h b/include/phasar/PhasarLLVM/ControlFlow/LLVMBasedBackwardICFG.h index c3ac4191b6..d9bbb1786a 100644 --- a/include/phasar/PhasarLLVM/ControlFlow/LLVMBasedBackwardICFG.h +++ b/include/phasar/PhasarLLVM/ControlFlow/LLVMBasedBackwardICFG.h @@ -46,9 +46,6 @@ class LLVMBasedBackwardICFG : public LLVMBasedBackwardCFG, using ICFGBase::printAsJson; - using CFGBase::getAsJson; - using ICFGBase::getAsJson; - public: LLVMBasedBackwardICFG(LLVMBasedICFG *ForwardICFG); @@ -67,7 +64,6 @@ class LLVMBasedBackwardICFG : public LLVMBasedBackwardCFG, getReturnSitesOfCallAtImpl(n_t Inst) const; void printImpl(llvm::raw_ostream &OS) const; void printAsJsonImpl(llvm::raw_ostream &OS) const; - [[nodiscard, deprecated]] nlohmann::json getAsJsonImpl() const; [[nodiscard]] const CallGraph &getCallGraphImpl() const noexcept; [[nodiscard]] size_t getNumCallSitesImpl() const noexcept; diff --git a/include/phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h b/include/phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h index 4b9e35dd9e..9ed1799e0b 100644 --- a/include/phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h +++ b/include/phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h @@ -135,9 +135,6 @@ class LLVMBasedICFG : public LLVMBasedCFG, public ICFGBase { using ICFGBase::printAsJson; - using CFGBase::getAsJson; - using ICFGBase::getAsJson; - private: [[nodiscard]] FunctionRange getAllFunctionsImpl() const; [[nodiscard]] f_t getFunctionImpl(llvm::StringRef Fun) const; @@ -150,7 +147,6 @@ class LLVMBasedICFG : public LLVMBasedCFG, public ICFGBase { getReturnSitesOfCallAtImpl(n_t Inst) const; void printImpl(llvm::raw_ostream &OS) const; void printAsJsonImpl(llvm::raw_ostream &OS) const; - [[nodiscard, deprecated]] nlohmann::json getAsJsonImpl() const; [[nodiscard]] const LLVMBasedCallGraph &getCallGraphImpl() const noexcept { return CG; } diff --git a/include/phasar/PhasarLLVM/ControlFlow/Resolver/DTAResolver.h b/include/phasar/PhasarLLVM/ControlFlow/Resolver/DTAResolver.h deleted file mode 100644 index 3a34ea4f24..0000000000 --- a/include/phasar/PhasarLLVM/ControlFlow/Resolver/DTAResolver.h +++ /dev/null @@ -1,78 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2017 Philipp Schubert. - * All rights reserved. This program and the accompanying materials are made - * available under the terms of LICENSE.txt. - * - * Contributors: - * Philipp Schubert and others - *****************************************************************************/ - -/* - * DTAResolver.h - * - * Created on: 20.07.2018 - * Author: nicolas bellec - */ - -#ifndef PHASAR_PHASARLLVM_CONTROLFLOW_RESOLVER_DTARESOLVER_H_ -#define PHASAR_PHASARLLVM_CONTROLFLOW_RESOLVER_DTARESOLVER_H_ - -#include "phasar/PhasarLLVM/ControlFlow/Resolver/CHAResolver.h" -#include "phasar/PhasarLLVM/Pointer/TypeGraphs/CachedTypeGraph.h" -#include "phasar/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.h" -// To switch the TypeGraph -// #include "phasar/PhasarLLVM/Pointer/TypeGraphs/LazyTypeGraph.h" - -#include - -namespace llvm { -class Instruction; -class CallBase; -class Function; -class BitCastInst; -} // namespace llvm - -namespace psr { - -class [[deprecated("Does not work with opaque pointers anymore")]] DTAResolver - : public CHAResolver { -public: - using TypeGraph_t = CachedTypeGraph; - - DTAResolver(const LLVMProjectIRDB *IRDB, const LLVMVFTableProvider *VTP, - const DIBasedTypeHierarchy *TH); - - ~DTAResolver() override = default; - - FunctionSetTy resolveVirtualCall(const llvm::CallBase *CallSite) override; - - void otherInst(const llvm::Instruction *Inst) override; - - [[nodiscard]] std::string str() const override; - - [[nodiscard]] bool mutatesHelperAnalysisInformation() - const noexcept override { - return false; - } - -protected: - TypeGraph_t TypeGraph; - - /** - * An heuristic that return true if the bitcast instruction is interesting to - * take into the DTA relational graph - */ - static bool heuristicAntiConstructorThisType( - const llvm::BitCastInst *BitCast); - - /** - * Another heuristic that return true if the bitcast instruction is - * interesting to take into the DTA relational graph (use the presence or not - * of vtable) - - */ - bool heuristicAntiConstructorVtablePos(const llvm::BitCastInst *BitCast); -}; -} // namespace psr - -#endif diff --git a/include/phasar/PhasarLLVM/ControlFlow/SparseLLVMBasedICFGView.h b/include/phasar/PhasarLLVM/ControlFlow/SparseLLVMBasedICFGView.h index 927840d252..8c0aaa9dac 100644 --- a/include/phasar/PhasarLLVM/ControlFlow/SparseLLVMBasedICFGView.h +++ b/include/phasar/PhasarLLVM/ControlFlow/SparseLLVMBasedICFGView.h @@ -59,7 +59,6 @@ class SparseLLVMBasedICFGView [[nodiscard]] llvm::SmallVector getReturnSitesOfCallAtImpl(n_t Inst) const; void printImpl(llvm::raw_ostream &OS) const; - [[nodiscard, deprecated]] nlohmann::json getAsJsonImpl() const; [[nodiscard]] const CallGraph &getCallGraphImpl() const noexcept; [[nodiscard]] const SparseLLVMBasedCFG & diff --git a/include/phasar/PhasarLLVM/DataFlow/IfdsIde/Problems/TypeStateDescriptions/TypeStateDescription.h b/include/phasar/PhasarLLVM/DataFlow/IfdsIde/Problems/TypeStateDescriptions/TypeStateDescription.h index a7e14e8fc0..0e6865686b 100644 --- a/include/phasar/PhasarLLVM/DataFlow/IfdsIde/Problems/TypeStateDescriptions/TypeStateDescription.h +++ b/include/phasar/PhasarLLVM/DataFlow/IfdsIde/Problems/TypeStateDescriptions/TypeStateDescription.h @@ -78,7 +78,7 @@ struct TypeStateDescription : public TypeStateDescriptionBase { * Represents the start/initial state of an object after creation, e.g. state * of a file handle after fopen() */ - [[nodiscard]] virtual State start() const = 0; + [[nodiscard, deprecated]] virtual State start() const = 0; /** * Represents the error state of an object diff --git a/include/phasar/PhasarLLVM/Passes/GeneralStatisticsAnalysis.h b/include/phasar/PhasarLLVM/Passes/GeneralStatisticsAnalysis.h index 4f0e943b78..fddf1e98d5 100644 --- a/include/phasar/PhasarLLVM/Passes/GeneralStatisticsAnalysis.h +++ b/include/phasar/PhasarLLVM/Passes/GeneralStatisticsAnalysis.h @@ -19,8 +19,6 @@ #include "llvm/IR/PassManager.h" -#include "nlohmann/json.hpp" - #include namespace llvm { @@ -74,111 +72,6 @@ struct GeneralStatistics { std::set RetResInstructions; std::string ModuleName{}; - /** - * @brief Returns the number of Allocation sites. - */ - [[nodiscard]] [[deprecated( - "Getters are no longer needed. Use AllocationSites instead")]] size_t - getAllocationsites() const; - - /** - * @brief Returns the number of Function calls. - */ - [[nodiscard]] [[deprecated( - "Getters are no longer needed. Use CallSites instead")]] size_t - getFunctioncalls() const; - - /** - * @brief Returns the number of Instructions. - */ - [[nodiscard]] [[deprecated( - "Getters are no longer needed. Use Instructions instead")]] size_t - getInstructions() const; - - /** - * @brief Returns the number of global pointers. - */ - [[nodiscard]] [[deprecated( - "All globals are pointers. Use Globals instead")]] size_t - getGlobalPointers() const; - - /** - * @brief Returns the number of basic blocks. - */ - [[nodiscard]] [[deprecated( - "Getters are no longer needed. Use BasicBlocks instead")]] size_t - getBasicBlocks() const; - - /** - * @brief Returns the number of functions. - */ - [[nodiscard]] [[deprecated( - "Getters are no longer needed. Use Functions instead")]] size_t - getFunctions() const; - - /** - * @brief Returns the number of globals. - */ - [[nodiscard]] [[deprecated( - "Getters are no longer needed. Use Globals instead")]] size_t - getGlobals() const; - - /** - * @brief Returns the number of constant globals. - */ - [[nodiscard]] [[deprecated( - "Getters are no longer needed. Use GlobalConsts instead")]] size_t - getGlobalConsts() const; - - /** - * @brief Returns the number of memory intrinsics. - */ - [[nodiscard]] [[deprecated( - "Getters are no longer needed. Use MemIntrinsics instead")]] size_t - getMemoryIntrinsics() const; - - /** - * @brief Returns the number of store instructions. - */ - [[nodiscard]] [[deprecated( - "Getters are no longer needed. Use StoreInstructions instead")]] size_t - getStoreInstructions() const; - - /** - * @brief Returns the number of load instructions. - */ - [[nodiscard]] [[deprecated( - "Getters are no longer needed. Use LoadInstructions instead; this " - "function seems to be broken anyway")]] size_t - getLoadInstructions(); - - /** - * @brief Returns all possible Types. - */ - [[nodiscard]] [[deprecated( - "Getters are no longer needed. Use AllocatedTypes instead")]] const std:: - set & - getAllocatedTypes() const; - - /** - * @brief Returns all stack and heap allocating instructions. - */ - [[nodiscard]] [[deprecated( - "Getters are no longer needed. Use AllocaInstructions " - "instead")]] const std::set & - getAllocaInstructions() const; - - /** - * @brief Returns all Return and Resume Instructions. - */ - [[nodiscard]] [[deprecated( - "Getters are no longer needed. Use RetResInstructions " - "instead")]] const std::set & - getRetResInstructions() const; - - [[nodiscard]] [[deprecated( - "Please use printAsJson() instead")]] nlohmann::json - getAsJson() const; void printAsJson(llvm::raw_ostream &OS = llvm::outs()) const; }; diff --git a/include/phasar/PhasarLLVM/Pointer.h b/include/phasar/PhasarLLVM/Pointer.h index 220567251a..a2a67fd202 100644 --- a/include/phasar/PhasarLLVM/Pointer.h +++ b/include/phasar/PhasarLLVM/Pointer.h @@ -10,13 +10,10 @@ #ifndef PHASAR_PHASARLLVM_POINTER_H #define PHASAR_PHASARLLVM_POINTER_H -#include "phasar/PhasarLLVM/Pointer/LLVMAliasGraph.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" -#include "phasar/PhasarLLVM/Pointer/TypeGraphs/CachedTypeGraph.h" -#include "phasar/PhasarLLVM/Pointer/TypeGraphs/LazyTypeGraph.h" -#include "phasar/PhasarLLVM/Pointer/TypeGraphs/TypeGraph.h" #endif // PHASAR_PHASARLLVM_POINTER_H diff --git a/include/phasar/PhasarLLVM/Pointer/LLVMAliasGraph.h b/include/phasar/PhasarLLVM/Pointer/LLVMAliasGraph.h deleted file mode 100644 index 83c22dbef4..0000000000 --- a/include/phasar/PhasarLLVM/Pointer/LLVMAliasGraph.h +++ /dev/null @@ -1,275 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2017 Philipp Schubert. - * All rights reserved. This program and the accompanying materials are made - * available under the terms of LICENSE.txt. - * - * Contributors: - * Philipp Schubert and others - *****************************************************************************/ - -#ifndef PHASAR_PHASARLLVM_POINTER_LLVMALIASGRAPH_H_ -#define PHASAR_PHASARLLVM_POINTER_LLVMALIASGRAPH_H_ - -#include "phasar/Config/Configuration.h" -#include "phasar/PhasarLLVM/Pointer/LLVMAliasInfo.h" -#include "phasar/PhasarLLVM/Pointer/LLVMBasedAliasAnalysis.h" -#include "phasar/Pointer/AliasInfoBase.h" -#include "phasar/Pointer/AliasInfoTraits.h" -#include "phasar/Pointer/AliasSetOwner.h" -#include "phasar/Utils/AnalysisProperties.h" - -#include "llvm/IR/AbstractCallSite.h" - -#include "boost/graph/adjacency_list.hpp" -#include "nlohmann/json.hpp" - -#include -#include -#include - -namespace llvm { -class Value; -class Module; -class Instruction; -class AAResults; -class Function; -class Type; -} // namespace llvm - -namespace psr { -extern template class BoxedPtr; -extern template class BoxedConstPtr; -extern template class AliasSetOwner; - -class LLVMAliasGraph; -template <> -struct AliasInfoTraits - : DefaultAATraits {}; - -/** - * TODO: Is this impl legacy code? Can it be removed? - * - * This class is a representation of a points-to graph. It is possible to - * construct a points-to graph for a single function using the results of - * the llvm alias analysis or merge several points-to graphs into a single - * points-to graph, e.g. to construct a whole program points-to graph. - * - * The graph itself is undirectional and can have labeled edges. - * - * @brief Represents the points-to graph of a function. - */ -class [[deprecated("Use LLVMAliasSet Instead")]] LLVMAliasGraph - : public AnalysisPropertiesMixin, - AliasInfoBaseUtils { - using traits_t = AliasInfoTraits; - -public: - using n_t = traits_t::n_t; - using v_t = traits_t::v_t; - using AliasSetTy = traits_t::AliasSetTy; - using AliasSetPtrTy = traits_t::AliasSetPtrTy; - using AllocationSiteSetPtrTy = traits_t::AllocationSiteSetPtrTy; - - // Call-graph friends - friend class LLVMBasedICFG; - /** - * @brief Holds the information of a vertex in the points-to graph. - */ - struct VertexProperties { - /** - * This might be an Instruction, an Operand of an Instruction, Global - * Variable or a formal Argument. - */ - const llvm::Value *V = nullptr; - VertexProperties() = default; - VertexProperties(const llvm::Value *V); - std::string getValueAsString() const; - - // Fetching the users for V is expensive, so we cache the result. - mutable std::vector Users; - std::vector getUsers() const; - }; - - /** - * @brief Holds the information of an edge in the points-to graph. - */ - struct EdgeProperties { - /// This may contain a call or invoke instruction. - const llvm::Value *V = nullptr; - EdgeProperties() = default; - EdgeProperties(const llvm::Value *V); - [[nodiscard]] std::string getValueAsString() const; - }; - - /// Data structure for holding the points-to graph. - using graph_t = - boost::adjacency_list; - - /// The type for vertex representative objects. - using vertex_t = boost::graph_traits::vertex_descriptor; - - /// The type for edge representative objects. - using edge_t = boost::graph_traits::edge_descriptor; - - /// The type for a vertex iterator. - using vertex_iterator = boost::graph_traits::vertex_iterator; - using out_edge_iterator = boost::graph_traits::out_edge_iterator; - using in_edge_iterator = boost::graph_traits::in_edge_iterator; - - /** - * Creates a points-to graph based on the computed Alias results. - * - * @brief Creates a points-to graph for a given function. - * @param AA Contains the computed Alias Results. - * @param F Points-to graph is created for this particular function. - * @param onlyConsiderMustAlias True, if only Must Aliases should be - * considered. False, if May and Must Aliases should be - * considered. - */ - explicit LLVMAliasGraph(LLVMProjectIRDB & IRDB, bool UseLazyEvaluation = true, - AliasAnalysisType PATy = - AliasAnalysisType::CFLAnders); - - /** - * @brief Returns true if graph contains 0 nodes. - */ - bool empty() const; - - /** - * @brief Returns the number of graph nodes. - */ - size_t size() const; - - /** - * @brief Returns a std::vector containing pointers which are escaping through - * function parameters. - * @return Vector holding function argument pointers and the function argument - * number. - */ - std::vector> - getPointersEscapingThroughParams(); - - /** - * @brief Returns a std::vector containing pointers which are escaping through - * function return statements. - * @return Vector with pointers. - */ - std::vector getPointersEscapingThroughReturns() const; - - /** - * @brief Returns a std::vector containing pointers which are escaping through - * function return statements for a specific function. - * @param F Function pointer - * @return Vector with pointers. - */ - std::vector getPointersEscapingThroughReturnsForFunction( - const llvm::Function *Fd) const; - - /** - * @brief Checks if a given value is represented by a vertex in the points-to - * graph. - * @return True, the points-to graph contains the given value. - */ - bool containsValue(llvm::Value * V); - - /** - * The value-vertex-map maps each Value of the points-to graph to - * its corresponding Vertex in the points-to graph. - * - * @brief Prints the value-vertex-map to the command-line. - */ - void printValueVertexMap(); - - class PointerVertexOrEdgePrinter { - public: - PointerVertexOrEdgePrinter(const graph_t &PAG) : PAG(PAG) {} - template - void operator()(std::ostream &Out, const VertexOrEdge &V) const { - Out << "[label=\"" << PAG[V].getValueAsString() << "\"]"; - } - - private: - const graph_t &PAG; - }; - - static inline PointerVertexOrEdgePrinter makePointerVertexOrEdgePrinter( - const graph_t &PAG) { - return {PAG}; - } - - /** - * @brief Prints the points-to graph in .dot format to the given output - * stream. - * @param outputstream. - */ - void printAsDot(llvm::raw_ostream &OS = llvm::outs()) const; - - size_t getNumVertices() const; - - size_t getNumEdges() const; - - // --- IsAliasInfo impl - - [[nodiscard]] bool isInterProcedural() const noexcept; - - [[nodiscard]] AliasAnalysisType getAliasAnalysisType() const noexcept; - - AliasResult alias(const llvm::Value *V1, const llvm::Value *V2, - const llvm::Instruction *I = nullptr); - - AliasSetPtrTy getAliasSet(const llvm::Value *V, - const llvm::Instruction *I = nullptr); - - AllocationSiteSetPtrTy getReachableAllocationSites( - const llvm::Value *V, bool IntraProcOnly = false, - const llvm::Instruction *I = nullptr); - - [[nodiscard]] bool isInReachableAllocationSites( - const llvm::Value *V, const llvm::Value *PotentialValue, - bool IntraProcOnly = false, const llvm::Instruction *I = nullptr); - - void mergeWith(const LLVMAliasGraph &OtherPTI); - - void introduceAlias(const llvm::Value *V1, const llvm::Value *V2, - const llvm::Instruction *I = nullptr, - AliasResult Kind = AliasResult::MustAlias); - - 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; - } - -private: - // --- - - // void mergeGraph(const LLVMAliasGraph &Other); - - void computeAliasGraph(const llvm::Value *V); - - void computeAliasGraph(llvm::Function * F); - - struct AllocationSiteDFSVisitor; - struct ReachabilityDFSVisitor; - - /// The points to graph. - graph_t PAG; - using ValueVertexMapT = std::unordered_map; - ValueVertexMapT ValueVertexMap; - /// Keep track of what has already been merged into this points-to graph. - std::unordered_set AnalyzedFunctions; - LLVMBasedAliasAnalysis PTA; - - AliasSetOwner::memory_resource_type MRes; - AliasSetOwner Owner{&MRes}; - std::unordered_map> Cache; -}; - -} // namespace psr - -#endif diff --git a/include/phasar/PhasarLLVM/Pointer/LLVMAliasSet.h b/include/phasar/PhasarLLVM/Pointer/LLVMAliasSet.h index 7a9c2dbd71..ff4ccbe5dc 100644 --- a/include/phasar/PhasarLLVM/Pointer/LLVMAliasSet.h +++ b/include/phasar/PhasarLLVM/Pointer/LLVMAliasSet.h @@ -17,15 +17,10 @@ #include "phasar/Pointer/AliasResult.h" #include "phasar/Pointer/AliasSetOwner.h" #include "phasar/Utils/AnalysisProperties.h" -#include "phasar/Utils/StableVector.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseSet.h" -#include "nlohmann/json.hpp" - -#include - namespace llvm { class Value; class Instruction; @@ -100,10 +95,6 @@ class LLVMAliasSet : public AnalysisPropertiesMixin, void print(llvm::raw_ostream &OS = llvm::outs()) const; - [[nodiscard]] [[deprecated( - "Please use printAsJson() instead")]] nlohmann::json - getAsJson() const; - [[nodiscard]] LLVMAliasSetData getLLVMAliasSetData() const; void printAsJson(llvm::raw_ostream &OS = llvm::outs()) const; diff --git a/include/phasar/PhasarLLVM/Pointer/TypeGraphs/CachedTypeGraph.h b/include/phasar/PhasarLLVM/Pointer/TypeGraphs/CachedTypeGraph.h deleted file mode 100644 index 17efc1abbf..0000000000 --- a/include/phasar/PhasarLLVM/Pointer/TypeGraphs/CachedTypeGraph.h +++ /dev/null @@ -1,109 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2017 Philipp Schubert. - * All rights reserved. This program and the accompanying materials are made - * available under the terms of LICENSE.txt. - * - * Contributors: - * Philipp Schubert and others - *****************************************************************************/ - -/* - * CachedTypeGraph.h - * - * Created on: 28.06.2018 - * Author: nicolas bellec - */ - -#ifndef PHASAR_PHASARLLVM_POINTER_TYPEGRAPHS_CACHEDTYPEGRAPH_H_ -#define PHASAR_PHASARLLVM_POINTER_TYPEGRAPHS_CACHEDTYPEGRAPH_H_ - -#include "phasar/PhasarLLVM/Pointer/TypeGraphs/TypeGraph.h" - -#include "boost/graph/adjacency_list.hpp" -#include "boost/graph/graph_traits.hpp" -#include "boost/graph/reverse_graph.hpp" - -#include -#include -#include - -#ifndef PSR_FRIEND_TEST -#define PSR_FRIEND_TEST(TEST, CLASS) -#endif - -namespace llvm { -class StructType; -} // namespace llvm - -namespace psr { -class CachedTypeGraph : public TypeGraph { -protected: - struct VertexProperties { - std::string Name; - std::set Types; - const llvm::StructType *BaseType = nullptr; - }; - - struct EdgeProperties { - EdgeProperties() = default; - }; - - using graph_t = - boost::adjacency_list; - - using vertex_t = boost::graph_traits::vertex_descriptor; - using vertex_iterator = boost::graph_traits::vertex_iterator; - using edge_t = boost::graph_traits::edge_descriptor; - using out_edge_iterator = boost::graph_traits::out_edge_iterator; - using in_edge_iterator = boost::graph_traits::in_edge_iterator; - - using rev_graph_t = boost::reverse_graph; - - using rev_vertex_t = boost::graph_traits::vertex_descriptor; - using rev_vertex_iterator = boost::graph_traits::vertex_iterator; - using rev_edge_t = boost::graph_traits::edge_descriptor; - using rev_out_edge_iterator = - boost::graph_traits::out_edge_iterator; - using rev_in_edge_iterator = - boost::graph_traits::in_edge_iterator; - - struct dfs_visitor; - struct reverse_type_propagation_dfs_visitor; - - std::unordered_map TypeVertexMap; - graph_t G; - bool AlreadyVisited = false; - - PSR_FRIEND_TEST(TypeGraphTest, AddType) - PSR_FRIEND_TEST(TypeGraphTest, AddLinkSimple) - PSR_FRIEND_TEST(TypeGraphTest, AddLinkWithSubs) - PSR_FRIEND_TEST(TypeGraphTest, AddLinkWithRecursion) - PSR_FRIEND_TEST(TypeGraphTest, ReverseTypePropagation) - PSR_FRIEND_TEST(TypeGraphTest, TypeAggregation) - PSR_FRIEND_TEST(TypeGraphTest, Merging) - - vertex_t addType(const llvm::StructType *NewType); - void reverseTypePropagation(const llvm::StructType *BaseStruct); - void aggregateTypes(); - bool addLinkWithoutReversePropagation(const llvm::StructType *From, - const llvm::StructType *To); - -public: - CachedTypeGraph() = default; - - ~CachedTypeGraph() override = default; - // CachedTypeGraph(const CachedTypeGraph ©) = delete; - // CachedTypeGraph& operator=(const CachedTypeGraph ©) = delete; - // CachedTypeGraph(CachedTypeGraph &&move) = delete; - // CachedTypeGraph& operator=(CachedTypeGraph &&move) = delete; - - bool addLink(const llvm::StructType *From, - const llvm::StructType *To) override; - void printAsDot(const std::string &Path = "typegraph.dot") const override; - std::set - getTypes(const llvm::StructType *StructType) override; -}; -} // namespace psr - -#endif diff --git a/include/phasar/PhasarLLVM/Pointer/TypeGraphs/LazyTypeGraph.h b/include/phasar/PhasarLLVM/Pointer/TypeGraphs/LazyTypeGraph.h deleted file mode 100644 index a29e6a45ea..0000000000 --- a/include/phasar/PhasarLLVM/Pointer/TypeGraphs/LazyTypeGraph.h +++ /dev/null @@ -1,92 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2017 Philipp Schubert. - * All rights reserved. This program and the accompanying materials are made - * available under the terms of LICENSE.txt. - * - * Contributors: - * Philipp Schubert and others - *****************************************************************************/ - -/* - * LazyTypeGraph.h - * - * Created on: 28.06.2018 - * Author: nicolas bellec - */ - -#ifndef PHASAR_PHASARLLVM_POINTER_TYPEGRAPHS_LAZYTYPEGRAPH_H -#define PHASAR_PHASARLLVM_POINTER_TYPEGRAPHS_LAZYTYPEGRAPH_H - -#include "phasar/PhasarLLVM/Pointer/TypeGraphs/TypeGraph.h" - -#include "boost/graph/adjacency_list.hpp" -#include "boost/graph/graph_traits.hpp" -#include "boost/graph/reverse_graph.hpp" - -#include -#include -#include - -namespace llvm { -class StructType; -} // namespace llvm - -namespace psr { -class LazyTypeGraph : public TypeGraph { -protected: - struct VertexProperties { - std::string Name; - const llvm::StructType *SType = nullptr; - }; - - struct EdgeProperties { - EdgeProperties() = default; - }; - - using graph_t = - boost::adjacency_list; - - using vertex_t = boost::graph_traits::vertex_descriptor; - using vertex_iterator = boost::graph_traits::vertex_iterator; - using edge_t = boost::graph_traits::edge_descriptor; - using out_edge_iterator = boost::graph_traits::out_edge_iterator; - using in_edge_iterator = boost::graph_traits::in_edge_iterator; - - using rev_graph_t = boost::reverse_graph; - - using rev_vertex_t = boost::graph_traits::vertex_descriptor; - using rev_vertex_iterator = boost::graph_traits::vertex_iterator; - using rev_edge_t = boost::graph_traits::edge_descriptor; - using rev_out_edge_iterator = - boost::graph_traits::out_edge_iterator; - using rev_in_edge_iterator = - boost::graph_traits::in_edge_iterator; - - struct dfs_visitor; - - std::unordered_map TypeToVertexMap; - graph_t Graph; - bool AlreadyVisited = false; - - vertex_t addType(const llvm::StructType *NewType); - void aggregateTypes(); - -public: - LazyTypeGraph() = default; - - ~LazyTypeGraph() override = default; - // LazyTypeGraph(const LazyTypeGraph ©) = delete; - // LazyTypeGraph& operator=(const LazyTypeGraph ©) = delete; - // LazyTypeGraph(LazyTypeGraph &&move) = delete; - // LazyTypeGraph& operator=(LazyTypeGraph &&move) = delete; - - [[nodiscard]] bool addLink(const llvm::StructType *From, - const llvm::StructType *To) override; - void printAsDot(const std::string &Path = "typegraph.dot") const override; - [[nodiscard]] std::set - getTypes(const llvm::StructType *StructType) override; -}; -} // namespace psr - -#endif diff --git a/include/phasar/PhasarLLVM/Pointer/TypeGraphs/TypeGraph.h b/include/phasar/PhasarLLVM/Pointer/TypeGraphs/TypeGraph.h deleted file mode 100644 index b7a4ac9090..0000000000 --- a/include/phasar/PhasarLLVM/Pointer/TypeGraphs/TypeGraph.h +++ /dev/null @@ -1,50 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2017 Philipp Schubert. - * All rights reserved. This program and the accompanying materials are made - * available under the terms of LICENSE.txt. - * - * Contributors: - * Philipp Schubert and others - *****************************************************************************/ - -/* - * TypeGraph.h - * - * Created on: 28.06.2018 - * Author: nicolas bellec - */ - -#ifndef PHASAR_PHASARLLVM_POINTER_TYPEGRAPHS_TYPEGRAPH_H_ -#define PHASAR_PHASARLLVM_POINTER_TYPEGRAPHS_TYPEGRAPH_H_ - -#include -#include -#include - -namespace llvm { -class StructType; -} // namespace llvm - -namespace psr { -template class TypeGraph { -public: - TypeGraph() = default; - - virtual ~TypeGraph() = default; - // TypeGraph(const TypeGraph ©) = delete; - // TypeGraph& operator=(const TypeGraph ©) = delete; - // TypeGraph(TypeGraph &&move) = delete; - // TypeGraph& operator=(TypeGraph &&move) = delete; - - /* Add a link if not already in the graph - * Return true if the node has been added, false otherwise - */ - virtual bool addLink(const llvm::StructType *From, - const llvm::StructType *To) = 0; - virtual void printAsDot(const std::string &Path = "typegraph.dot") const = 0; - virtual std::set - getTypes(const llvm::StructType *ST) = 0; -}; -} // namespace psr - -#endif diff --git a/include/phasar/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.h b/include/phasar/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.h index 53b93d9f1a..1b5694c6d4 100644 --- a/include/phasar/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.h +++ b/include/phasar/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.h @@ -14,11 +14,9 @@ #include "phasar/PhasarLLVM/TypeHierarchy/LLVMVFTable.h" #include "phasar/TypeHierarchy/TypeHierarchy.h" -#include "llvm/ADT/BitVector.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" -#include "llvm/IR/DebugInfo.h" #include "llvm/IR/DebugInfoMetadata.h" #include "llvm/Support/Casting.h" @@ -101,10 +99,6 @@ class DIBasedTypeHierarchy */ void printAsDot(llvm::raw_ostream &OS = llvm::outs()) const; - [[nodiscard]] [[deprecated( - "Please use printAsJson() instead")]] nlohmann::json - getAsJson() const override; - /** * @brief Prints the class hierarchy to an ostream in json format. * @param an outputstream diff --git a/include/phasar/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.h b/include/phasar/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.h index 3678dfa44c..1e1a79cfe6 100644 --- a/include/phasar/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.h +++ b/include/phasar/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.h @@ -51,7 +51,7 @@ class LLVMProjectIRDB; * hierarchy graph based on the data from the %ProjectIRCompiledDB * and reconstructing the virtual method tables. */ -class LLVMTypeHierarchy +class [[deprecated("Use DIBasedTypeHierarchy instead")]] LLVMTypeHierarchy : public TypeHierarchy { public: struct VertexProperties { @@ -110,11 +110,11 @@ class LLVMTypeHierarchy // map from clearname to vtable variable std::unordered_map ClearNameTVMap; - std::vector - getSubTypes(const llvm::Module &M, const llvm::StructType &Type) const; + std::vector getSubTypes( + const llvm::Module &M, const llvm::StructType &Type) const; - std::vector - getVirtualFunctions(const llvm::Module &M, const llvm::StructType &Type); + std::vector getVirtualFunctions( + const llvm::Module &M, const llvm::StructType &Type); protected: void buildLLVMTypeHierarchy(const llvm::Module &M); @@ -157,29 +157,29 @@ class LLVMTypeHierarchy */ void constructHierarchy(const llvm::Module &M); - [[nodiscard]] inline bool - hasType(const llvm::StructType *Type) const override { + [[nodiscard]] inline bool hasType(const llvm::StructType *Type) + const override { return TypeVertexMap.count(Type); } - [[nodiscard]] inline bool - isSubType(const llvm::StructType *Type, - const llvm::StructType *SubType) const override { + [[nodiscard]] inline bool isSubType(const llvm::StructType *Type, + const llvm::StructType *SubType) + const override { auto ReachableTypes = getSubTypes(Type); return ReachableTypes.count(SubType); } - std::set - getSubTypes(const llvm::StructType *Type) const override; + std::set getSubTypes(const llvm::StructType *Type) + const override; - [[nodiscard]] const llvm::StructType * - getType(llvm::StringRef TypeName) const override; + [[nodiscard]] const llvm::StructType *getType(llvm::StringRef TypeName) + const override; - [[nodiscard]] std::vector - getAllTypes() const override; + [[nodiscard]] std::vector getAllTypes() + const override; - [[nodiscard]] llvm::StringRef - getTypeName(const llvm::StructType *Type) const override; + [[nodiscard]] llvm::StringRef getTypeName(const llvm::StructType *Type) + const override; [[nodiscard]] size_t size() const noexcept override { return boost::num_vertices(TypeGraph); @@ -191,10 +191,6 @@ class LLVMTypeHierarchy void print(llvm::raw_ostream &OS = llvm::outs()) const override; - [[nodiscard]] [[deprecated( - "Please use printAsJson() instead")]] nlohmann::json - getAsJson() const override; - // void mergeWith(LLVMTypeHierarchy &Other); /** diff --git a/include/phasar/PhasarLLVM/TypeHierarchy/LLVMVFTable.h b/include/phasar/PhasarLLVM/TypeHierarchy/LLVMVFTable.h index cd2e226920..a68c1b341a 100644 --- a/include/phasar/PhasarLLVM/TypeHierarchy/LLVMVFTable.h +++ b/include/phasar/PhasarLLVM/TypeHierarchy/LLVMVFTable.h @@ -13,8 +13,6 @@ #include "phasar/PhasarLLVM/TypeHierarchy/LLVMVFTableData.h" #include "phasar/TypeHierarchy/VFTable.h" -#include "nlohmann/json.hpp" - #include namespace llvm { @@ -71,10 +69,6 @@ class LLVMVFTable : public VFTable { void print(llvm::raw_ostream &OS) const override; - [[nodiscard]] [[deprecated( - "Please use printAsJson() instead")]] nlohmann::json - getAsJson() const override; - [[nodiscard]] LLVMVFTableData getVFTableData() const; void printAsJson(llvm::raw_ostream &OS) const override; diff --git a/include/phasar/Pointer/AliasInfo.h b/include/phasar/Pointer/AliasInfo.h index 056969fe5e..db861acdca 100644 --- a/include/phasar/Pointer/AliasInfo.h +++ b/include/phasar/Pointer/AliasInfo.h @@ -139,12 +139,6 @@ class AliasInfoRef : public AnalysisPropertiesMixin> { VT->Print(AA, OS); } - [[nodiscard, deprecated("Use printAsJson() instead")]] nlohmann::json - getAsJson() const { - assert(VT != nullptr); - return VT->GetAsJson(AA); - } - void printAsJson(llvm::raw_ostream &OS) const { assert(VT != nullptr); VT->PrintAsJson(AA, OS); @@ -200,7 +194,6 @@ class AliasInfoRef : public AnalysisPropertiesMixin> { ByConstRef, bool, ByConstRef); void (*Print)(const void *, llvm::raw_ostream &); - nlohmann::json (*GetAsJson)(const void *); void (*PrintAsJson)(const void *, llvm::raw_ostream &); void (*MergeWith)(void *, void *); void (*IntroduceAlias)(void *, ByConstRef, ByConstRef, @@ -240,15 +233,6 @@ class AliasInfoRef : public AnalysisPropertiesMixin> { [](const void *AA, llvm::raw_ostream &OS) { static_cast(AA)->print(OS); }, - [](const void *AA) noexcept { -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated" - if constexpr (has_getAsJson::value) { - return static_cast(AA)->getAsJson(); - } - return nlohmann::json(); -#pragma GCC diagnostic pop - }, [](const void *AA, llvm::raw_ostream &OS) { static_cast(AA)->printAsJson(OS); }, diff --git a/include/phasar/TypeHierarchy/TypeHierarchy.h b/include/phasar/TypeHierarchy/TypeHierarchy.h index d753652cf9..5d06705d1b 100644 --- a/include/phasar/TypeHierarchy/TypeHierarchy.h +++ b/include/phasar/TypeHierarchy/TypeHierarchy.h @@ -14,8 +14,6 @@ #include "llvm/Support/raw_ostream.h" -#include "nlohmann/json_fwd.hpp" - #include namespace psr { @@ -40,10 +38,6 @@ template class TypeHierarchy { virtual void print(llvm::raw_ostream &OS = llvm::outs()) const = 0; - [[nodiscard, - deprecated("Please use printAsJson() instead")]] virtual nlohmann::json - getAsJson() const = 0; - virtual void printAsJson(llvm::raw_ostream &OS) const = 0; }; diff --git a/include/phasar/TypeHierarchy/VFTable.h b/include/phasar/TypeHierarchy/VFTable.h index 83c544dbcd..a236f2e345 100644 --- a/include/phasar/TypeHierarchy/VFTable.h +++ b/include/phasar/TypeHierarchy/VFTable.h @@ -12,8 +12,6 @@ #include "llvm/Support/raw_ostream.h" -#include "nlohmann/json.hpp" - #include namespace llvm { @@ -38,10 +36,6 @@ template class VFTable { virtual void print(llvm::raw_ostream &OS) const = 0; - [[nodiscard, - deprecated("Please use printAsJson() instead")]] virtual nlohmann::json - getAsJson() const = 0; - virtual void printAsJson(llvm::raw_ostream &OS) const = 0; }; diff --git a/include/phasar/Utils/Logger.h b/include/phasar/Utils/Logger.h index 6b3ea5e186..abf1fd65e6 100644 --- a/include/phasar/Utils/Logger.h +++ b/include/phasar/Utils/Logger.h @@ -155,12 +155,6 @@ class Logger final { #define PHASAR_LOG_LEVEL(level, message) (void)0 #endif -/** - * Initializes the logger. - */ -[[deprecated("Please use the new initialize*Logger() family instead")]] void -initializeLogger(bool UseLogger, const std::string &LogFile = ""); - } // namespace psr #endif diff --git a/include/phasar/Utils/Utilities.h b/include/phasar/Utils/Utilities.h index de2698c00e..f2c7504c74 100644 --- a/include/phasar/Utils/Utilities.h +++ b/include/phasar/Utils/Utilities.h @@ -33,16 +33,6 @@ std::string createTimeStamp(); bool isConstructor(llvm::StringRef MangledName); -namespace legacy { -// May need to call this function from a safe environment where we have already -// checked that it does not take any harm. Surround it with the legacy namespace -// as a marker that this function will be removed soon. - -/// [[deprecated("Requires non-opaque pointers, which will no longer be " -/// "supported by LLVM in the next version!")]] -const llvm::Type *stripPointer(const llvm::Type *Pointer); -} // namespace legacy - bool isMangled(llvm::StringRef Name); template diff --git a/lib/Config/Configuration.cpp b/lib/Config/Configuration.cpp index 11a36279e3..8378bacaab 100644 --- a/lib/Config/Configuration.cpp +++ b/lib/Config/Configuration.cpp @@ -55,10 +55,6 @@ llvm::StringRef PhasarConfig::PhasarDirectory() noexcept { return PHASAR_SRC_DIR; } -llvm::StringRef PhasarConfig::DefaultSourceSinkFunctionsPath() noexcept { - return PHASAR_SRC_DIR "/config/phasar-source-sink-function.json"; -} - static bool loadConfigFileInto(PhasarConfig &PC, llvm::StringRef FileName, std::set &Lines) { auto ConfigFile = PC.readConfigFileAsTextOrErr(FileName); diff --git a/lib/PhasarLLVM/ControlFlow/LLVMBasedBackwardICFG.cpp b/lib/PhasarLLVM/ControlFlow/LLVMBasedBackwardICFG.cpp index 53a3a3adb2..1d9e41cf29 100644 --- a/lib/PhasarLLVM/ControlFlow/LLVMBasedBackwardICFG.cpp +++ b/lib/PhasarLLVM/ControlFlow/LLVMBasedBackwardICFG.cpp @@ -68,10 +68,6 @@ void LLVMBasedBackwardICFG::printAsJsonImpl(llvm::raw_ostream &OS) const { ForwardICFG->printAsJson(OS); } -nlohmann::json LLVMBasedBackwardICFG::getAsJsonImpl() const { - return ForwardICFG->getAsJson(); -} - auto LLVMBasedBackwardICFG::getCallGraphImpl() const noexcept -> const CallGraph & { return ForwardICFG->getCallGraph(); diff --git a/lib/PhasarLLVM/ControlFlow/LLVMBasedICFG.cpp b/lib/PhasarLLVM/ControlFlow/LLVMBasedICFG.cpp index ce87316f5d..addd88c957 100644 --- a/lib/PhasarLLVM/ControlFlow/LLVMBasedICFG.cpp +++ b/lib/PhasarLLVM/ControlFlow/LLVMBasedICFG.cpp @@ -158,12 +158,6 @@ void LLVMBasedICFG::printAsJsonImpl(llvm::raw_ostream &OS) const { [this](n_t Inst) { return IRDB->getInstructionId(Inst); }); } -nlohmann::json LLVMBasedICFG::getAsJsonImpl() const { - return CG.getAsJson( - [](f_t F) { return F->getName().str(); }, - [this](n_t Inst) { return IRDB->getInstructionId(Inst); }); -} - template class ICFGBase; } // namespace psr diff --git a/lib/PhasarLLVM/ControlFlow/LLVMVFTableProvider.cpp b/lib/PhasarLLVM/ControlFlow/LLVMVFTableProvider.cpp index 43c6dab56d..45820e2793 100644 --- a/lib/PhasarLLVM/ControlFlow/LLVMVFTableProvider.cpp +++ b/lib/PhasarLLVM/ControlFlow/LLVMVFTableProvider.cpp @@ -10,6 +10,7 @@ #include "llvm/BinaryFormat/Dwarf.h" #include "llvm/Demangle/Demangle.h" #include "llvm/IR/Constants.h" +#include "llvm/IR/DebugInfo.h" #include "llvm/IR/DebugInfoMetadata.h" #include "llvm/IR/Module.h" #include "llvm/Support/Casting.h" diff --git a/lib/PhasarLLVM/ControlFlow/Resolver/DTAResolver.cpp b/lib/PhasarLLVM/ControlFlow/Resolver/DTAResolver.cpp deleted file mode 100644 index 7863c024a4..0000000000 --- a/lib/PhasarLLVM/ControlFlow/Resolver/DTAResolver.cpp +++ /dev/null @@ -1,239 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2017 Philipp Schubert. - * All rights reserved. This program and the accompanying materials are made - * available under the terms of LICENSE.txt. - * - * Contributors: - * Philipp Schubert and others - *****************************************************************************/ - -/* - * DTAResolver.cpp - * - * Created on: 20.07.2018 - * Author: nicolas bellec - */ - -#include "phasar/PhasarLLVM/ControlFlow/Resolver/DTAResolver.h" - -#include "phasar/PhasarLLVM/ControlFlow/LLVMVFTableProvider.h" -#include "phasar/PhasarLLVM/Utils/LLVMIRToSrc.h" -#include "phasar/PhasarLLVM/Utils/LLVMShorthands.h" -#include "phasar/Utils/Logger.h" -#include "phasar/Utils/Utilities.h" - -#include "llvm/IR/Constants.h" -#include "llvm/IR/DebugInfoMetadata.h" -#include "llvm/IR/DerivedTypes.h" -#include "llvm/IR/Function.h" -#include "llvm/IR/InstIterator.h" -#include "llvm/IR/Instruction.h" -#include "llvm/IR/Instructions.h" -#include "llvm/IR/Module.h" -#include "llvm/IR/Operator.h" -#include "llvm/IR/Value.h" -#include "llvm/Support/Casting.h" -#include "llvm/Support/ErrorHandling.h" - -#include - -using namespace psr; - -DTAResolver::DTAResolver(const LLVMProjectIRDB *IRDB, - const LLVMVFTableProvider *VTP, - const DIBasedTypeHierarchy *TH) - : CHAResolver(IRDB, VTP, TH) {} - -bool DTAResolver::heuristicAntiConstructorThisType( - const llvm::BitCastInst *BitCast) { - llvm::report_fatal_error("Does not work with opaque pointers anymore"); -#if 0 - // We check if the caller is a constructor, and if the this argument has the - // same type as the source type of the bitcast. If it is the case, it returns - // false, true otherwise. - - if (const auto *Caller = BitCast->getFunction()) { - if (isConstructor(Caller->getName().str())) { - if (auto *FuncTy = Caller->getFunctionType()) { - if (auto *ThisTy = FuncTy->getParamType(0)) { - if (ThisTy == BitCast->getSrcTy()) { - return false; - } - } - } - } - } - - return true; -#endif -} - -bool DTAResolver::heuristicAntiConstructorVtablePos( - const llvm::BitCastInst *BitCast) { - llvm::report_fatal_error("Does not work with opaque pointers anymore"); -#if 0 - - // Better heuristic than the previous one, can handle the CRTP. Based on the - // previous one. - - - if (heuristicAntiConstructorThisType(BitCast)) { - return true; - } - - // We know that we are in a constructor and the source type of the bitcast is - // the same as the this argument. We then check where the bitcast is against - // the store instruction of the vtable. - if (!BitCast->getSrcTy()->isOpaquePointerTy()) { - const auto *StructTy = psr::legacy::stripPointer(BitCast->getSrcTy()); - if (StructTy == nullptr) { - throw std::runtime_error( - "StructTy == nullptr in the heuristic_anti_contructor"); - } - - // If it doesn't contain vtable, there is no reason to call this class in - // the DTA graph, so no need to add it - if (StructTy->isStructTy()) { - if (VTP->hasVFTable(llvm::dyn_cast(StructTy))) { - return false; - } - } - } - // So there is a vtable, the question is, where is it compared to the bitcast - // instruction Carefull, there can be multiple vtable storage, we want to get - // the last one vtable storage typically are : store i32 (...)** bitcast (i8** - // getelementptr inbounds ({ [3 x i8*], [3 x i8*] }, { [3 x i8*], [3 x i8*] }* - // @_ZTV2AA, i32 0, inrange i32 1, i32 3) to i32 (...)**), i32 (...)*** %17, - // align 8 - // WARNING: May break when changing llvm version or using clang with version - // > 5.0.1 - - const auto *Caller = BitCast->getFunction(); - if (Caller == nullptr) { - throw std::runtime_error( - "A bitcast instruction has no associated function"); - } - - int Idx = 0; - - int VtableNum = 0; - - int BitcastNum = 0; - - for (auto I = llvm::inst_begin(Caller), E = llvm::inst_end(Caller); I != E; - ++I, ++Idx) { - const auto &Inst = *I; - - if (const auto *Store = llvm::dyn_cast(&Inst)) { - // We got a store instruction, now we are checking if it is a vtable - // storage - if (const auto *BitcastExpr = - llvm::dyn_cast(Store->getValueOperand())) { - if (BitcastExpr->isCast()) { - if (auto *ConstGep = llvm::dyn_cast( - BitcastExpr->getOperand(0))) { - if (auto *Gep = llvm::dyn_cast(ConstGep)) { - if (auto *Vtable = llvm::dyn_cast( - Gep->getPointerOperand())) { - // We can here assume that we found a vtable - VtableNum = Idx; - } - } - } - } - } - } - - if (&Inst == BitCast) { - BitcastNum = Idx; - } - } - - return (BitcastNum > VtableNum); -#endif -} - -void DTAResolver::otherInst(const llvm::Instruction *Inst) { - llvm::report_fatal_error("Does not work with opaque pointers anymore"); -#if 0 - if (Inst->getType()->isOpaquePointerTy()) { - /// XXX: We may want to get these information on a different way, e.g. by - /// analyzing the debug info - return; - } - if (const auto *BitCast = llvm::dyn_cast(Inst)) { - // We add the connection between the two types in the DTA graph - auto *Src = BitCast->getSrcTy(); - auto *Dest = BitCast->getDestTy(); - - const auto *SrcStructType = llvm::dyn_cast( - psr::legacy::stripPointer(Src)); // NOLINT - const auto *DestStructType = llvm::dyn_cast( - psr::legacy::stripPointer(Dest)); // NOLINT - - if (SrcStructType && DestStructType && - heuristicAntiConstructorVtablePos(BitCast)) { - TypeGraph.addLink(DestStructType, SrcStructType); - } - } -#endif -} -auto DTAResolver::resolveVirtualCall(const llvm::CallBase *CallSite) - -> FunctionSetTy { - llvm::report_fatal_error("Does not work with opaque pointers anymore"); -#if 0 - FunctionSetTy PossibleCallTargets; - - PHASAR_LOG_LEVEL(DEBUG, - "Call virtual function: " << llvmIRToString(CallSite)); - - auto RetrievedVtableIndex = getVFTIndex(CallSite); - if (!RetrievedVtableIndex.has_value()) { - // An error occured - PHASAR_LOG_LEVEL(DEBUG, - "Error with resolveVirtualCall : impossible to retrieve " - "the vtable index\n" - << llvmIRToString(CallSite) << "\n"); - return {}; - } - - auto VtableIndex = RetrievedVtableIndex.value(); - - PHASAR_LOG_LEVEL(DEBUG, "Virtual function table entry is: " << VtableIndex); - - const auto *ReceiverType = getReceiverStructType(CallSite); - - auto PossibleTypes = TypeGraph.getTypes(ReceiverType); - - // WARNING We deactivated the check on allocated because it is - // unabled to get the types allocated in the used libraries - // auto allocated_types = IRDB.getAllocatedTypes(); - // auto end_it = allocated_types.end(); - for (const auto *PossibleType : PossibleTypes) { - if (const auto *PossibleTypeStruct = - llvm::dyn_cast(PossibleType)) { - // if ( allocated_types.find(possible_type_struct) != end_it ) { - const auto *Target = - getNonPureVirtualVFTEntry(PossibleTypeStruct, VtableIndex, CallSite); - if (Target) { - PossibleCallTargets.insert(Target); - } - } - } - - if (PossibleCallTargets.empty()) { - PossibleCallTargets = CHAResolver::resolveVirtualCall(CallSite); - } - - PHASAR_LOG_LEVEL(DEBUG, "Possible targets are:"); -#ifdef DYNAMIC_LOG - for (const auto *Entry : PossibleCallTargets) { - PHASAR_LOG_LEVEL(DEBUG, Entry); - } -#endif - - return PossibleCallTargets; -#endif -} - -std::string DTAResolver::str() const { return "DTA"; } diff --git a/lib/PhasarLLVM/ControlFlow/Resolver/Resolver.cpp b/lib/PhasarLLVM/ControlFlow/Resolver/Resolver.cpp index 27c91bcd4a..9065a43415 100644 --- a/lib/PhasarLLVM/ControlFlow/Resolver/Resolver.cpp +++ b/lib/PhasarLLVM/ControlFlow/Resolver/Resolver.cpp @@ -19,7 +19,6 @@ #include "phasar/ControlFlow/CallGraphAnalysisType.h" #include "phasar/PhasarLLVM/ControlFlow/LLVMVFTableProvider.h" #include "phasar/PhasarLLVM/ControlFlow/Resolver/CHAResolver.h" -#include "phasar/PhasarLLVM/ControlFlow/Resolver/DTAResolver.h" #include "phasar/PhasarLLVM/ControlFlow/Resolver/NOResolver.h" #include "phasar/PhasarLLVM/ControlFlow/Resolver/OTFResolver.h" #include "phasar/PhasarLLVM/ControlFlow/Resolver/RTAResolver.h" @@ -205,12 +204,6 @@ std::unique_ptr Resolver::create(CallGraphAnalysisType Ty, case CallGraphAnalysisType::RTA: assert(TH != nullptr); return std::make_unique(IRDB, VTP, TH); - case CallGraphAnalysisType::DTA: - assert(TH != nullptr); - PHASAR_LOG_LEVEL(ERROR, "Do not use the DTA resolver anymore. It relies on " - "the removed 'typed-pointers' feature of LLVM."); - std::exit(1); - // return std::make_unique(IRDB, VTP, TH); case CallGraphAnalysisType::VTA: llvm::report_fatal_error( "The VTA callgraph algorithm is not implemented yet"); diff --git a/lib/PhasarLLVM/ControlFlow/SparseLLVMBasedICFGView.cpp b/lib/PhasarLLVM/ControlFlow/SparseLLVMBasedICFGView.cpp index a61b147cc7..ac17cfbfe1 100644 --- a/lib/PhasarLLVM/ControlFlow/SparseLLVMBasedICFGView.cpp +++ b/lib/PhasarLLVM/ControlFlow/SparseLLVMBasedICFGView.cpp @@ -49,10 +49,6 @@ void SparseLLVMBasedICFGView::printImpl(llvm::raw_ostream &OS) const { ICF->print(OS); } -nlohmann::json SparseLLVMBasedICFGView::getAsJsonImpl() const { - return ICF->getAsJson(); -} - auto SparseLLVMBasedICFGView::getCallGraphImpl() const noexcept -> const CallGraph & { return ICF->getCallGraph(); diff --git a/lib/PhasarLLVM/Passes/GeneralStatisticsAnalysis.cpp b/lib/PhasarLLVM/Passes/GeneralStatisticsAnalysis.cpp index ed64e47840..4575fa59ea 100644 --- a/lib/PhasarLLVM/Passes/GeneralStatisticsAnalysis.cpp +++ b/lib/PhasarLLVM/Passes/GeneralStatisticsAnalysis.cpp @@ -23,7 +23,6 @@ #include "llvm/IR/Module.h" #include "llvm/Pass.h" #include "llvm/Support/Casting.h" -#include "llvm/Support/Format.h" #include "llvm/Support/FormatVariadic.h" #include "llvm/Support/raw_ostream.h" @@ -252,43 +251,6 @@ GeneralStatistics GeneralStatisticsAnalysis::runOnModule(llvm::Module &M) { return Stats; } -size_t GeneralStatistics::getAllocationsites() const { return AllocationSites; } - -size_t GeneralStatistics::getFunctioncalls() const { return CallSites; } - -size_t GeneralStatistics::getInstructions() const { return Instructions; } - -size_t GeneralStatistics::getGlobalPointers() const { return Globals; } - -size_t GeneralStatistics::getBasicBlocks() const { return BasicBlocks; } - -size_t GeneralStatistics::getFunctions() const { return Functions; } - -size_t GeneralStatistics::getGlobals() const { return Globals; } - -size_t GeneralStatistics::getGlobalConsts() const { return GlobalConsts; } - -size_t GeneralStatistics::getMemoryIntrinsics() const { return MemIntrinsics; } - -size_t GeneralStatistics::getStoreInstructions() const { - return StoreInstructions; -} - -const std::set & -GeneralStatistics::getAllocatedTypes() const { - return AllocatedTypes; -} - -const std::set & -GeneralStatistics::getAllocaInstructions() const { - return AllocaInstructions; -} - -const std::set & -GeneralStatistics::getRetResInstructions() const { - return RetResInstructions; -} - void GeneralStatistics::printAsJson(llvm::raw_ostream &OS) const { nlohmann::json Json; @@ -333,14 +295,6 @@ void GeneralStatistics::printAsJson(llvm::raw_ostream &OS) const { OS << Json << '\n'; } -nlohmann::json GeneralStatistics::getAsJson() const { - std::string GeneralStatisticsAsString; - llvm::raw_string_ostream Stream(GeneralStatisticsAsString); - printAsJson(Stream); - - return nlohmann::json::parse(GeneralStatisticsAsString); -} - } // namespace psr namespace { diff --git a/lib/PhasarLLVM/Pointer/LLVMAliasGraph.cpp b/lib/PhasarLLVM/Pointer/LLVMAliasGraph.cpp deleted file mode 100644 index 26a0acac8f..0000000000 --- a/lib/PhasarLLVM/Pointer/LLVMAliasGraph.cpp +++ /dev/null @@ -1,469 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2017 Philipp Schubert. - * All rights reserved. This program and the accompanying materials are made - * available under the terms of LICENSE.txt. - * - * Contributors: - * Philipp Schubert and others - *****************************************************************************/ - -#include "phasar/PhasarLLVM/Pointer/LLVMAliasGraph.h" - -#include "phasar/PhasarLLVM/DB/LLVMProjectIRDB.h" -#include "phasar/PhasarLLVM/Pointer/LLVMBasedAliasAnalysis.h" -#include "phasar/PhasarLLVM/Pointer/LLVMPointsToUtils.h" -#include "phasar/PhasarLLVM/Utils/LLVMShorthands.h" -#include "phasar/Utils/Logger.h" -#include "phasar/Utils/NlohmannLogging.h" -#include "phasar/Utils/PAMMMacros.h" -#include "phasar/Utils/Utilities.h" - -#include "llvm/ADT/SetVector.h" -#include "llvm/Analysis/AliasAnalysis.h" -#include "llvm/IR/Constants.h" -#include "llvm/IR/InstIterator.h" -#include "llvm/IR/Instructions.h" -#include "llvm/IR/Module.h" -#include "llvm/IR/Value.h" -#include "llvm/Support/raw_ostream.h" - -#include "boost/graph/copy.hpp" -#include "boost/graph/depth_first_search.hpp" -#include "boost/graph/graph_utility.hpp" -#include "boost/graph/graphviz.hpp" - -using namespace std; - -namespace psr { -struct LLVMAliasGraph::AllocationSiteDFSVisitor : boost::default_dfs_visitor { - // collect the allocation sites that are found - AliasSetTy &AllocationSites; - // keeps track of the current path - std::vector VisitorStack; - // the call stack that can be matched against the visitor stack - const std::vector &CallStack; - - AllocationSiteDFSVisitor(AliasSetTy &AllocationSizes, - const vector &CallStack) - : AllocationSites(AllocationSizes), CallStack(CallStack) {} - - template - void discover_vertex(Vertex U, const Graph & /*G*/) { - VisitorStack.push_back(U); - } - - template - void finish_vertex(Vertex U, const Graph &G) { - // check for stack allocation - if (const auto *Alloc = llvm::dyn_cast(G[U].V)) { - // If the call stack is empty, we completely ignore the calling context - if (matchesStack(G) || CallStack.empty()) { - PHASAR_LOG_LEVEL(DEBUG, - "Found stack allocation: " << llvmIRToString(Alloc)); - AllocationSites.insert(G[U].V); - } - } - // check for heap allocation - if (llvm::isa(G[U].V) || - llvm::isa(G[U].V)) { - const auto *CallSite = llvm::cast(G[U].V); - if (CallSite->getCalledFunction() != nullptr && - isHeapAllocatingFunction(CallSite->getCalledFunction())) { - // If the call stack is empty, we completely ignore the calling - // context - if (matchesStack(G) || CallStack.empty()) { - PHASAR_LOG_LEVEL( - DEBUG, "Found heap allocation: " << llvmIRToString(CallSite)); - AllocationSites.insert(G[U].V); - } - } - } - VisitorStack.pop_back(); - } - - template bool matchesStack(const Graph &G) { - size_t CallStackIdx = 0; - for (size_t I = 0, J = 1; - I < VisitorStack.size() && J < VisitorStack.size(); ++I, ++J) { - auto E = boost::edge(VisitorStack[I], VisitorStack[J], G); - if (G[E.first].V == nullptr) { - continue; - } - if (G[E.first].V != CallStack[CallStack.size() - CallStackIdx - 1]) { - return false; - } - CallStackIdx++; - } - return true; - } -}; - -struct LLVMAliasGraph::ReachabilityDFSVisitor : boost::default_dfs_visitor { - std::set &AliasSet; - ReachabilityDFSVisitor(set &Result) : AliasSet(Result) {} - template - void finish_vertex(Vertex U, const Graph & /*Graph*/) { - AliasSet.insert(U); - } -}; - -// points-to graph internal stuff - -LLVMAliasGraph::VertexProperties::VertexProperties(const llvm::Value *V) - : V(V) {} - -std::string LLVMAliasGraph::VertexProperties::getValueAsString() const { - return llvmIRToString(V); -} - -std::vector -LLVMAliasGraph::VertexProperties::getUsers() const { - if (!Users.empty() || V == nullptr) { - return Users; - } - auto AllUsers = V->users(); - Users.insert(Users.end(), AllUsers.begin(), AllUsers.end()); - return Users; -} - -LLVMAliasGraph::EdgeProperties::EdgeProperties(const llvm::Value *V) : V(V) {} - -std::string LLVMAliasGraph::EdgeProperties::getValueAsString() const { - return llvmIRToString(V); -} - -// points-to graph stuff - -LLVMAliasGraph::LLVMAliasGraph(LLVMProjectIRDB &IRDB, bool UseLazyEvaluation, - AliasAnalysisType /*PATy*/) - : PTA(IRDB, UseLazyEvaluation) {} - -void LLVMAliasGraph::computeAliasGraph(const llvm::Value *V) { - // FIXME when fixed in LLVM - auto *VF = const_cast(retrieveFunction(V)); // NOLINT - computeAliasGraph(VF); -} - -void LLVMAliasGraph::computeAliasGraph(llvm::Function *F) { - // check if we already analyzed the function - if (AnalyzedFunctions.find(F) != AnalyzedFunctions.end()) { - return; - } - PAMM_GET_INSTANCE; - PHASAR_LOG_LEVEL(DEBUG, "Analyzing function: " << F->getName()); - AnalyzedFunctions.insert(F); - llvm::AAResults &AA = *PTA.getAAResults(F); - bool EvalAAMD = true; - - // taken from llvm/Analysis/AliasAnalysisEvaluator.cpp - const llvm::DataLayout &DL = F->getParent()->getDataLayout(); - - llvm::SetVector Pointers; - llvm::SmallSetVector Calls; - llvm::SetVector Loads; - llvm::SetVector Stores; - - for (auto &I : F->args()) { - if (I.getType()->isPointerTy()) { // Add all pointer arguments. - Pointers.insert(&I); - } - } - - for (llvm::inst_iterator I = inst_begin(*F), E = inst_end(*F); I != E; ++I) { - if (I->getType()->isPointerTy()) { // Add all pointer instructions. - Pointers.insert(&*I); - } - if (EvalAAMD && llvm::isa(&*I)) { - Loads.insert(&*I); - } - if (EvalAAMD && llvm::isa(&*I)) { - Stores.insert(&*I); - } - llvm::Instruction &Inst = *I; - if (auto *Call = llvm::dyn_cast(&Inst)) { - llvm::Value *Callee = Call->getCalledOperand(); - // Skip actual functions for direct function calls. - if (!llvm::isa(Callee) && isInterestingPointer(Callee)) { - Pointers.insert(Callee); - } - // Consider formals. - for (llvm::Use &DataOp : Call->data_ops()) { - if (isInterestingPointer(DataOp)) { - Pointers.insert(DataOp); - } - } - Calls.insert(Call); - } else { - // Consider all operands. - for (llvm::Instruction::op_iterator OI = Inst.op_begin(), - OE = Inst.op_end(); - OI != OE; ++OI) { - if (isInterestingPointer(*OI)) { - Pointers.insert(*OI); - } - } - } - } - - INC_COUNTER("GS Pointer", Pointers.size(), Core); - - // make vertices for all pointers - for (auto *P : Pointers) { - ValueVertexMap[P] = boost::add_vertex(VertexProperties(P), PAG); - } - // iterate over the worklist, and run the full (n^2)/2 disambiguations - const auto MapEnd = ValueVertexMap.end(); - for (auto I1 = ValueVertexMap.begin(); I1 != MapEnd; ++I1) { - llvm::Type *I1ElTy = - !I1->first->getType()->isOpaquePointerTy() - ? I1->first->getType()->getNonOpaquePointerElementType() - : nullptr; - const uint64_t I1Size = I1ElTy && I1ElTy->isSized() - ? DL.getTypeStoreSize(I1ElTy) - : llvm::MemoryLocation::UnknownSize; - for (auto I2 = std::next(I1); I2 != MapEnd; ++I2) { - llvm::Type *I2ElTy = - !I2->first->getType()->isOpaquePointerTy() - ? I2->first->getType()->getNonOpaquePointerElementType() - : nullptr; - const uint64_t I2Size = I2ElTy && I2ElTy->isSized() - ? DL.getTypeStoreSize(I2ElTy) - : llvm::MemoryLocation::UnknownSize; - switch (AA.alias(I1->first, I1Size, I2->first, I2Size)) { - case llvm::AliasResult::NoAlias: - break; - case llvm::AliasResult::MayAlias: // no break - [[fallthrough]]; - case llvm::AliasResult::PartialAlias: // no break - [[fallthrough]]; - case llvm::AliasResult::MustAlias: - boost::add_edge(I1->second, I2->second, PAG); - break; - default: - break; - } - } - } -} - -bool LLVMAliasGraph::isInterProcedural() const noexcept { return false; } - -AliasAnalysisType LLVMAliasGraph::getAliasAnalysisType() const noexcept { - return AliasAnalysisType::Invalid; -} - -AliasResult LLVMAliasGraph::alias(const llvm::Value *V1, const llvm::Value *V2, - const llvm::Instruction * /*I*/) { - computeAliasGraph(V1); - computeAliasGraph(V2); - auto PTS = getAliasSet(V1); - if (PTS->contains(V2)) { - return AliasResult::MustAlias; - } - return AliasResult::NoAlias; -} - -auto LLVMAliasGraph::getReachableAllocationSites( - const llvm::Value *V, bool /*IntraProcOnly*/, - const llvm::Instruction * /*I*/) -> AllocationSiteSetPtrTy { - computeAliasGraph(V); - auto AllocSites = std::make_unique(); - AllocationSiteDFSVisitor AllocVis(*AllocSites, {}); - vector ColorMap(boost::num_vertices(PAG)); - boost::depth_first_visit( - PAG, ValueVertexMap[V], AllocVis, - boost::make_iterator_property_map( - ColorMap.begin(), boost::get(boost::vertex_index, PAG), ColorMap[0])); - return AllocSites; -} - -[[nodiscard]] bool LLVMAliasGraph::isInReachableAllocationSites( - const llvm::Value *V, const llvm::Value *PotentialValue, bool IntraProcOnly, - const llvm::Instruction *I) { - return getReachableAllocationSites(V, IntraProcOnly, I) - ->count(PotentialValue); -} - -void LLVMAliasGraph::mergeWith(const LLVMAliasGraph &OtherPTI) { - AnalyzedFunctions.insert(OtherPTI.AnalyzedFunctions.begin(), - OtherPTI.AnalyzedFunctions.end()); - using vertex_t = graph_t::vertex_descriptor; - using vertex_map_t = std::map; - vertex_map_t OldToNewVertexMapping; - boost::associative_property_map VertexMapWrapper( - OldToNewVertexMapping); - boost::copy_graph(OtherPTI.PAG, PAG, boost::orig_to_copy(VertexMapWrapper)); - for (const auto &OtherValues : OtherPTI.ValueVertexMap) { - auto Search = OldToNewVertexMapping.find(OtherValues.second); - if (Search != OldToNewVertexMapping.end()) { - ValueVertexMap.insert(make_pair(OtherValues.first, Search->second)); - } - } -} - -void LLVMAliasGraph::introduceAlias(const llvm::Value *V1, - const llvm::Value *V2, - const llvm::Instruction *I, - AliasResult /*Kind*/) { - computeAliasGraph(V1); - computeAliasGraph(V2); - auto Vert1 = ValueVertexMap[V1]; - auto Vert2 = ValueVertexMap[V2]; - boost::add_edge(Vert1, Vert2, I, PAG); -} - -vector> -LLVMAliasGraph::getPointersEscapingThroughParams() { - vector> EscapingPointers; - for (auto VertexIter : boost::make_iterator_range(boost::vertices(PAG))) { - if (const auto *Arg = llvm::dyn_cast(PAG[VertexIter].V)) { - EscapingPointers.emplace_back(Arg->getArgNo(), Arg); - } - } - return EscapingPointers; -} - -vector -LLVMAliasGraph::getPointersEscapingThroughReturns() const { - vector EscapingPointers; - for (auto VertexIter : boost::make_iterator_range(boost::vertices(PAG))) { - const auto &Vertex = PAG[VertexIter]; - for (const auto *const User : Vertex.getUsers()) { - if (llvm::isa(User)) { - EscapingPointers.push_back(Vertex.V); - } - } - } - return EscapingPointers; -} - -vector -LLVMAliasGraph::getPointersEscapingThroughReturnsForFunction( - const llvm::Function *F) const { - vector EscapingPointers; - for (auto VertexIter : boost::make_iterator_range(boost::vertices(PAG))) { - const auto &Vertex = PAG[VertexIter]; - for (const auto *const User : Vertex.getUsers()) { - if (const auto *R = llvm::dyn_cast(User)) { - if (R->getFunction() == F) { - EscapingPointers.push_back(Vertex.V); - } - } - } - } - return EscapingPointers; -} - -bool LLVMAliasGraph::containsValue(llvm::Value *V) { - for (auto VertexIter : boost::make_iterator_range(boost::vertices(PAG))) { - if (PAG[VertexIter].V == V) { - return true; - } - } - return false; -} - -auto LLVMAliasGraph::getAliasSet(const llvm::Value *V, - const llvm::Instruction * /*I*/) - -> AliasSetPtrTy { - PAMM_GET_INSTANCE; - INC_COUNTER("[Calls] getAliasSet", 1, Full); - START_TIMER("Alias-Set Computation", Full); - const auto *VF = retrieveFunction(V); - computeAliasGraph(VF); - // check if the graph contains a corresponding vertex - set ReachableVertices; - ReachabilityDFSVisitor Vis(ReachableVertices); - vector ColorMap(boost::num_vertices(PAG)); - boost::depth_first_visit( - PAG, ValueVertexMap.at(V), Vis, - boost::make_iterator_property_map( - ColorMap.begin(), boost::get(boost::vertex_index, PAG), ColorMap[0])); - auto ResultSet = [this, V] { - auto &Ret = Cache[V]; - - if (!Ret) { - Ret = Owner.acquire(); - } - - return Ret; - }(); - - for (auto Vertex : ReachableVertices) { - ResultSet->insert(PAG[Vertex].V); - } - PAUSE_TIMER("Alias-Set Computation", Full); - ADD_TO_HISTOGRAM("Points-to", ResultSet->size(), 1, Full); - return ResultSet; -} - -void LLVMAliasGraph::print(llvm::raw_ostream &OS) const { - for (const auto &Fn : AnalyzedFunctions) { - llvm::outs() << "LLVMAliasGraph for " << Fn->getName() << ":\n"; - vertex_iterator UI; - - vertex_iterator UIEnd; - for (boost::tie(UI, UIEnd) = boost::vertices(PAG); UI != UIEnd; ++UI) { - OS << PAG[*UI].getValueAsString() << " <--> "; - out_edge_iterator EI; - - out_edge_iterator EIEnd; - for (boost::tie(EI, EIEnd) = boost::out_edges(*UI, PAG); EI != EIEnd; - ++EI) { - OS << PAG[target(*EI, PAG)].getValueAsString() << " "; - } - OS << '\n'; - } - } -} - -void LLVMAliasGraph::printAsDot(llvm::raw_ostream &OS) const { - std::stringstream S; - boost::write_graphviz(S, PAG, makePointerVertexOrEdgePrinter(PAG), - makePointerVertexOrEdgePrinter(PAG)); - OS << S.str(); -} - -nlohmann::json LLVMAliasGraph::getAsJson() const { - nlohmann::json J; - vertex_iterator VIv; - - vertex_iterator VIvEnd; - out_edge_iterator EI; - - out_edge_iterator EIEnd; - // iterate all graph vertices - for (boost::tie(VIv, VIvEnd) = boost::vertices(PAG); VIv != VIvEnd; ++VIv) { - J[PhasarConfig::JsonAliasGraphID().str()][PAG[*VIv].getValueAsString()]; - // iterate all out edges of vertex vi_v - for (boost::tie(EI, EIEnd) = boost::out_edges(*VIv, PAG); EI != EIEnd; - ++EI) { - J[PhasarConfig::JsonAliasGraphID().str()][PAG[*VIv].getValueAsString()] += - PAG[boost::target(*EI, PAG)].getValueAsString(); - } - } - return J; -} - -void LLVMAliasGraph::printValueVertexMap() { - for (const auto &Entry : ValueVertexMap) { - llvm::outs() << Entry.first << " <---> " << Entry.second << '\n'; - } -} - -bool LLVMAliasGraph::empty() const { return size() == 0; } - -size_t LLVMAliasGraph::size() const { return getNumVertices(); } - -size_t LLVMAliasGraph::getNumVertices() const { - return boost::num_vertices(PAG); -} - -size_t LLVMAliasGraph::getNumEdges() const { return boost::num_edges(PAG); } - -void LLVMAliasGraph::printAsJson(llvm::raw_ostream &OS) const { - nlohmann::json J = getAsJson(); - OS << J; -} - -} // namespace psr diff --git a/lib/PhasarLLVM/Pointer/LLVMAliasSet.cpp b/lib/PhasarLLVM/Pointer/LLVMAliasSet.cpp index ecc2eb532d..6beca389fb 100644 --- a/lib/PhasarLLVM/Pointer/LLVMAliasSet.cpp +++ b/lib/PhasarLLVM/Pointer/LLVMAliasSet.cpp @@ -716,33 +716,6 @@ void LLVMAliasSet::introduceAlias(const llvm::Value *V1, const llvm::Value *V2, mergeAliasSets(V1, V2); } -nlohmann::json LLVMAliasSet::getAsJson() const { - nlohmann::json J; - - /// Serialize the AliasSets - auto &Sets = J["AliasSets"]; - - for (const AliasSetTy *PTS : Owner.getAllAliasSets()) { - auto PtsJson = nlohmann::json::array(); - for (const auto *Alias : *PTS) { - auto Id = getMetaDataID(Alias); - if (Id != "-1") { - PtsJson.push_back(std::move(Id)); - } - } - if (!PtsJson.empty()) { - Sets.push_back(std::move(PtsJson)); - } - } - - /// Serialize the AnalyzedFunctions - auto &Fns = J["AnalyzedFunctions"]; - for (const auto *F : AnalyzedFunctions) { - Fns.push_back(F->getName()); - } - return J; -} - LLVMAliasSetData LLVMAliasSet::getLLVMAliasSetData() const { LLVMAliasSetData Data; diff --git a/lib/PhasarLLVM/Pointer/TypeGraphs/CachedTypeGraph.cpp b/lib/PhasarLLVM/Pointer/TypeGraphs/CachedTypeGraph.cpp deleted file mode 100644 index 77c7ab8698..0000000000 --- a/lib/PhasarLLVM/Pointer/TypeGraphs/CachedTypeGraph.cpp +++ /dev/null @@ -1,159 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2017 Philipp Schubert. - * All rights reserved. This program and the accompanying materials are made - * available under the terms of LICENSE.txt. - * - * Contributors: - * Philipp Schubert and others - *****************************************************************************/ - -/* - * TypeGraph.cpp - * - * Created on: 28.06.2018 - * Author: nicolas bellec - */ - -#include "phasar/PhasarLLVM/Pointer/TypeGraphs/CachedTypeGraph.h" - -#include "phasar/Utils/Logger.h" -#include "phasar/Utils/Utilities.h" - -#include "llvm/IR/DerivedTypes.h" - -#include "boost/graph/depth_first_search.hpp" -#include "boost/graph/graph_utility.hpp" -#include "boost/graph/graphviz.hpp" -#include "boost/property_map/dynamic_property_map.hpp" - -using namespace std; -using namespace psr; - -namespace psr { - -struct CachedTypeGraph::dfs_visitor : public boost::default_dfs_visitor { - dfs_visitor(graph_t *G) : G(G) {} - - void finish_edge(edge_t E, graph_t const &U) { // NOLINT - CachedTypeGraph::vertex_t Src = boost::source(E, U); - CachedTypeGraph::vertex_t Target = boost::target(E, U); - - for (const auto *TargetType : U[Target].Types) { - (*G)[Src].Types.insert(TargetType); - } - } - - graph_t *G; -}; - -struct CachedTypeGraph::reverse_type_propagation_dfs_visitor - : public boost::default_dfs_visitor { - reverse_type_propagation_dfs_visitor(rev_graph_t *G) : G(G) {} - - void examine_edge(rev_edge_t E, rev_graph_t const &U) { // NOLINT - auto Src = boost::source(E, U); - auto Target = boost::target(E, U); - - for (const auto *SrcType : U[Src].Types) { - (*G)[Target].Types.insert(SrcType); - } - } - - rev_graph_t *G; -}; - -CachedTypeGraph::vertex_t -CachedTypeGraph::addType(const llvm::StructType *NewType) { - std::string Name; - if (!NewType->isLiteral()) { - Name = NewType->getName(); - } else { - std::stringstream StrS; - StrS << "literal_" << NewType; - Name = StrS.str(); - } - - if (TypeVertexMap.find(Name) == TypeVertexMap.end()) { - auto Vertex = boost::add_vertex(G); - TypeVertexMap[Name] = Vertex; - G[Vertex].Name = Name; - G[Vertex].BaseType = NewType; - G[Vertex].Types.insert(NewType); - } - - return TypeVertexMap[Name]; -} - -bool CachedTypeGraph::addLink(const llvm::StructType *From, - const llvm::StructType *To) { - if (AlreadyVisited) { - return false; - } - - AlreadyVisited = true; - - auto FromVertex = addType(From); - auto ToVertex = addType(To); - - auto ResultEdge = boost::add_edge(FromVertex, ToVertex, G); - - if (ResultEdge.second) { - reverseTypePropagation(To); - } - - AlreadyVisited = false; - return ResultEdge.second; -} - -bool CachedTypeGraph::addLinkWithoutReversePropagation( - const llvm::StructType *From, const llvm::StructType *To) { - if (AlreadyVisited) { - return false; - } - - AlreadyVisited = true; - - auto FromVertex = addType(From); - auto ToVertex = addType(To); - - auto ResultEdge = boost::add_edge(FromVertex, ToVertex, G); - - AlreadyVisited = false; - return ResultEdge.second; -} - -void CachedTypeGraph::printAsDot(const std::string &Path) const { - std::ofstream Ofs(Path); - boost::write_graphviz( - Ofs, G, boost::make_label_writer(boost::get(&VertexProperties::Name, G))); -} - -void CachedTypeGraph::aggregateTypes() { - dfs_visitor Vis(&G); - boost::depth_first_search(G, boost::visitor(Vis)); -} - -void CachedTypeGraph::reverseTypePropagation( - const llvm::StructType *BaseStruct) { - auto Name = BaseStruct->getName().str(); - - std::vector ColorMap(boost::num_vertices(G)); - - auto Reversed = boost::reverse_graph(G); - reverse_type_propagation_dfs_visitor Vis(&Reversed); - - boost::depth_first_visit(Reversed, TypeVertexMap[Name], Vis, - boost::make_iterator_property_map( - ColorMap.begin(), - boost::get(boost::vertex_index, Reversed), - ColorMap[0])); -} - -std::set -CachedTypeGraph::getTypes(const llvm::StructType *StructType) { - auto StructTyVertex = addType(StructType); - return G[StructTyVertex].Types; -} - -} // namespace psr diff --git a/lib/PhasarLLVM/Pointer/TypeGraphs/LazyTypeGraph.cpp b/lib/PhasarLLVM/Pointer/TypeGraphs/LazyTypeGraph.cpp deleted file mode 100644 index ee33541287..0000000000 --- a/lib/PhasarLLVM/Pointer/TypeGraphs/LazyTypeGraph.cpp +++ /dev/null @@ -1,104 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2017 Philipp Schubert. - * All rights reserved. This program and the accompanying materials are made - * available under the terms of LICENSE.txt. - * - * Contributors: - * Philipp Schubert and others - *****************************************************************************/ - -/* - * LazyLazyTypeGraph.cpp - * - * Created on: 28.06.2018 - * Author: nicolas bellec - */ - -#include "phasar/PhasarLLVM/Pointer/TypeGraphs/LazyTypeGraph.h" - -#include "phasar/Utils/Logger.h" -#include "phasar/Utils/Utilities.h" - -#include "llvm/IR/DerivedTypes.h" - -#include "boost/graph/depth_first_search.hpp" -#include "boost/graph/graph_utility.hpp" -#include "boost/graph/graphviz.hpp" -#include "boost/property_map/dynamic_property_map.hpp" - -using namespace std; -using namespace psr; - -namespace psr { - -struct LazyTypeGraph::dfs_visitor : public boost::default_dfs_visitor { - dfs_visitor(std::set &Result) : Result(Result) {} - - void finish_edge(edge_t E, graph_t const &U) { - LazyTypeGraph::vertex_t Target = boost::target(E, U); - - Result.insert(U[Target].SType); - } - - std::set &Result; -}; - -LazyTypeGraph::vertex_t -LazyTypeGraph::addType(const llvm::StructType *NewType) { - auto Name = NewType->getName().str(); - - if (TypeToVertexMap.find(Name) == TypeToVertexMap.end()) { - auto Vertex = boost::add_vertex(Graph); - TypeToVertexMap[Name] = Vertex; - Graph[Vertex].Name = Name; - Graph[Vertex].SType = NewType; - } - - return TypeToVertexMap[Name]; -} - -bool LazyTypeGraph::addLink(const llvm::StructType *From, - const llvm::StructType *To) { - if (AlreadyVisited) { - return false; - } - - AlreadyVisited = true; - - auto FromVertex = addType(From); - auto ToVertex = addType(To); - - auto ResultEdge = boost::add_edge(FromVertex, ToVertex, Graph); - - AlreadyVisited = false; - return ResultEdge.second; -} - -void LazyTypeGraph::printAsDot(const std::string &Path) const { - std::ofstream Ofs(Path); - boost::write_graphviz(Ofs, Graph, - boost::make_label_writer(boost::get( - &LazyTypeGraph::VertexProperties::Name, Graph))); -} - -std::set -LazyTypeGraph::getTypes(const llvm::StructType *StructType) { - auto StructTyVertex = addType(StructType); - - std::vector ColorMap(boost::num_vertices(Graph)); - - std::set Results; - Results.insert(StructType); - - dfs_visitor Vis(Results); - - boost::depth_first_visit( - Graph, StructTyVertex, Vis, - boost::make_iterator_property_map(ColorMap.begin(), - boost::get(boost::vertex_index, Graph), - ColorMap[0])); - - return Results; -} - -} // namespace psr diff --git a/lib/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.cpp b/lib/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.cpp index d6188b1b53..36319dc05a 100644 --- a/lib/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.cpp +++ b/lib/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.cpp @@ -361,12 +361,6 @@ void DIBasedTypeHierarchy::print(llvm::raw_ostream &OS) const { } } -[[nodiscard]] [[deprecated("Please use printAsJson() instead")]] nlohmann::json -DIBasedTypeHierarchy::getAsJson() const { - /// TODO: implement - llvm::report_fatal_error("Not implemented"); -} - DIBasedTypeHierarchyData DIBasedTypeHierarchy::getTypeHierarchyData() const { DIBasedTypeHierarchyData Data; diff --git a/lib/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.cpp b/lib/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.cpp index 2e0707f9f4..028abe8659 100644 --- a/lib/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.cpp +++ b/lib/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.cpp @@ -49,7 +49,7 @@ using namespace std; namespace psr { // provide a VertexPropertyWrite to tell boost how to write a vertex -class TypeHierarchyVertexWriter { +class [[deprecated]] TypeHierarchyVertexWriter { public: TypeHierarchyVertexWriter(const LLVMTypeHierarchy::bidigraph_t &TyGraph) : TyGraph(TyGraph) {} @@ -389,75 +389,6 @@ void LLVMTypeHierarchy::print(llvm::raw_ostream &OS) const { } } -nlohmann::json LLVMTypeHierarchy::getAsJson() const { - nlohmann::json J; - vertex_iterator VIv; - - vertex_iterator VIvEnd; - out_edge_iterator EI; - - out_edge_iterator EIEnd; - // iterate all graph vertices - for (boost::tie(VIv, VIvEnd) = boost::vertices(TypeGraph); VIv != VIvEnd; - ++VIv) { - J[PhasarConfig::JsonTypeHierarchyID().str()][TypeGraph[*VIv].getTypeName()]; - // iterate all out edges of vertex vi_v - for (boost::tie(EI, EIEnd) = boost::out_edges(*VIv, TypeGraph); EI != EIEnd; - ++EI) { - J[PhasarConfig::JsonTypeHierarchyID().str()] - [TypeGraph[*VIv].getTypeName()] += - TypeGraph[boost::target(*EI, TypeGraph)].getTypeName(); - } - } - return J; -} - -// void LLVMTypeHierarchy::mergeWith(LLVMTypeHierarchy &Other) { -// cout << "LLVMTypeHierarchy::mergeWith()" << endl; -// boost::copy_graph(Other.TypeGraph, TypeGraph); // G += H; -// // build the contractions -// vector> contractions; -// map observed; -// for (auto V : boost::make_iterator_range(boost::vertices(TypeGraph))) { -// if (observed.find(TypeGraph[V].name) != observed.end()) { -// // check which one has the valid pointer and the knowledge of the -// vtables if (TypeGraph[V].llvmtype) { -// contractions.push_back(make_pair(observed[TypeGraph[V].name], V)); -// } else { -// contractions.push_back(make_pair(V, observed[TypeGraph[V].name])); -// } -// } else { -// observed[TypeGraph[V].name] = V; -// } -// } -// cout << "contractions.size(): " << contractions.size() << '\n'; -// for (auto contraction : contractions) { -// contract_vertices( -// contraction.first, contraction.second, TypeGraph); -// } -// // merge the vtables -// TypeVFTMap.insert(Other.TypeVFTMap.begin(), -// Other.TypeVFTMap.end()); -// // merge the modules analyzed -// contained_modules.insert(Other.contained_modules.begin(), -// Other.contained_modules.end()); -// // reset the vertex mapping -// TypeVertexMap.clear(); -// for (auto V : boost::make_iterator_range(boost::vertices(TypeGraph))) { -// TypeVertexMap[TypeGraph[V].name] = V; -// } -// // cache the reachable types -// bidigraph_t tc; -// boost::transitive_closure(TypeGraph, tc); -// for (auto V : boost::make_iterator_range(boost::vertices(TypeGraph))) { -// for (auto OE : boost::make_iterator_range(boost::out_edges(V, tc))) { -// auto Source = boost::source(OE, tc); -// auto Target = boost::target(OE, tc); -// TypeGraph[V].reachableTypes.insert(TypeGraph[Target].name); -// } -// } -// } - void LLVMTypeHierarchy::printAsDot(llvm::raw_ostream &OS) const { std::stringstream S; boost::write_graphviz(S, TypeGraph, TypeHierarchyVertexWriter(TypeGraph)); diff --git a/lib/PhasarLLVM/TypeHierarchy/LLVMVFTable.cpp b/lib/PhasarLLVM/TypeHierarchy/LLVMVFTable.cpp index b25822da84..f2a5a849bd 100644 --- a/lib/PhasarLLVM/TypeHierarchy/LLVMVFTable.cpp +++ b/lib/PhasarLLVM/TypeHierarchy/LLVMVFTable.cpp @@ -48,11 +48,6 @@ void LLVMVFTable::print(llvm::raw_ostream &OS) const { } } -nlohmann::json LLVMVFTable::getAsJson() const { - nlohmann::json J = "{}"_json; - return J; -} - [[nodiscard]] LLVMVFTableData LLVMVFTable::getVFTableData() const { LLVMVFTableData Data; diff --git a/lib/Utils/Logger.cpp b/lib/Utils/Logger.cpp index 35cd18a29f..b166bf67b6 100644 --- a/lib/Utils/Logger.cpp +++ b/lib/Utils/Logger.cpp @@ -225,16 +225,3 @@ void Logger::addLinePrefix(llvm::raw_ostream &OS, } } // namespace psr - -void psr::initializeLogger(bool UseLogger, const std::string &LogFile) { - if (!UseLogger) { - Logger::disable(); - return; - } - if (LogFile.empty()) { - Logger::initializeStderrLogger(Logger::getLoggerFilterLevel()); - } else { - std::ignore = - Logger::initializeFileLogger(LogFile, Logger::getLoggerFilterLevel()); - } -} diff --git a/lib/Utils/Utilities.cpp b/lib/Utils/Utilities.cpp index 28e8d378ec..0c2aeedaca 100644 --- a/lib/Utils/Utilities.cpp +++ b/lib/Utils/Utilities.cpp @@ -64,19 +64,6 @@ bool isConstructor(llvm::StringRef MangledName) { return false; } -const llvm::Type *legacy::stripPointer(const llvm::Type *Pointer) { - const auto *Next = llvm::dyn_cast(Pointer); - while (Next) { - assert(!Next->isOpaquePointerTy() && - "Don't call stripPointer, when analyzing IR that uses opaque " - "pointers!"); - Pointer = Next->getNonOpaquePointerElementType(); - Next = llvm::dyn_cast(Pointer); - } - - return Pointer; -} - bool isMangled(llvm::StringRef Name) { // See llvm/Demangle/Demangle.cpp if (Name.startswith("_Z") || Name.startswith("___Z")) { diff --git a/unittests/DB/HexastoreTest.cpp b/unittests/DB/HexastoreTest.cpp index 06bc7ff83a..6ce20b23a7 100644 --- a/unittests/DB/HexastoreTest.cpp +++ b/unittests/DB/HexastoreTest.cpp @@ -100,12 +100,12 @@ TEST(HexastoreTest, StoreGraphNoEdgeLabels) { struct Vertex { string Name; Vertex() = default; - Vertex(string Name) : Name(move(Name)) {} + Vertex(string Name) : Name(std::move(Name)) {} }; struct Edge { string EdgeName; Edge() = default; - Edge(string Label) : EdgeName(move(Label)) {} + Edge(string Label) : EdgeName(std::move(Label)) {} }; using graph_t = boost::adjacency_list(I) || llvm::isa(I)) { - const auto &Callees = ICFG.getCalleesOfCallAt(I); - - ASSERT_TRUE(ICFG.isVirtualFunctionCall(I)); - ASSERT_EQ(Callees.size(), 2U); - ASSERT_TRUE(llvm::is_contained(Callees, VFuncB)); - ASSERT_TRUE(llvm::is_contained(Callees, VFuncA)); - ASSERT_TRUE(llvm::is_contained(ICFG.getCallersOf(VFuncA), I)); - ASSERT_TRUE(llvm::is_contained(ICFG.getCallersOf(VFuncB), I)); - } -} - -TEST(LLVMBasedICFG_DTATest, VirtualCallSite_6) { - GTEST_SKIP() << "Requires typed pointers!"; - LLVMProjectIRDB IRDB(unittest::PathToLLTestFiles + - "call_graphs/virtual_call_6_cpp.ll"); - DIBasedTypeHierarchy TH(IRDB); - LLVMAliasSet PT(&IRDB); - LLVMBasedICFG ICFG(&IRDB, CallGraphAnalysisType::DTA, {"main"}, &TH, &PT); - const llvm::Function *F = IRDB.getFunctionDefinition("main"); - const llvm::Function *VFuncA = IRDB.getFunctionDefinition("_ZN1A5VfuncEv"); - const llvm::Function *VFuncB = IRDB.getFunctionDefinition("_ZN1B5VfuncEv"); - ASSERT_TRUE(F); - ASSERT_TRUE(VFuncA); - ASSERT_TRUE(VFuncB); - - const llvm::Instruction *I = getNthInstruction(F, 6); - const auto &Callers = ICFG.getCallersOf(VFuncA); - ASSERT_EQ(Callers.size(), 1U); - ASSERT_TRUE(llvm::is_contained(Callers, I)); -} - -int main(int Argc, char **Argv) { - ::testing::InitGoogleTest(&Argc, Argv); - return RUN_ALL_TESTS(); -} diff --git a/unittests/PhasarLLVM/TypeHierarchy/CMakeLists.txt b/unittests/PhasarLLVM/TypeHierarchy/CMakeLists.txt index d4407ecef7..fc190151ac 100644 --- a/unittests/PhasarLLVM/TypeHierarchy/CMakeLists.txt +++ b/unittests/PhasarLLVM/TypeHierarchy/CMakeLists.txt @@ -3,7 +3,6 @@ set(PointerSources DIBasedTypeHierarchyTest.cpp LLVMTypeHierarchySerializationTest.cpp LLVMTypeHierarchyTest.cpp - TypeGraphTest.cpp ) foreach(TEST_SRC ${PointerSources}) diff --git a/unittests/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchySerializationTest.cpp b/unittests/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchySerializationTest.cpp index 8ce287caf4..9042b52547 100644 --- a/unittests/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchySerializationTest.cpp +++ b/unittests/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchySerializationTest.cpp @@ -15,6 +15,9 @@ using namespace psr; +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated" + /* ============== TEST FIXTURE ============== */ class LLVMTypeHierarchySerialization : public ::testing::TestWithParam { @@ -65,6 +68,8 @@ TEST_P(LLVMTypeHierarchySerialization, OrigAndDeserEqual) { compareResults(TypeHierarchy, DeserializedTypeHierarchy); } +#pragma GCC diagnostic pop + static constexpr std::string_view TypeHierarchyTestFiles[] = { "type_hierarchy_1_cpp_dbg.ll", "type_hierarchy_2_cpp_dbg.ll", "type_hierarchy_3_cpp_dbg.ll", "type_hierarchy_4_cpp_dbg.ll", diff --git a/unittests/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchyTest.cpp b/unittests/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchyTest.cpp index 0d302c9124..c9404f6070 100644 --- a/unittests/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchyTest.cpp +++ b/unittests/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchyTest.cpp @@ -20,6 +20,9 @@ using namespace psr; using llvm::demangle; +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated" + namespace psr { // Check basic type hierarchy construction @@ -408,6 +411,8 @@ PHASAR_SKIP_TEST(TEST(LTHTest, HandleSTLString) { } // namespace psr +#pragma GCC diagnostic pop + int main(int Argc, char **Argv) { ::testing::InitGoogleTest(&Argc, Argv); auto Res = RUN_ALL_TESTS(); diff --git a/unittests/PhasarLLVM/TypeHierarchy/TypeGraphTest.cpp b/unittests/PhasarLLVM/TypeHierarchy/TypeGraphTest.cpp deleted file mode 100644 index 22a5252239..0000000000 --- a/unittests/PhasarLLVM/TypeHierarchy/TypeGraphTest.cpp +++ /dev/null @@ -1,417 +0,0 @@ -#include "gtest/gtest.h" -// -- Need gtest for the FRIEND_TEST macro -#define PSR_FRIEND_TEST(TEST, CLASS) FRIEND_TEST(TEST, CLASS); - -#include "phasar/Config/Configuration.h" -#include "phasar/PhasarLLVM/DB/LLVMProjectIRDB.h" -#include "phasar/PhasarLLVM/Pointer/TypeGraphs/CachedTypeGraph.h" -#include "phasar/PhasarLLVM/Pointer/TypeGraphs/LazyTypeGraph.h" -#include "phasar/PhasarLLVM/Utils/LLVMShorthands.h" -#include "phasar/Utils/Utilities.h" - -#include "llvm/Support/ManagedStatic.h" - -#include "TestConfig.h" -#include "boost/graph/isomorphism.hpp" - -using namespace std; -using namespace psr; - -namespace psr { - -TEST(TypeGraphTest, AddType) { - LLVMProjectIRDB IRDB( - {unittest::PathToLLTestFiles + "basic/two_structs_cpp.ll"}); - llvm::Module *M = IRDB.getModule(); - - unsigned int NbStruct = 0; - - CachedTypeGraph Tg; - CachedTypeGraph::graph_t G; - - for (auto *StructType : M->getIdentifiedStructTypes()) { - ASSERT_TRUE(StructType != nullptr); - - auto Node = Tg.addType(StructType); - - ASSERT_TRUE(Tg.G[Node].Name == StructType->getName().str()); - ASSERT_TRUE(Tg.G[Node].BaseType == StructType); - ASSERT_TRUE(Tg.G[Node].Types.size() == 1); - ASSERT_TRUE(Tg.G[Node].Types.count(StructType)); - - boost::add_vertex(G); - - ASSERT_TRUE(boost::isomorphism(G, Tg.G)); - - ++NbStruct; - } - - ASSERT_TRUE(NbStruct >= 2); -} - -TEST(TypeGraphTest, ReverseTypePropagation) { - LLVMProjectIRDB IRDB( - {unittest::PathToLLTestFiles + "basic/seven_structs_cpp.ll"}); - llvm::Module *M = IRDB.getModule(); - - unsigned int NbStruct = 0; - llvm::StructType *StructA = nullptr; - - llvm::StructType *StructB = nullptr; - - llvm::StructType *StructC = nullptr; - - llvm::StructType *StructD = nullptr; - - llvm::StructType *StructE = nullptr; - - CachedTypeGraph Tg; - - // Isomorphism to assure that the TypeGraph have the wanted structure - CachedTypeGraph::graph_t G; - - for (auto *StructType : M->getIdentifiedStructTypes()) { - if (StructType) { - switch (NbStruct) { - case 0: - StructA = StructType; - break; - case 1: - StructB = StructType; - break; - case 2: - StructC = StructType; - break; - case 3: - StructD = StructType; - break; - case 4: - StructE = StructType; - break; - case 5: - [[fallthrough]]; - case 6: - break; - default: - // NB: Will always fail but serve to understand where the error come - // from - ASSERT_TRUE(NbStruct < 7); - break; - } - - ++NbStruct; - } - } - - ASSERT_TRUE(NbStruct == 7); - ASSERT_TRUE(StructA != nullptr); - ASSERT_TRUE(StructB != nullptr); - ASSERT_TRUE(StructC != nullptr); - ASSERT_TRUE(StructD != nullptr); - ASSERT_TRUE(StructE != nullptr); - - auto VertexA = boost::add_vertex(G); - auto VertexB = boost::add_vertex(G); - auto VertexC = boost::add_vertex(G); - auto VertexD = boost::add_vertex(G); - auto VertexE = boost::add_vertex(G); - - auto NodeA = Tg.addType(StructA); - auto NodeB = Tg.addType(StructB); - auto NodeC = Tg.addType(StructC); - auto NodeD = Tg.addType(StructD); - auto NodeE = Tg.addType(StructE); - - Tg.addLinkWithoutReversePropagation(StructA, StructB); - Tg.addLinkWithoutReversePropagation(StructB, StructC); - Tg.addLinkWithoutReversePropagation(StructC, StructD); - Tg.addLinkWithoutReversePropagation(StructE, StructB); - - boost::add_edge(VertexA, VertexB, G); - boost::add_edge(VertexB, VertexC, G); - boost::add_edge(VertexC, VertexD, G); - boost::add_edge(VertexE, VertexB, G); - - ASSERT_TRUE(boost::isomorphism(G, Tg.G)); - - auto TgEdges = boost::edges(Tg.G); - - int NumberEdge = 0; - - TgEdges = boost::edges(Tg.G); - for (auto It = TgEdges.first; It != TgEdges.second; ++It) { - ++NumberEdge; - - auto Src = boost::source(*It, Tg.G); - auto Target = boost::target(*It, Tg.G); - - ASSERT_TRUE(NumberEdge <= 4); - - ASSERT_TRUE(Src == NodeA || Src == NodeB || Src == NodeC || Src == NodeE); - if (Src == NodeA) { - ASSERT_TRUE(Target == NodeB); - } else if (Src == NodeB) { - ASSERT_TRUE(Target == NodeC); - } else if (Src == NodeC) { - ASSERT_TRUE(Target == NodeD); - } else if (Src == NodeE) { - ASSERT_TRUE(Target == NodeB); - } - } - - ASSERT_TRUE(NumberEdge == 4); - NumberEdge = 0; // NOLINT Avoid stupid mistakes - - // Check that the type are coherent in the graph - ASSERT_TRUE(Tg.G[VertexA].Types.count(StructA)); - ASSERT_TRUE(Tg.G[VertexA].Types.size() == 1); - ASSERT_TRUE(Tg.G[VertexB].Types.count(StructB)); - ASSERT_TRUE(Tg.G[VertexB].Types.size() == 1); - ASSERT_TRUE(Tg.G[VertexC].Types.count(StructC)); - ASSERT_TRUE(Tg.G[VertexC].Types.size() == 1); - ASSERT_TRUE(Tg.G[VertexD].Types.count(StructD)); - ASSERT_TRUE(Tg.G[VertexD].Types.size() == 1); - ASSERT_TRUE(Tg.G[VertexE].Types.count(StructE)); - ASSERT_TRUE(Tg.G[VertexE].Types.size() == 1); - - Tg.reverseTypePropagation(StructC); - - // Check that the type are coherent in the graph - ASSERT_TRUE(Tg.G[VertexA].Types.count(StructA) && - Tg.G[VertexA].Types.count(StructB) && - Tg.G[VertexA].Types.count(StructC)); - ASSERT_TRUE(Tg.G[VertexA].Types.size() == 3); - ASSERT_TRUE(Tg.G[VertexB].Types.count(StructB) && - Tg.G[VertexB].Types.count(StructC)); - ASSERT_TRUE(Tg.G[VertexB].Types.size() == 2); - ASSERT_TRUE(Tg.G[VertexC].Types.count(StructC)); - ASSERT_TRUE(Tg.G[VertexC].Types.size() == 1); - ASSERT_TRUE(Tg.G[VertexD].Types.count(StructD)); - ASSERT_TRUE(Tg.G[VertexD].Types.size() == 1); - ASSERT_TRUE(Tg.G[VertexE].Types.count(StructE) && - Tg.G[VertexE].Types.count(StructB) && - Tg.G[VertexE].Types.count(StructC)); - ASSERT_TRUE(Tg.G[VertexE].Types.size() == 3); -} - -TEST(TypeGraphTest, AddLinkSimple) { - LLVMProjectIRDB IRDB( - {unittest::PathToLLTestFiles + "basic/two_structs_cpp.ll"}); - llvm::Module *M = IRDB.getModule(); - - unsigned int NbStruct = 0; - llvm::StructType *StructA = nullptr; - - llvm::StructType *StructB = nullptr; - - CachedTypeGraph Tg; - CachedTypeGraph::graph_t G; - - for (auto *StructType : M->getIdentifiedStructTypes()) { - if (StructType) { - switch (NbStruct) { - case 0: - StructA = StructType; - break; - case 1: - StructB = StructType; - break; - default: - // NB: Will always fail but serve to understand where the error come - // from - ASSERT_TRUE(NbStruct < 2); - break; - } - - ++NbStruct; - } - } - - ASSERT_TRUE(NbStruct == 2); - ASSERT_TRUE(StructA != nullptr); - ASSERT_TRUE(StructB != nullptr); - - auto NodeA = Tg.addType(StructA); - auto NodeB = Tg.addType(StructB); - Tg.addLink(StructA, StructB); - - auto VertexA = boost::add_vertex(G); - auto VertexB = boost::add_vertex(G); - - boost::add_edge(VertexA, VertexB, G); - - ASSERT_TRUE(boost::isomorphism(G, Tg.G)); - - auto P = edges(Tg.G); - - auto Begin = P.first; - auto End = P.second; - - int NumberEdge = 0; - - for (auto It = Begin; It != End; ++It) { - ++NumberEdge; - - auto Src = boost::source(*It, Tg.G); - auto Target = boost::target(*It, Tg.G); - - ASSERT_TRUE(NumberEdge == 1); - ASSERT_TRUE(Src == NodeA); - ASSERT_TRUE(Target == NodeB); - } - - ASSERT_TRUE(NumberEdge == 1); -} - -TEST(TypeGraphTest, TypeAggregation) { - LLVMProjectIRDB IRDB( - {unittest::PathToLLTestFiles + "basic/seven_structs_cpp.ll"}); - llvm::Module *M = IRDB.getModule(); - - unsigned int NbStruct = 0; - llvm::StructType *StructA = nullptr; - llvm::StructType *StructB = nullptr; - llvm::StructType *StructC = nullptr; - llvm::StructType *StructD = nullptr; - llvm::StructType *StructE = nullptr; - - CachedTypeGraph Tg; - - // Isomorphism to assure that the TypeGraph have the wanted structure - CachedTypeGraph::graph_t G; - - for (auto *StructType : M->getIdentifiedStructTypes()) { - if (StructType) { - switch (NbStruct) { - case 0: - StructA = StructType; - break; - case 1: - StructB = StructType; - break; - case 2: - StructC = StructType; - break; - case 3: - StructD = StructType; - break; - case 4: - StructE = StructType; - break; - case 5: - [[fallthrough]]; - case 6: - break; - default: - // NB: Will always fail but serve to understand where the error come - // from - ASSERT_TRUE(NbStruct < 7); - break; - } - - ++NbStruct; - } - } - - ASSERT_TRUE(NbStruct == 7); - ASSERT_TRUE(StructA != nullptr); - ASSERT_TRUE(StructB != nullptr); - ASSERT_TRUE(StructC != nullptr); - ASSERT_TRUE(StructD != nullptr); - ASSERT_TRUE(StructE != nullptr); - - auto VertexA = boost::add_vertex(G); - auto VertexB = boost::add_vertex(G); - auto VertexC = boost::add_vertex(G); - auto VertexD = boost::add_vertex(G); - auto VertexE = boost::add_vertex(G); - - auto NodeA = Tg.addType(StructA); - auto NodeB = Tg.addType(StructB); - auto NodeC = Tg.addType(StructC); - auto NodeD = Tg.addType(StructD); - auto NodeE = Tg.addType(StructE); - - Tg.addLinkWithoutReversePropagation(StructA, StructB); - Tg.addLinkWithoutReversePropagation(StructB, StructC); - Tg.addLinkWithoutReversePropagation(StructC, StructD); - Tg.addLinkWithoutReversePropagation(StructE, StructB); - - boost::add_edge(VertexA, VertexB, G); - boost::add_edge(VertexB, VertexC, G); - boost::add_edge(VertexC, VertexD, G); - boost::add_edge(VertexE, VertexB, G); - - ASSERT_TRUE(boost::isomorphism(G, Tg.G)); - - auto TgEdges = boost::edges(Tg.G); - - int NumberEdge = 0; - - TgEdges = boost::edges(Tg.G); - for (auto It = TgEdges.first; It != TgEdges.second; ++It) { - ++NumberEdge; - - auto Src = boost::source(*It, Tg.G); - auto Target = boost::target(*It, Tg.G); - - ASSERT_TRUE(NumberEdge <= 4); - - ASSERT_TRUE(Src == NodeA || Src == NodeB || Src == NodeC || Src == NodeE); - if (Src == NodeA) { - ASSERT_TRUE(Target == NodeB); - } else if (Src == NodeB) { - ASSERT_TRUE(Target == NodeC); - } else if (Src == NodeC) { - ASSERT_TRUE(Target == NodeD); - } else if (Src == NodeE) { - ASSERT_TRUE(Target == NodeB); - } - } - - ASSERT_TRUE(NumberEdge == 4); - NumberEdge = 0; // NOLINT Avoid stupid mistakes - - // Check that the type are coherent in the graph - ASSERT_TRUE(Tg.G[VertexA].Types.count(StructA)); - ASSERT_TRUE(Tg.G[VertexA].Types.size() == 1); - ASSERT_TRUE(Tg.G[VertexB].Types.count(StructB)); - ASSERT_TRUE(Tg.G[VertexB].Types.size() == 1); - ASSERT_TRUE(Tg.G[VertexC].Types.count(StructC)); - ASSERT_TRUE(Tg.G[VertexC].Types.size() == 1); - ASSERT_TRUE(Tg.G[VertexD].Types.count(StructD)); - ASSERT_TRUE(Tg.G[VertexD].Types.size() == 1); - ASSERT_TRUE(Tg.G[VertexE].Types.count(StructE)); - ASSERT_TRUE(Tg.G[VertexE].Types.size() == 1); - - Tg.aggregateTypes(); - - // Check that the type are coherent in the graph - ASSERT_TRUE(Tg.G[VertexA].Types.count(StructA) && - Tg.G[VertexA].Types.count(StructB) && - Tg.G[VertexA].Types.count(StructC) && - Tg.G[VertexA].Types.count(StructD)); - ASSERT_TRUE(Tg.G[VertexA].Types.size() == 4); - ASSERT_TRUE(Tg.G[VertexB].Types.count(StructB) && - Tg.G[VertexB].Types.count(StructC) && - Tg.G[VertexB].Types.count(StructD)); - ASSERT_TRUE(Tg.G[VertexB].Types.size() == 3); - ASSERT_TRUE(Tg.G[VertexC].Types.count(StructC) && - Tg.G[VertexC].Types.count(StructD)); - ASSERT_TRUE(Tg.G[VertexC].Types.size() == 2); - ASSERT_TRUE(Tg.G[VertexD].Types.count(StructD)); - ASSERT_TRUE(Tg.G[VertexD].Types.size() == 1); - ASSERT_TRUE(Tg.G[VertexE].Types.count(StructE) && - Tg.G[VertexE].Types.count(StructB) && - Tg.G[VertexE].Types.count(StructC) && - Tg.G[VertexE].Types.count(StructD)); - ASSERT_TRUE(Tg.G[VertexE].Types.size() == 4); -} -} // namespace psr - -int main(int Argc, char **Argv) { - ::testing::InitGoogleTest(&Argc, Argv); - auto Res = RUN_ALL_TESTS(); - llvm::llvm_shutdown(); - return Res; -}