diff --git a/CMakeLists.txt b/CMakeLists.txt index ab524715d..8f2591a81 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -63,10 +63,18 @@ set(RELEASE_CONFIGURATIONS RELWITHDEBINFO RELEASE CACHE INTERNAL "" FORCE) # TODO: Once available, we may want to use -fextend-lifetimes on Debug- and RelWithDebInfo builds to improve debugging experience # https://reviews.llvm.org/D157613 -string(APPEND CMAKE_CXX_FLAGS " -MP -fstack-protector-strong -ffunction-sections -fdata-sections -pipe") -string(APPEND CMAKE_CXX_FLAGS_DEBUG " -Og -fno-omit-frame-pointer") -string(APPEND CMAKE_CXX_FLAGS_RELWITHDEBINFO " -fno-omit-frame-pointer") -string(APPEND CMAKE_CXX_FLAGS_RELEASE "") + +if (NOT MSVC) + string(APPEND CMAKE_CXX_FLAGS " -MP -fstack-protector-strong -ffunction-sections -fdata-sections -pipe") + string(APPEND CMAKE_CXX_FLAGS_DEBUG " -Og -fno-omit-frame-pointer") + string(APPEND CMAKE_CXX_FLAGS_RELWITHDEBINFO " -fno-omit-frame-pointer") + string(APPEND CMAKE_CXX_FLAGS_RELEASE "") +else() + string(APPEND CMAKE_CXX_FLAGS " /Zc:__cplusplus /bigobj") # /D_ITERATOR_DEBUG_LEVEL=0 /VERBOSE:LIB + if(NOT DEFINED CMAKE_MSVC_RUNTIME_LIBRARY) + set(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreadedDLL) + endif() +endif() option(CMAKE_VISIBILITY_INLINES_HIDDEN "Hide inlined functions from the DSO table (default ON)" ON) @@ -163,6 +171,12 @@ option(PHASAR_DEBUG_LIBDEPS "Debug internal library dependencies (private linkag #option(BUILD_SHARED_LIBS "Build shared libraries (default is ON)" ON) option(PHASAR_BUILD_DYNLIB "Build one fat shared library. Requires BUILD_SHARED_LIBS to be turned OFF (default is OFF)" OFF) +if (BUILD_SHARED_LIBS) + message(STATUS "Build shared libraries") +else() + message(STATUS "Build static libraries") +endif() + if(PHASAR_BUILD_DYNLIB AND BUILD_SHARED_LIBS) message(FATAL_ERROR "PHASAR_BUILD_DYNLIB is incompatible with BUILD_SHARED_LIBS") endif() @@ -214,7 +228,7 @@ endif() # Filesystem if (LLVM_ENABLE_LIBCXX) set(PHASAR_STD_FILESYSTEM c++fs) -else() +elseif(NOT MSVC) set(PHASAR_STD_FILESYSTEM stdc++fs) endif() @@ -278,6 +292,11 @@ add_subdirectory(external/json-schema-validator) if (NOT PHASAR_IN_TREE) set(BUILD_GMOCK OFF) set(INSTALL_GTEST OFF) + + if (MSVC AND CMAKE_MSVC_RUNTIME_LIBRARY MATCHES "DLL$") + set(gtest_force_shared_crt ON) + endif() + add_subdirectory(external/googletest EXCLUDE_FROM_ALL) set(GTEST_INCLUDE_DIR "external/googletest/googletest/include") else() @@ -289,9 +308,17 @@ endif() find_path(SQLITE3_INCLUDE_DIR NAMES sqlite3.h) find_library(SQLITE3_LIBRARY NAMES sqlite3) -option(USE_LLVM_FAT_LIB "Link against libLLVM.so instead of the individual LLVM libraries if possible (default is OFF; always on if BUILD_SHARED_LIBS is ON)" OFF) +if(NOT "${SQLITE3_LIBRARY}" STREQUAL "SQLITE3_LIBRARY-NOTFOUND") + # include_directories(SYSTEM ${SQLITE3_INCLUDE_DIR}) + # link_libraries(${SQLITE3_LIBRARY}) + set(PHASAR_HAS_SQLITE3 ON) +endif() + # LLVM + +option(USE_LLVM_FAT_LIB "Link against libLLVM.so instead of the individual LLVM libraries if possible (default is OFF; always on if BUILD_SHARED_LIBS is ON)" OFF) + if (NOT PHASAR_IN_TREE) # Only search for LLVM if we build out of tree find_package(LLVM 14 REQUIRED CONFIG) @@ -463,6 +490,14 @@ endif() # Build all IR test code if (PHASAR_BUILD_IR) message("Building IR test code") + + message(STATUS "Searching for clang in ${LLVM_BINARY_DIR}") + find_program(CLANG_EXE clang-14 HINTS ${LLVM_BINARY_DIR} REQUIRED) + find_program(LLVMOPT_EXE opt-14 HINTS ${LLVM_BINARY_DIR}) + if(LLVMOPT_EXE STREQUAL "LLVMOPT_EXE-NOTFOUND") + find_program(LLVMOPT_EXE opt HINTS ${LLVM_BINARY_DIR}) + endif() + add_subdirectory(test) endif() diff --git a/cmake/phasar_macros.cmake b/cmake/phasar_macros.cmake index 2c9decf9a..6293fa515 100644 --- a/cmake/phasar_macros.cmake +++ b/cmake/phasar_macros.cmake @@ -109,11 +109,10 @@ function(generate_ll_file) set(GEN_CMD_COMMENT "${GEN_CMD_COMMENT} ${GEN_LL_FILE}") # define .ll file generation command + set(GEN_CMD ${CLANG_EXE}) if(${test_code_file_ext} STREQUAL ".cpp") - set(GEN_CMD ${CMAKE_CXX_COMPILER_LAUNCHER} ${CMAKE_CXX_COMPILER}) list(APPEND GEN_CMD ${GEN_CXX_FLAGS}) else() - set(GEN_CMD ${CMAKE_C_COMPILER_LAUNCHER} ${CMAKE_C_COMPILER}) list(APPEND GEN_CMD ${GEN_C_FLAGS}) endif() @@ -121,7 +120,7 @@ function(generate_ll_file) add_custom_command( OUTPUT ${test_code_ll_file} COMMAND ${GEN_CMD} ${test_code_file_path} -o ${test_code_ll_file} - COMMAND ${CMAKE_CXX_COMPILER_LAUNCHER} opt -mem2reg -S ${test_code_ll_file} -o ${test_code_ll_file} + COMMAND ${LLVMOPT_EXE} -mem2reg -S ${test_code_ll_file} -o ${test_code_ll_file} COMMENT ${GEN_CMD_COMMENT} DEPENDS ${GEN_LL_FILE} VERBATIM diff --git a/config.h.in b/config.h.in index d5df1dd0f..3518ab7bb 100644 --- a/config.h.in +++ b/config.h.in @@ -7,5 +7,6 @@ #cmakedefine PAMM_FULL #cmakedefine DYNAMIC_LOG +#cmakedefine PHASAR_HAS_SQLITE3 #endif /* PHASAR_CONFIG_CONFIG_H */ diff --git a/include/phasar/ControlFlow/CFGBase.h b/include/phasar/ControlFlow/CFGBase.h index 57e358225..094c7c686 100644 --- a/include/phasar/ControlFlow/CFGBase.h +++ b/include/phasar/ControlFlow/CFGBase.h @@ -15,6 +15,10 @@ #include "nlohmann/json.hpp" +#include + +#include + namespace psr { enum class SpecialMemberFunctionType; @@ -119,6 +123,7 @@ template class CFGBase { return self().getStatementIdImpl(Inst); } [[nodiscard]] decltype(auto) getFunctionName(ByConstRef Fun) const { + static_assert(__cplusplus > 201402L); static_assert(is_string_like_v); return self().getFunctionNameImpl(Fun); } diff --git a/include/phasar/ControlFlow/CallGraph.h b/include/phasar/ControlFlow/CallGraph.h index 590b16964..0c6c73eaa 100644 --- a/include/phasar/ControlFlow/CallGraph.h +++ b/include/phasar/ControlFlow/CallGraph.h @@ -13,8 +13,8 @@ #include "phasar/ControlFlow/CallGraphBase.h" #include "phasar/Utils/ByRef.h" #include "phasar/Utils/Logger.h" +#include "phasar/Utils/ScopeExit.h" #include "phasar/Utils/StableVector.h" -#include "phasar/Utils/Utilities.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" diff --git a/include/phasar/DB.h b/include/phasar/DB.h index f77b88f01..e7c8bc262 100644 --- a/include/phasar/DB.h +++ b/include/phasar/DB.h @@ -10,7 +10,10 @@ #ifndef PHASAR_DB_H #define PHASAR_DB_H +#ifdef PHASAR_HAS_SQLITE3 #include "phasar/DB/Hexastore.h" +#endif + #include "phasar/DB/ProjectIRDBBase.h" #include "phasar/DB/Queries.h" diff --git a/include/phasar/DataFlow/IfdsIde/EdgeFunction.h b/include/phasar/DataFlow/IfdsIde/EdgeFunction.h index 72f33565a..837932cfa 100644 --- a/include/phasar/DataFlow/IfdsIde/EdgeFunction.h +++ b/include/phasar/DataFlow/IfdsIde/EdgeFunction.h @@ -427,30 +427,27 @@ class [[clang::trivial_abi]] EdgeFunction final : EdgeFunctionBase { typename = std::enable_if_t< !std::is_same_v> && IsEdgeFunction>> - [[nodiscard]] friend bool operator==(EdgeFunctionRef LHS, - const EdgeFunction &RHS) noexcept { - if (!RHS.template isa()) { + [[nodiscard]] bool operator==(EdgeFunctionRef RHS) noexcept { + if (!isa()) { return false; } - if (LHS.Instance == RHS.EF) { + if (RHS.Instance == EF) { return true; } if constexpr (IsEqualityComparable) { - return *LHS == *getPtr(RHS.EF); + return *RHS == *getPtr(EF); } else { return true; } } - template > && - IsEdgeFunction>> - [[nodiscard]] friend bool - operator==(const EdgeFunction &LHS, - EdgeFunctionRef RHS) noexcept { + template >>> + [[nodiscard]] friend bool operator==(EdgeFunctionRef LHS, + const EdgeFunction &RHS) noexcept { return RHS == LHS; } + [[nodiscard]] friend bool operator==(const EdgeFunction &EF, std::nullptr_t) noexcept { return EF.VTAndHeapAlloc.getOpaqueValue() == nullptr; diff --git a/include/phasar/DataFlow/IfdsIde/EdgeFunctionUtils.h b/include/phasar/DataFlow/IfdsIde/EdgeFunctionUtils.h index 018a7849f..e0a005a66 100644 --- a/include/phasar/DataFlow/IfdsIde/EdgeFunctionUtils.h +++ b/include/phasar/DataFlow/IfdsIde/EdgeFunctionUtils.h @@ -71,11 +71,13 @@ template struct AllBottom final { [[nodiscard]] constexpr bool isConstant() const noexcept { return true; } - template >> friend bool operator==(const AllBottom &LHS, const AllBottom &RHS) noexcept { - return LHS.BottomValue == RHS.BottomValue; + if constexpr (HasJoinLatticeTraits) { + return true; + } else { + return LHS.BottomValue == RHS.BottomValue; + } } }; @@ -111,10 +113,12 @@ template struct AllTop final { [[nodiscard]] constexpr bool isConstant() const noexcept { return true; } - template >> friend bool operator==(const AllTop &LHS, const AllTop &RHS) noexcept { - return LHS.TopValue == RHS.TopValue; + if constexpr (HasJoinLatticeTraits) { + return true; + } else { + return LHS.TopValue == RHS.TopValue; + } } }; @@ -310,7 +314,7 @@ template struct JoinEdgeFunction { } }; - return DefaultJoinEdgeFunctionComposer{This, SecondFunction}; + return DefaultJoinEdgeFunctionComposer{{This, SecondFunction}}; } [[nodiscard]] static EdgeFunction diff --git a/include/phasar/DataFlow/PathSensitivity/ExplodedSuperGraph.h b/include/phasar/DataFlow/PathSensitivity/ExplodedSuperGraph.h index df9d1ec3c..5be664da2 100644 --- a/include/phasar/DataFlow/PathSensitivity/ExplodedSuperGraph.h +++ b/include/phasar/DataFlow/PathSensitivity/ExplodedSuperGraph.h @@ -14,6 +14,7 @@ #include "phasar/Utils/ByRef.h" #include "phasar/Utils/Logger.h" #include "phasar/Utils/Printer.h" +#include "phasar/Utils/ScopeExit.h" #include "phasar/Utils/StableVector.h" #include "phasar/Utils/Utilities.h" diff --git a/include/phasar/PhasarLLVM/ControlFlow/LLVMBasedBackwardICFG.h b/include/phasar/PhasarLLVM/ControlFlow/LLVMBasedBackwardICFG.h index 101718a42..6b93b6982 100644 --- a/include/phasar/PhasarLLVM/ControlFlow/LLVMBasedBackwardICFG.h +++ b/include/phasar/PhasarLLVM/ControlFlow/LLVMBasedBackwardICFG.h @@ -41,15 +41,18 @@ class LLVMBasedBackwardICFG : public LLVMBasedBackwardCFG, } }; +public: + using typename LLVMBasedBackwardCFG::f_t; + using typename LLVMBasedBackwardCFG::n_t; + + LLVMBasedBackwardICFG(LLVMBasedICFG *ForwardICFG); + using CFGBase::print; using ICFGBase::print; using CFGBase::getAsJson; using ICFGBase::getAsJson; -public: - LLVMBasedBackwardICFG(LLVMBasedICFG *ForwardICFG); - private: [[nodiscard]] FunctionRange getAllFunctionsImpl() const; [[nodiscard]] f_t getFunctionImpl(llvm::StringRef Fun) const; diff --git a/include/phasar/PhasarLLVM/ControlFlow/LLVMBasedCFG.h b/include/phasar/PhasarLLVM/ControlFlow/LLVMBasedCFG.h index 2c7ac54cf..76ccee894 100644 --- a/include/phasar/PhasarLLVM/ControlFlow/LLVMBasedCFG.h +++ b/include/phasar/PhasarLLVM/ControlFlow/LLVMBasedCFG.h @@ -14,6 +14,7 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringRef.h" #include "llvm/IR/InstIterator.h" #include "llvm/IR/InstrTypes.h" #include "llvm/IR/Instructions.h" @@ -86,7 +87,7 @@ template class LLVMBasedCFGImpl : public CFGBase { [[nodiscard]] SpecialMemberFunctionType getSpecialMemberFunctionTypeImpl(f_t Fun) const; [[nodiscard]] std::string getStatementIdImpl(n_t Inst) const; - [[nodiscard]] auto getFunctionNameImpl(f_t Fun) const { + [[nodiscard]] llvm::StringRef getFunctionNameImpl(f_t Fun) const { return Fun->getName(); } [[nodiscard]] std::string getDemangledFunctionNameImpl(f_t Fun) const; diff --git a/include/phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h b/include/phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h index f1af71970..a9ff5e04d 100644 --- a/include/phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h +++ b/include/phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h @@ -52,6 +52,9 @@ class LLVMBasedICFG : public LLVMBasedCFG, public ICFGBase { struct Builder; public: + using typename LLVMBasedCFG::f_t; + using typename LLVMBasedCFG::n_t; + static constexpr llvm::StringLiteral GlobalCRuntimeModelName = "__psrCRuntimeGlobalCtorsModel"; diff --git a/include/phasar/PhasarLLVM/DataFlow/IfdsIde/LLVMZeroValue.h b/include/phasar/PhasarLLVM/DataFlow/IfdsIde/LLVMZeroValue.h index ad55a9840..0f0fd41d2 100644 --- a/include/phasar/PhasarLLVM/DataFlow/IfdsIde/LLVMZeroValue.h +++ b/include/phasar/PhasarLLVM/DataFlow/IfdsIde/LLVMZeroValue.h @@ -19,12 +19,10 @@ #include "llvm/ADT/StringRef.h" #include "llvm/IR/GlobalVariable.h" +#include "llvm/IR/Value.h" #include - -namespace llvm { -class Value; -} // namespace llvm +#include namespace psr { @@ -52,10 +50,17 @@ class LLVMZeroValue : public llvm::GlobalVariable { // Do not specify a destructor (at all)! static const LLVMZeroValue *getInstance(); +#ifndef _MSC_VER // NOLINTNEXTLINE(readability-identifier-naming) static constexpr auto isLLVMZeroValue = [](const llvm::Value *V) noexcept { return V == getInstance(); }; +#else + // NOLINTNEXTLINE(readability-identifier-naming) + static bool isLLVMZeroValue(const llvm::Value *V) noexcept { + return V == getInstance(); + } +#endif }; } // namespace psr diff --git a/include/phasar/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEInstInteractionAnalysis.h b/include/phasar/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEInstInteractionAnalysis.h index 9e9972ac4..a07d420d0 100644 --- a/include/phasar/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEInstInteractionAnalysis.h +++ b/include/phasar/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEInstInteractionAnalysis.h @@ -1218,6 +1218,13 @@ class IDEInstInteractionAnalysisT return LLVMZeroValue::isLLVMZeroValue(d); } + // Apparently, a friend function cannot access friends: + // https://stackoverflow.com/a/67773627 + friend llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, + const IIAAKillOrReplaceEF &EF); + friend llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, + const IIAAAddLabelsEF &EF); + static void printEdgeFactImpl(llvm::raw_ostream &OS, ByConstRef EdgeFact) { if (std::holds_alternative(EdgeFact)) { diff --git a/include/phasar/PhasarLLVM/Pointer/LLVMAliasGraph.h b/include/phasar/PhasarLLVM/Pointer/LLVMAliasGraph.h index c266980b1..cf63af047 100644 --- a/include/phasar/PhasarLLVM/Pointer/LLVMAliasGraph.h +++ b/include/phasar/PhasarLLVM/Pointer/LLVMAliasGraph.h @@ -182,14 +182,14 @@ class LLVMAliasGraph : public AnalysisPropertiesMixin, class PointerVertexOrEdgePrinter { public: - PointerVertexOrEdgePrinter(const graph_t &PAG) : PAG(PAG) {} + PointerVertexOrEdgePrinter(const graph_t &PAG) : PAG(&PAG) {} template void operator()(std::ostream &Out, const VertexOrEdge &V) const { - Out << "[label=\"" << PAG[V].getValueAsString() << "\"]"; + Out << "[label=\"" << (*PAG)[V].getValueAsString() << "\"]"; } private: - const graph_t &PAG; + const graph_t *PAG; }; static inline PointerVertexOrEdgePrinter diff --git a/include/phasar/PhasarLLVM/Utils/LLVMShorthands.h b/include/phasar/PhasarLLVM/Utils/LLVMShorthands.h index 21d2df136..dd6aeb385 100644 --- a/include/phasar/PhasarLLVM/Utils/LLVMShorthands.h +++ b/include/phasar/PhasarLLVM/Utils/LLVMShorthands.h @@ -17,9 +17,8 @@ #ifndef PHASAR_PHASARLLVM_UTILS_LLVMSHORTHANDS_H #define PHASAR_PHASARLLVM_UTILS_LLVMSHORTHANDS_H -#include "phasar/Utils/Utilities.h" - #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/SmallVector.h" #include #include @@ -35,6 +34,7 @@ class StoreInst; class BranchInst; class Module; class CallInst; +class Type; } // namespace llvm namespace psr { diff --git a/include/phasar/Utils/DOTGraph.h b/include/phasar/Utils/DOTGraph.h index b16777c9f..a89fe96d6 100644 --- a/include/phasar/Utils/DOTGraph.h +++ b/include/phasar/Utils/DOTGraph.h @@ -18,7 +18,7 @@ #define PHASAR_UTILS_DOTGRAPH_H #include "phasar/Config/Configuration.h" -#include "phasar/Utils/Utilities.h" +#include "phasar/Utils/StringIDLess.h" #include #include diff --git a/include/phasar/Utils/GraphTraits.h b/include/phasar/Utils/GraphTraits.h index be00b4b84..037aba61f 100644 --- a/include/phasar/Utils/GraphTraits.h +++ b/include/phasar/Utils/GraphTraits.h @@ -10,8 +10,8 @@ #ifndef PHASAR_UTILS_GRAPHTRAITS_H #define PHASAR_UTILS_GRAPHTRAITS_H +#include "phasar/Utils/ScopeExit.h" #include "phasar/Utils/TypeTraits.h" -#include "phasar/Utils/Utilities.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/None.h" diff --git a/include/phasar/Utils/ScopeExit.h b/include/phasar/Utils/ScopeExit.h new file mode 100644 index 000000000..7523f2d7e --- /dev/null +++ b/include/phasar/Utils/ScopeExit.h @@ -0,0 +1,40 @@ +/****************************************************************************** + * Copyright (c) 2023 Fabian Schiebel. + * All rights reserved. This program and the accompanying materials are made + * available under the terms of LICENSE.txt. + * + * Contributors: + * Fabian Schiebel and others + *****************************************************************************/ + +#ifndef PHASAR_UTILS_SCOPEEXIT_H +#define PHASAR_UTILS_SCOPEEXIT_H + +#include +#include + +namespace psr { +/// See "https://en.cppreference.com/w/cpp/experimental/scope_exit/scope_exit" +template class scope_exit { // NOLINT +public: + template ()())> + scope_exit(FFn &&F) noexcept(std::is_nothrow_constructible_v) + : F(std::forward(F)) {} + + ~scope_exit() noexcept { F(); } + + scope_exit(const scope_exit &) = delete; + scope_exit(scope_exit &&) = delete; + + scope_exit &operator=(const scope_exit &) = delete; + scope_exit &operator=(scope_exit &&) = delete; + +private: + Fn F; +}; + +template scope_exit(Fn) -> scope_exit; + +} // namespace psr + +#endif // PHASAR_UTILS_SCOPEEXIT_H diff --git a/include/phasar/Utils/StringIDLess.h b/include/phasar/Utils/StringIDLess.h new file mode 100644 index 000000000..9821ea958 --- /dev/null +++ b/include/phasar/Utils/StringIDLess.h @@ -0,0 +1,22 @@ + +/****************************************************************************** + * 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_UTILS_STRINGIDLESS_H_ +#define PHASAR_UTILS_STRINGIDLESS_H_ + +#include + +namespace psr { +struct StringIDLess { + bool operator()(const std::string &LHS, const std::string &RHS) const; +}; +} // namespace psr + +#endif // PHASAR_UTILS_STRINGIDLESS_H_ diff --git a/include/phasar/Utils/Utilities.h b/include/phasar/Utils/Utilities.h index ec4f26cd0..1a4d6acd9 100644 --- a/include/phasar/Utils/Utilities.h +++ b/include/phasar/Utils/Utilities.h @@ -11,6 +11,7 @@ #define PHASAR_UTILS_UTILITIES_H_ #include "phasar/Utils/BitVectorSet.h" +#include "phasar/Utils/StringIDLess.h" #include "phasar/Utils/TypeTraits.h" #include "llvm/ADT/Hashing.h" @@ -153,31 +154,6 @@ void intersectWith(BitVectorSet &Dest, const BitVectorSet &Src) { llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const std::vector &Bits); -struct StringIDLess { - bool operator()(const std::string &LHS, const std::string &RHS) const; -}; - -/// See "https://en.cppreference.com/w/cpp/experimental/scope_exit/scope_exit" -template class scope_exit { // NOLINT -public: - template ()())> - scope_exit(FFn &&F) noexcept(std::is_nothrow_constructible_v) - : F(std::forward(F)) {} - - ~scope_exit() noexcept { F(); } - - scope_exit(const scope_exit &) = delete; - scope_exit(scope_exit &&) = delete; - - scope_exit &operator=(const scope_exit &) = delete; - scope_exit &operator=(scope_exit &&) = delete; - -private: - Fn F; -}; - -template scope_exit(Fn) -> scope_exit; - // Copied from "https://en.cppreference.com/w/cpp/utility/variant/visit" template struct Overloaded : Ts... { using Ts::operator()...; }; diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index cbcfbaa01..e192a44ff 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -42,7 +42,7 @@ add_phasar_library(phasar ${PHASAR_DYNLIB_KIND} phasar_llvm_ifdside phasar_analysis_strategy phasar_controller - LINK_PRIVATE + LINK_PUBLIC ${Boost_LIBRARIES} LLVM_LINK_COMPONENTS Core diff --git a/lib/Config/CMakeLists.txt b/lib/Config/CMakeLists.txt index 455fa8fbf..af5916d38 100644 --- a/lib/Config/CMakeLists.txt +++ b/lib/Config/CMakeLists.txt @@ -3,6 +3,6 @@ file(GLOB_RECURSE CONFIG_SRC *.h *.cpp) add_phasar_library(phasar_config ${CONFIG_SRC} LINKS phasar_utils - LINK_PRIVATE ${Boost_LIBRARIES} + LINK_PUBLIC ${Boost_LIBRARIES} LLVM_LINK_COMPONENTS Support ) diff --git a/lib/DB/CMakeLists.txt b/lib/DB/CMakeLists.txt index d5dbf67e1..7c2af9b61 100644 --- a/lib/DB/CMakeLists.txt +++ b/lib/DB/CMakeLists.txt @@ -1,12 +1,20 @@ -file(GLOB_RECURSE DB_SRC *.h *.cpp) +if(PHASAR_HAS_SQLITE3) + file(GLOB_RECURSE DB_SRC *.h *.cpp) +else() + set(DB_SRC DB.cpp) +endif() add_phasar_library(phasar_db ${DB_SRC} LINKS phasar_passes phasar_utils LLVM_LINK_COMPONENTS Support - LINK_PRIVATE ${SQLITE3_LIBRARY} ) -target_include_directories(phasar_db - PRIVATE ${SQLITE3_INCLUDE_DIR} -) +if(PHASAR_HAS_SQLITE3) + target_link_libraries(phasar_db + PRIVATE ${SQLITE3_LIBRARY} + ) + target_include_directories(phasar_db + PRIVATE ${SQLITE3_INCLUDE_DIR} + ) +endif() diff --git a/lib/DB/DB.cpp b/lib/DB/DB.cpp new file mode 100644 index 000000000..312515073 --- /dev/null +++ b/lib/DB/DB.cpp @@ -0,0 +1 @@ +// dummy, such that phasar_db compiles even if Hexastore is disabled diff --git a/lib/PhasarLLVM/DataFlow/IfdsIde/CMakeLists.txt b/lib/PhasarLLVM/DataFlow/IfdsIde/CMakeLists.txt index 9411bc739..7e605da2e 100644 --- a/lib/PhasarLLVM/DataFlow/IfdsIde/CMakeLists.txt +++ b/lib/PhasarLLVM/DataFlow/IfdsIde/CMakeLists.txt @@ -19,6 +19,6 @@ add_phasar_library(phasar_llvm_ifdside Support Demangle - LINK_PRIVATE + LINK_PUBLIC ${Boost_LIBRARIES} ) diff --git a/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/ExtendedTaintAnalysis/AbstractMemoryLocationFactory.cpp b/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/ExtendedTaintAnalysis/AbstractMemoryLocationFactory.cpp index 6baa82949..c54699729 100644 --- a/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/ExtendedTaintAnalysis/AbstractMemoryLocationFactory.cpp +++ b/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/ExtendedTaintAnalysis/AbstractMemoryLocationFactory.cpp @@ -9,6 +9,7 @@ #include "phasar/PhasarLLVM/DataFlow/IfdsIde/Problems/ExtendedTaintAnalysis/AbstractMemoryLocationFactory.h" +#include "phasar/PhasarLLVM/DataFlow/IfdsIde/Problems/ExtendedTaintAnalysis/AbstractMemoryLocation.h" #include "phasar/Utils/Logger.h" #include "llvm/IR/Instructions.h" diff --git a/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEGeneralizedLCA/EdgeValue.cpp b/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEGeneralizedLCA/EdgeValue.cpp index 9ef9026bb..871beec86 100644 --- a/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEGeneralizedLCA/EdgeValue.cpp +++ b/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEGeneralizedLCA/EdgeValue.cpp @@ -411,10 +411,10 @@ int EdgeValue::compare(const EdgeValue &Lhs, const EdgeValue &Rhs) { int64_t Rhsval; double RhsvalFp; if (Rhs.tryGetInt(Rhsval)) { - return +std::signbit(Lhsval - Rhsval); + return (Lhsval > Rhsval) * 2 - 1; } if (Rhs.tryGetFP(RhsvalFp)) { - return +std::signbit(double(Lhsval) - RhsvalFp); + return (double(Lhsval) > RhsvalFp) * 2 - 1; } break; } @@ -428,7 +428,7 @@ int EdgeValue::compare(const EdgeValue &Lhs, const EdgeValue &Rhs) { RhsvalFp = double(Rhsval); } - return +std::signbit(Lhsval - RhsvalFp); + return (Lhsval > RhsvalFp) * 2 - 1; } break; diff --git a/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/IDELinearConstantAnalysis.cpp b/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/IDELinearConstantAnalysis.cpp index a8aa6e824..aeaed44ed 100644 --- a/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/IDELinearConstantAnalysis.cpp +++ b/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/IDELinearConstantAnalysis.cpp @@ -221,7 +221,7 @@ struct BinOp { // TODO: Optimize Binop::composeWith(BinOp) - return LCAEdgeFunctionComposer{This, SecondFunction}; + return LCAEdgeFunctionComposer{{This, SecondFunction}}; } static EdgeFunction join(EdgeFunctionRef This, diff --git a/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/IFDSUninitializedVariables.cpp b/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/IFDSUninitializedVariables.cpp index 7dea9e963..9c47fa19c 100644 --- a/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/IFDSUninitializedVariables.cpp +++ b/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/IFDSUninitializedVariables.cpp @@ -201,7 +201,7 @@ IFDSUninitializedVariables::getNormalFlowFunction( for (const auto &Operand : Inst->operands()) { const llvm::UndefValue *Undef = llvm::dyn_cast(Operand); - if (Operand == Source || Operand == Undef) { + if (Operand.get() == Source || Operand.get() == Undef) { //---------------------------------------------------------------- // It is not necessary and (from my point of view) not intended to // report a leak on EVERY kind of instruction. diff --git a/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/TypeStateDescriptions/OpenSSLEVPKDFCTXDescription.cpp b/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/TypeStateDescriptions/OpenSSLEVPKDFCTXDescription.cpp index df37f0bcb..4e00d5f67 100644 --- a/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/TypeStateDescriptions/OpenSSLEVPKDFCTXDescription.cpp +++ b/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/TypeStateDescriptions/OpenSSLEVPKDFCTXDescription.cpp @@ -9,6 +9,7 @@ #include "phasar/PhasarLLVM/DataFlow/IfdsIde/Problems/TypeStateDescriptions/OpenSSLEVPKDFCTXDescription.h" +#include "phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h" #include "phasar/PhasarLLVM/DataFlow/IfdsIde/Problems/TypeStateDescriptions/OpenSSLEVPKDFDescription.h" #include "llvm/IR/Instruction.h" diff --git a/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/TypeStateDescriptions/OpenSSLSecureHeapDescription.cpp b/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/TypeStateDescriptions/OpenSSLSecureHeapDescription.cpp index 3c0a90a67..4c464e157 100644 --- a/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/TypeStateDescriptions/OpenSSLSecureHeapDescription.cpp +++ b/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/TypeStateDescriptions/OpenSSLSecureHeapDescription.cpp @@ -9,6 +9,8 @@ #include "phasar/PhasarLLVM/DataFlow/IfdsIde/Problems/TypeStateDescriptions/OpenSSLSecureHeapDescription.h" +#include "phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h" + #include "llvm/ADT/StringSwitch.h" #include "llvm/Support/ErrorHandling.h" diff --git a/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/TypeStateDescriptions/OpenSSLSecureMemoryDescription.cpp b/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/TypeStateDescriptions/OpenSSLSecureMemoryDescription.cpp index 04d8eba6e..d961f3b94 100644 --- a/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/TypeStateDescriptions/OpenSSLSecureMemoryDescription.cpp +++ b/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/TypeStateDescriptions/OpenSSLSecureMemoryDescription.cpp @@ -115,7 +115,8 @@ std::string OpenSSLSecureMemoryDescription::getTypeNameOfInterest() const { set OpenSSLSecureMemoryDescription::getConsumerParamIdx(llvm::StringRef F) const { - if (const auto *It = llvm::find_if( + // NOTE: On MSVC, the array iterator is no pointer! + if (auto It = llvm::find_if( // NOLINT ConsumingFuncs, [&F](const auto &Pair) { return F == Pair.first; }); It != ConsumingFuncs.end()) { return {It->second}; diff --git a/lib/PhasarLLVM/Pointer/CMakeLists.txt b/lib/PhasarLLVM/Pointer/CMakeLists.txt index c189f6153..b4412dee9 100644 --- a/lib/PhasarLLVM/Pointer/CMakeLists.txt +++ b/lib/PhasarLLVM/Pointer/CMakeLists.txt @@ -17,6 +17,6 @@ add_phasar_library(phasar_llvm_pointer Passes Demangle - LINK_PRIVATE + LINK_PUBLIC ${Boost_LIBRARIES} ) diff --git a/lib/PhasarLLVM/Pointer/LLVMAliasGraph.cpp b/lib/PhasarLLVM/Pointer/LLVMAliasGraph.cpp index 5d217fb44..4f5224cbb 100644 --- a/lib/PhasarLLVM/Pointer/LLVMAliasGraph.cpp +++ b/lib/PhasarLLVM/Pointer/LLVMAliasGraph.cpp @@ -217,14 +217,14 @@ void LLVMAliasGraph::computeAliasGraph(llvm::Function *F) { llvm::Type *I1ElTy = llvm::cast(I1->first->getType())->getElementType(); const uint64_t I1Size = I1ElTy->isSized() - ? DL.getTypeStoreSize(I1ElTy) + ? DL.getTypeStoreSize(I1ElTy).getKnownMinSize() : llvm::MemoryLocation::UnknownSize; for (auto I2 = std::next(I1); I2 != MapEnd; ++I2) { llvm::Type *I2ElTy = llvm::cast(I2->first->getType())->getElementType(); - const uint64_t I2Size = I2ElTy->isSized() - ? DL.getTypeStoreSize(I2ElTy) - : llvm::MemoryLocation::UnknownSize; + const uint64_t I2Size = + I2ElTy->isSized() ? DL.getTypeStoreSize(I2ElTy).getKnownMinSize() + : llvm::MemoryLocation::UnknownSize; switch (AA.alias(I1->first, I1Size, I2->first, I2Size)) { case llvm::AliasResult::NoAlias: break; @@ -414,10 +414,10 @@ void LLVMAliasGraph::print(llvm::raw_ostream &OS) const { } void LLVMAliasGraph::printAsDot(llvm::raw_ostream &OS) const { - std::stringstream S; - boost::write_graphviz(S, PAG, makePointerVertexOrEdgePrinter(PAG), - makePointerVertexOrEdgePrinter(PAG)); - OS << S.str(); + // std::stringstream S; + // boost::write_graphviz(S, PAG, makePointerVertexOrEdgePrinter(PAG), + // makePointerVertexOrEdgePrinter(PAG)); + // OS << S.str(); } nlohmann::json LLVMAliasGraph::getAsJson() const { diff --git a/lib/PhasarLLVM/Pointer/LLVMAliasSet.cpp b/lib/PhasarLLVM/Pointer/LLVMAliasSet.cpp index 07902f06c..eaf2958ce 100644 --- a/lib/PhasarLLVM/Pointer/LLVMAliasSet.cpp +++ b/lib/PhasarLLVM/Pointer/LLVMAliasSet.cpp @@ -17,6 +17,7 @@ #include "phasar/Utils/BoxedPointer.h" #include "phasar/Utils/Logger.h" #include "phasar/Utils/NlohmannLogging.h" +#include "phasar/Utils/Utilities.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseSet.h" @@ -322,12 +323,14 @@ static bool mayAlias(llvm::AAResults &AA, const llvm::DataLayout &DL, auto VSize = V->getType()->getPointerElementType()->isSized() ? DL.getTypeStoreSize(V->getType()->getPointerElementType()) + .getKnownMinSize() : llvm::MemoryLocation::UnknownSize; auto RepSize = Rep->getType()->getPointerElementType()->isSized() ? DL.getTypeStoreSize(Rep->getType()->getPointerElementType()) - : llvm::MemoryLocation::UnknownSize; + .getKnownMinSize() + : llvm::TypeSize(llvm::MemoryLocation::UnknownSize, false); if (AA.alias(V, VSize, Rep, RepSize) != llvm::AliasResult::NoAlias) { return true; diff --git a/lib/PhasarLLVM/Pointer/TypeGraphs/CachedTypeGraph.cpp b/lib/PhasarLLVM/Pointer/TypeGraphs/CachedTypeGraph.cpp index 77c7ab869..3f3e15f54 100644 --- a/lib/PhasarLLVM/Pointer/TypeGraphs/CachedTypeGraph.cpp +++ b/lib/PhasarLLVM/Pointer/TypeGraphs/CachedTypeGraph.cpp @@ -66,7 +66,7 @@ CachedTypeGraph::vertex_t CachedTypeGraph::addType(const llvm::StructType *NewType) { std::string Name; if (!NewType->isLiteral()) { - Name = NewType->getName(); + Name = NewType->getName().str(); } else { std::stringstream StrS; StrS << "literal_" << NewType; @@ -123,9 +123,10 @@ bool CachedTypeGraph::addLinkWithoutReversePropagation( } 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))); + // std::ofstream Ofs(Path); + // boost::write_graphviz( + // Ofs, G, boost::make_label_writer(boost::get(&VertexProperties::Name, + // G))); } void CachedTypeGraph::aggregateTypes() { diff --git a/lib/PhasarLLVM/Pointer/TypeGraphs/LazyTypeGraph.cpp b/lib/PhasarLLVM/Pointer/TypeGraphs/LazyTypeGraph.cpp index ee3354128..25e24b1f7 100644 --- a/lib/PhasarLLVM/Pointer/TypeGraphs/LazyTypeGraph.cpp +++ b/lib/PhasarLLVM/Pointer/TypeGraphs/LazyTypeGraph.cpp @@ -75,10 +75,14 @@ bool LazyTypeGraph::addLink(const llvm::StructType *From, } void LazyTypeGraph::printAsDot(const std::string &Path) const { + // TODO: There seems to be a problem with MSVC accessing + // LazyTypeGraph::VertexProperties::Name +#ifndef _MSC_VER std::ofstream Ofs(Path); boost::write_graphviz(Ofs, Graph, boost::make_label_writer(boost::get( &LazyTypeGraph::VertexProperties::Name, Graph))); +#endif } std::set diff --git a/lib/PhasarLLVM/TypeHierarchy/CMakeLists.txt b/lib/PhasarLLVM/TypeHierarchy/CMakeLists.txt index 3c3d86078..f3fc9b7dd 100644 --- a/lib/PhasarLLVM/TypeHierarchy/CMakeLists.txt +++ b/lib/PhasarLLVM/TypeHierarchy/CMakeLists.txt @@ -13,6 +13,6 @@ add_phasar_library(phasar_llvm_typehierarchy Support Analysis - LINK_PRIVATE + LINK_PUBLIC ${Boost_LIBRARIES} ) diff --git a/lib/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.cpp b/lib/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.cpp index 524176343..ee6d727dd 100644 --- a/lib/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.cpp +++ b/lib/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.cpp @@ -397,9 +397,9 @@ nlohmann::json LLVMTypeHierarchy::getAsJson() const { // } void LLVMTypeHierarchy::printAsDot(llvm::raw_ostream &OS) const { - std::stringstream S; - boost::write_graphviz(S, TypeGraph, TypeHierarchyVertexWriter(TypeGraph)); - OS << S.str(); + // std::stringstream S; + // boost::write_graphviz(S, TypeGraph, TypeHierarchyVertexWriter(TypeGraph)); + // OS << S.str(); } void LLVMTypeHierarchy::printAsJson(llvm::raw_ostream &OS) const { diff --git a/lib/Utils/CMakeLists.txt b/lib/Utils/CMakeLists.txt index c10569663..8cd000b72 100644 --- a/lib/Utils/CMakeLists.txt +++ b/lib/Utils/CMakeLists.txt @@ -19,6 +19,7 @@ add_phasar_library(phasar_utils ${PHASAR_STD_FILESYSTEM} LINK_PUBLIC nlohmann_json::nlohmann_json + ${Boost_LIBRARIES} ) set_target_properties(phasar_utils diff --git a/lib/Utils/DOTGraph.cpp b/lib/Utils/DOTGraph.cpp index f745336c2..ee20cc96d 100644 --- a/lib/Utils/DOTGraph.cpp +++ b/lib/Utils/DOTGraph.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include namespace psr { diff --git a/lib/Utils/IO.cpp b/lib/Utils/IO.cpp index dad2e4a70..b016db47d 100644 --- a/lib/Utils/IO.cpp +++ b/lib/Utils/IO.cpp @@ -18,7 +18,6 @@ #include "phasar/Utils/ErrorHandling.h" #include "phasar/Utils/Logger.h" -#include "phasar/Utils/Utilities.h" #include "llvm/ADT/SmallString.h" #include "llvm/Support/MemoryBuffer.h" diff --git a/tools/example-tool/CMakeLists.txt b/tools/example-tool/CMakeLists.txt index e4d397e70..94820e1a5 100644 --- a/tools/example-tool/CMakeLists.txt +++ b/tools/example-tool/CMakeLists.txt @@ -17,6 +17,16 @@ target_link_libraries(myphasartool ${PHASAR_STD_FILESYSTEM} ) +if(USE_LLVM_FAT_LIB) + llvm_config(myphasartool USE_SHARED ${LLVM_LINK_COMPONENTS}) +else() + llvm_config(myphasartool ${LLVM_LINK_COMPONENTS}) +endif() + +if(BUILD_PHASAR_CLANG) + target_link_libraries(myphasartool PRIVATE ${CLANG_LIBRARY}) +endif() + install(TARGETS myphasartool RUNTIME DESTINATION bin ) diff --git a/tools/phasar-cli/phasar-cli.cpp b/tools/phasar-cli/phasar-cli.cpp index 6781e8e4b..5f2223a4d 100644 --- a/tools/phasar-cli/phasar-cli.cpp +++ b/tools/phasar-cli/phasar-cli.cpp @@ -260,7 +260,8 @@ void validateParamModule() { if (!(std::filesystem::exists(ModulePath) && !std::filesystem::is_directory(ModulePath) && (ModulePath.extension() == ".ll" || ModulePath.extension() == ".bc"))) { - llvm::errs() << "LLVM module '" << std::filesystem::canonical(ModulePath) + llvm::errs() << "LLVM module '" + << std::filesystem::canonical(ModulePath).string() << "' does not exist!\n"; exit(1); } @@ -352,7 +353,8 @@ int main(int Argc, const char **Argv) { if (ProjectIdOpt.empty()) { ProjectIdOpt = std::filesystem::path(ModuleOpt.getValue()) .filename() - .replace_extension(); + .replace_extension() + .string(); if (ProjectIdOpt.empty()) { ProjectIdOpt = "default-phasar-project"; } diff --git a/unittests/DB/CMakeLists.txt b/unittests/DB/CMakeLists.txt index d3b224e01..71be20612 100644 --- a/unittests/DB/CMakeLists.txt +++ b/unittests/DB/CMakeLists.txt @@ -1,7 +1,9 @@ -set(DBSources - HexastoreTest.cpp -) -foreach(TEST_SRC ${DBSources}) - add_phasar_unittest(${TEST_SRC}) -endforeach(TEST_SRC) +if(NOT "${SQLITE3_LIBRARY}" STREQUAL "SQLITE3_LIBRARY-NOTFOUND") + set(DBSources + HexastoreTest.cpp + ) + foreach(TEST_SRC ${DBSources}) + add_phasar_unittest(${TEST_SRC}) + endforeach(TEST_SRC) +endif() diff --git a/unittests/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEGeneralizedLCATest.cpp b/unittests/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEGeneralizedLCATest.cpp index 17a74b610..9d4ec4e3b 100644 --- a/unittests/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEGeneralizedLCATest.cpp +++ b/unittests/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEGeneralizedLCATest.cpp @@ -129,9 +129,10 @@ TEST_F(IDEGeneralizedLCATest, StringTestCpp) { std::vector GroundTruth; const auto *LastMainInstruction = getLastInstructionOf(HA->getProjectIRDB().getFunction("main")); - GroundTruth.push_back({{EdgeValue("Hello, World")}, - 3, - std::stoi(getMetaDataID(LastMainInstruction))}); + GroundTruth.push_back( + {{EdgeValue("Hello, World")}, + 3U, + unsigned(std::stoi(getMetaDataID(LastMainInstruction)))}); compareResults(GroundTruth); }