Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Windows support #695

Draft
wants to merge 14 commits into
base: development
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 39 additions & 6 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down Expand Up @@ -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()
Expand Down Expand Up @@ -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()

Expand Down Expand Up @@ -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()
Expand All @@ -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)
Expand Down Expand Up @@ -463,6 +490,12 @@ 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 HINTS ${LLVM_BINARY_DIR} REQUIRED)
find_program(CLANGXX_EXE clang++ HINTS ${LLVM_BINARY_DIR} REQUIRED)
find_program(LLVMOPT_EXE opt HINTS ${LLVM_BINARY_DIR} REQUIRED)

add_subdirectory(test)
endif()

Expand Down
6 changes: 3 additions & 3 deletions cmake/phasar_macros.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -110,18 +110,18 @@ function(generate_ll_file)

# define .ll file generation command
if(${test_code_file_ext} STREQUAL ".cpp")
set(GEN_CMD ${CMAKE_CXX_COMPILER_LAUNCHER} ${CMAKE_CXX_COMPILER})
set(GEN_CMD ${CLANGXX_EXE})
list(APPEND GEN_CMD ${GEN_CXX_FLAGS})
else()
set(GEN_CMD ${CMAKE_C_COMPILER_LAUNCHER} ${CMAKE_C_COMPILER})
set(GEN_CMD ${CLANG_EXE})
list(APPEND GEN_CMD ${GEN_C_FLAGS})
endif()

if(GEN_LL_MEM2REG)
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
Expand Down
1 change: 1 addition & 0 deletions config.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@
#cmakedefine PAMM_FULL

#cmakedefine DYNAMIC_LOG
#cmakedefine PHASAR_HAS_SQLITE3

#endif /* PHASAR_CONFIG_CONFIG_H */
12 changes: 9 additions & 3 deletions include/phasar/ControlFlow/CFGBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@

#include "nlohmann/json.hpp"

#include <type_traits>

#include <llvm/ADT/StringRef.h>

namespace psr {

enum class SpecialMemberFunctionType;
Expand Down Expand Up @@ -119,6 +123,7 @@ template <typename Derived> class CFGBase {
return self().getStatementIdImpl(Inst);
}
[[nodiscard]] decltype(auto) getFunctionName(ByConstRef<f_t> Fun) const {
static_assert(__cplusplus > 201402L);
static_assert(is_string_like_v<decltype(self().getFunctionNameImpl(Fun))>);
return self().getFunctionNameImpl(Fun);
}
Expand All @@ -144,9 +149,10 @@ template <typename Derived> class CFGBase {

template <typename ICF, typename Domain>
// NOLINTNEXTLINE(readability-identifier-naming)
constexpr bool is_cfg_v = is_crtp_base_of_v<CFGBase, ICF>
&&std::is_same_v<typename ICF::n_t, typename Domain::n_t>
&&std::is_same_v<typename ICF::f_t, typename Domain::f_t>;
constexpr bool is_cfg_v =
is_crtp_base_of_v<CFGBase, ICF> &&
std::is_same_v<typename ICF::n_t, typename Domain::n_t> &&
std::is_same_v<typename ICF::f_t, typename Domain::f_t>;
fabianbs96 marked this conversation as resolved.
Show resolved Hide resolved

} // namespace psr

Expand Down
1 change: 0 additions & 1 deletion include/phasar/ControlFlow/CallGraph.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
#include "phasar/Utils/ByRef.h"
#include "phasar/Utils/Logger.h"
#include "phasar/Utils/StableVector.h"
#include "phasar/Utils/Utilities.h"

#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
Expand Down
3 changes: 3 additions & 0 deletions include/phasar/DB.h
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down
35 changes: 17 additions & 18 deletions include/phasar/DataFlow/IfdsIde/EdgeFunction.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,17 +61,17 @@ concept IsEdgeFunction = requires(const T &EF, const EdgeFunction<typename T::l_
{T::compose(CEF, TEEF)} -> std::same_as<EdgeFunction<typename T::l_t>>;
{T::join(CEF, TEEF)} -> std::same_as<EdgeFunction<typename T::l_t>>;
};
// clang-format on
// clang-format on
fabianbs96 marked this conversation as resolved.
Show resolved Hide resolved

#endif

class EdgeFunctionBase {
public:
template <typename ConcreteEF>
static constexpr bool
IsSOOCandidate = sizeof(ConcreteEF) <= sizeof(void *) && // NOLINT
alignof(ConcreteEF) <= alignof(void *) &&
std::is_trivially_copyable_v<ConcreteEF>;
static constexpr bool IsSOOCandidate =
sizeof(ConcreteEF) <= sizeof(void *) && // NOLINT
alignof(ConcreteEF) <= alignof(void *) &&
std::is_trivially_copyable_v<ConcreteEF>;
fabianbs96 marked this conversation as resolved.
Show resolved Hide resolved

protected:
enum class AllocationPolicy {
Expand All @@ -82,7 +82,9 @@ class EdgeFunctionBase {
struct RefCountedBase {
mutable std::atomic_size_t Rc = 0;
};
template <typename T> struct RefCounted : RefCountedBase { T Value; };
template <typename T> struct RefCounted : RefCountedBase {
T Value;
};
fabianbs96 marked this conversation as resolved.
Show resolved Hide resolved

template <typename T> struct CachedRefCounted : RefCounted<T> {
EdgeFunctionSingletonCache<T> *Cache{};
Expand Down Expand Up @@ -427,30 +429,27 @@ class [[clang::trivial_abi]] EdgeFunction final : EdgeFunctionBase {
typename = std::enable_if_t<
!std::is_same_v<EdgeFunction, std::decay_t<ConcreteEF>> &&
IsEdgeFunction<ConcreteEF>>>
[[nodiscard]] friend bool operator==(EdgeFunctionRef<ConcreteEF> LHS,
const EdgeFunction &RHS) noexcept {
if (!RHS.template isa<ConcreteEF>()) {
[[nodiscard]] bool operator==(EdgeFunctionRef<ConcreteEF> RHS) noexcept {
if (!isa<ConcreteEF>()) {
return false;
}
if (LHS.Instance == RHS.EF) {
if (RHS.Instance == EF) {
return true;
}
if constexpr (IsEqualityComparable<ConcreteEF>) {
return *LHS == *getPtr<ConcreteEF>(RHS.EF);
return *RHS == *getPtr<ConcreteEF>(EF);
} else {
return true;
}
}

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

[[nodiscard]] friend bool operator==(const EdgeFunction &EF,
std::nullptr_t) noexcept {
return EF.VTAndHeapAlloc.getOpaqueValue() == nullptr;
Expand Down
18 changes: 11 additions & 7 deletions include/phasar/DataFlow/IfdsIde/EdgeFunctionUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,13 @@ template <typename L> struct AllBottom final {

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

template <typename LL = L,
typename = std::enable_if_t<!HasJoinLatticeTraits<LL>>>
friend bool operator==(const AllBottom<L> &LHS,
const AllBottom<L> &RHS) noexcept {
return LHS.BottomValue == RHS.BottomValue;
if constexpr (HasJoinLatticeTraits<L>) {
return true;
} else {
return LHS.BottomValue == RHS.BottomValue;
}
}
};

Expand Down Expand Up @@ -111,10 +113,12 @@ template <typename L> struct AllTop final {

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

template <typename LL = L,
typename = std::enable_if_t<!HasJoinLatticeTraits<LL>>>
friend bool operator==(const AllTop<L> &LHS, const AllTop<L> &RHS) noexcept {
return LHS.TopValue == RHS.TopValue;
if constexpr (HasJoinLatticeTraits<L>) {
return true;
} else {
return LHS.TopValue == RHS.TopValue;
}
}
};

Expand Down Expand Up @@ -310,7 +314,7 @@ template <typename L, uint8_t N> struct JoinEdgeFunction {
}
};

return DefaultJoinEdgeFunctionComposer{This, SecondFunction};
return DefaultJoinEdgeFunctionComposer{{This, SecondFunction}};
}

[[nodiscard]] static EdgeFunction<l_t>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
3 changes: 2 additions & 1 deletion include/phasar/PhasarLLVM/ControlFlow/LLVMBasedCFG.h
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -86,7 +87,7 @@ template <typename Derived> class LLVMBasedCFGImpl : public CFGBase<Derived> {
[[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;
Expand Down
3 changes: 3 additions & 0 deletions include/phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ class LLVMBasedICFG : public LLVMBasedCFG, public ICFGBase<LLVMBasedICFG> {
struct Builder;

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

static constexpr llvm::StringLiteral GlobalCRuntimeModelName =
"__psrCRuntimeGlobalCtorsModel";

Expand Down
13 changes: 9 additions & 4 deletions include/phasar/PhasarLLVM/DataFlow/IfdsIde/LLVMZeroValue.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,10 @@

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

#include <memory>

namespace llvm {
class Value;
} // namespace llvm
#include <type_traits>

namespace psr {

Expand Down Expand Up @@ -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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<l_t> EdgeFact) {
if (std::holds_alternative<Top>(EdgeFact)) {
Expand Down
6 changes: 3 additions & 3 deletions include/phasar/PhasarLLVM/Pointer/LLVMAliasGraph.h
Original file line number Diff line number Diff line change
Expand Up @@ -182,14 +182,14 @@ class LLVMAliasGraph : public AnalysisPropertiesMixin<LLVMAliasGraph>,

class PointerVertexOrEdgePrinter {
public:
PointerVertexOrEdgePrinter(const graph_t &PAG) : PAG(PAG) {}
PointerVertexOrEdgePrinter(const graph_t &PAG) : PAG(&PAG) {}
template <class VertexOrEdge>
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
Expand Down
Loading
Loading