diff --git a/.github/workflows/deploy-docs.yml b/.github/workflows/deploy-docs.yml index 7588c25fd2..f17f92e0e4 100644 --- a/.github/workflows/deploy-docs.yml +++ b/.github/workflows/deploy-docs.yml @@ -28,8 +28,8 @@ jobs: - name: Build Doxygen Docs shell: bash env: - CXX: clang++-15 - CC: clang-15 + CXX: clang++-16 + CC: clang-16 run: | cmake -S . -B build -DPHASAR_BUILD_DOC=ON cmake --build ./build --target doc_doxygen diff --git a/CMakeLists.txt b/CMakeLists.txt index 0cf3198a04..a40a16cb47 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -306,7 +306,7 @@ option(USE_LLVM_FAT_LIB "Link against libLLVM.so instead of the individual LLVM # LLVM if (NOT PHASAR_LLVM_VERSION) - set(PHASAR_LLVM_VERSION 15) + set(PHASAR_LLVM_VERSION 16) endif() include(add_llvm) add_llvm() diff --git a/bootstrap.sh b/bootstrap.sh index 9d0a911acc..7d4aaef49e 100755 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -6,10 +6,10 @@ source ./utils/safeCommandsSet.sh readonly PHASAR_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" PHASAR_INSTALL_DIR="/usr/local/phasar" -LLVM_INSTALL_DIR="/usr/local/llvm-15" +LLVM_INSTALL_DIR="/usr/local/llvm-16" NUM_THREADS=$(nproc) -LLVM_RELEASE=llvmorg-15.0.7 +LLVM_RELEASE=llvmorg-16.0.6 DO_UNIT_TEST=true DO_INSTALL=false BUILD_TYPE=Release diff --git a/cmake/phasar_macros.cmake b/cmake/phasar_macros.cmake index 2bd952852c..d1dbb7bf32 100644 --- a/cmake/phasar_macros.cmake +++ b/cmake/phasar_macros.cmake @@ -82,7 +82,7 @@ function(generate_ll_file) NAMES clang++-${PHASAR_LLVM_VERSION} clang++ HINTS ${binary_hint_paths}) find_program(opt REQUIRED - NAMES opt-${PHASAR_LLVM_VERSION}4 opt + NAMES opt-${PHASAR_LLVM_VERSION} opt HINTS ${binary_hint_paths}) set(IS_VALID_VERSION "") @@ -208,7 +208,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 ${CMAKE_CXX_COMPILER_LAUNCHER} ${opt} -p mem2reg -S ${test_code_ll_file} -o ${test_code_ll_file} COMMENT ${GEN_CMD_COMMENT} DEPENDS ${GEN_LL_FILE} VERBATIM diff --git a/include/phasar/ControlFlow/CallGraphData.h b/include/phasar/ControlFlow/CallGraphData.h index 58393936a9..0e200ebb54 100644 --- a/include/phasar/ControlFlow/CallGraphData.h +++ b/include/phasar/ControlFlow/CallGraphData.h @@ -11,6 +11,7 @@ #define PHASAR_PHASARLLVM_CONTROLFLOW_CALLGRAPHDATA_H #include "llvm/ADT/StringRef.h" +#include "llvm/ADT/Twine.h" #include "llvm/Support/raw_ostream.h" #include diff --git a/include/phasar/DataFlow/IfdsIde/EdgeFunctionUtils.h b/include/phasar/DataFlow/IfdsIde/EdgeFunctionUtils.h index 72c4aa1a3f..906cde4e2c 100644 --- a/include/phasar/DataFlow/IfdsIde/EdgeFunctionUtils.h +++ b/include/phasar/DataFlow/IfdsIde/EdgeFunctionUtils.h @@ -352,7 +352,7 @@ template struct JoinEdgeFunction { if (const auto *Join = llvm::dyn_cast(EF)) { return {Join->OtherEF, Join->Seed}; } - return {llvm::makeArrayRef(EF), JLattice::top()}; + return {llvm::ArrayRef(EF), JLattice::top()}; }; auto [LVec, LSeed] = GetEFArrayAndSeed(LHS); diff --git a/include/phasar/PhasarLLVM/DB/LLVMProjectIRDB.h b/include/phasar/PhasarLLVM/DB/LLVMProjectIRDB.h index 03b6c03ea8..eab3e27f22 100644 --- a/include/phasar/PhasarLLVM/DB/LLVMProjectIRDB.h +++ b/include/phasar/PhasarLLVM/DB/LLVMProjectIRDB.h @@ -46,8 +46,17 @@ class LLVMProjectIRDB : public ProjectIRDBBase { /// Reads and parses the given LLVM IR file and owns the resulting IR Module. /// If an error occurs, an error message is written to stderr and subsequent /// calls to isValid() return false. + explicit LLVMProjectIRDB(const llvm::Twine &IRFileName); + + /// Reads and parses the given LLVM IR file and owns the resulting IR Module. + /// If an error occurs, an error message is written to stderr and subsequent + /// calls to isValid() return false. + [[deprecated("When moving to the next LLVM version, opaque pointers support " + "is removed completely. Please use one of the other " + "constructors of LLVMProjectIRDB.")]] explicit LLVMProjectIRDB(const llvm::Twine &IRFileName, - bool EnableOpaquePointers = LLVM_VERSION_MAJOR > 14); + bool EnableOpaquePointers); + /// Initializes the new ProjectIRDB with the given IR Module _without_ taking /// ownership. The module is optionally being preprocessed. /// @@ -69,8 +78,16 @@ class LLVMProjectIRDB : public ProjectIRDBBase { /// Parses the given LLVM IR file and owns the resulting IR Module. /// If an error occurs, an error message is written to stderr and subsequent /// calls to isValid() return false. + explicit LLVMProjectIRDB(llvm::MemoryBufferRef Buf); + + /// Parses the given LLVM IR file and owns the resulting IR Module. + /// If an error occurs, an error message is written to stderr and subsequent + /// calls to isValid() return false. + [[deprecated("When moving to the next LLVM version, opaque pointers support " + "is removed completely. Please use one of the other " + "constructors of LLVMProjectIRDB.")]] explicit LLVMProjectIRDB(llvm::MemoryBufferRef Buf, - bool EnableOpaquePointers = LLVM_VERSION_MAJOR > 14); + bool EnableOpaquePointers); LLVMProjectIRDB(const LLVMProjectIRDB &) = delete; LLVMProjectIRDB &operator=(const LLVMProjectIRDB &) = delete; @@ -98,8 +115,13 @@ class LLVMProjectIRDB : public ProjectIRDBBase { llvm::LLVMContext &Ctx) noexcept; [[nodiscard]] static llvm::ErrorOr - load(const llvm::Twine &IRFileName, - bool EnableOpaquePointers = LLVM_VERSION_MAJOR > 14); + load(const llvm::Twine &IRFileName); + + [[deprecated("When moving to the next LLVM version, opaque pointers support " + "is removed completely. Please use one of the other " + "constructors of LLVMProjectIRDB.")]] [[nodiscard]] + static llvm::ErrorOr load(const llvm::Twine &IRFileName, + bool EnableOpaquePointers); /// Also use the const overload using ProjectIRDBBase::getFunction; @@ -172,7 +194,7 @@ class LLVMProjectIRDB : public ProjectIRDBBase { [[nodiscard]] auto getAllInstructionsImpl() const noexcept { return llvm::map_range( - llvm::makeArrayRef(IdToInst).drop_front(IdOffset), + llvm::ArrayRef(IdToInst).drop_front(IdOffset), [](const llvm::Value *V) { return llvm::cast(V); }); } diff --git a/include/phasar/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEFeatureTaintAnalysis.h b/include/phasar/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEFeatureTaintAnalysis.h index b021f7b5af..d3c525ed6a 100644 --- a/include/phasar/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEFeatureTaintAnalysis.h +++ b/include/phasar/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEFeatureTaintAnalysis.h @@ -22,8 +22,8 @@ #include "phasar/Utils/TypeTraits.h" #include "llvm/ADT/FunctionExtras.h" -#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallBitVector.h" +#include "llvm/ADT/bit.h" #include #include @@ -48,7 +48,7 @@ struct IDEFeatureTaintEdgeFact { } #endif - llvm::SmallBitVector Ret(llvm::findLastSet(Bits) + 1); + llvm::SmallBitVector Ret(llvm::bit_width(Bits)); Ret.setBitsInMask((const uint32_t *)&Bits, sizeof(Bits)); return Ret; } @@ -62,7 +62,7 @@ struct IDEFeatureTaintEdgeFact { explicit IDEFeatureTaintEdgeFact() noexcept { Taints.invalid(); } void unionWith(uintptr_t Facts) { - auto RequiredSize = llvm::findLastSet(Facts) + 1; + size_t RequiredSize = llvm::bit_width(Facts); if (RequiredSize > Taints.size()) { Taints.resize(RequiredSize); } @@ -247,7 +247,7 @@ class FeatureTaintGenerator { FeatureTaintGenerator(EdgeFactGenerator &&EFGen) : FeatureTaintGenerator( [EFGen](InstOrGlobal IG) { - return !llvm::empty(std::invoke(EFGen, IG)); + return !std::empty(std::invoke(EFGen, IG)); }, std::forward(EFGen)) {} diff --git a/include/phasar/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEGeneralizedLCA/EdgeValue.h b/include/phasar/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEGeneralizedLCA/EdgeValue.h index 783698c91c..56a7e86f9b 100644 --- a/include/phasar/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEGeneralizedLCA/EdgeValue.h +++ b/include/phasar/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEGeneralizedLCA/EdgeValue.h @@ -18,6 +18,7 @@ #include "llvm/Support/raw_os_ostream.h" #include "llvm/Support/raw_ostream.h" +#include #include namespace psr::glca { diff --git a/include/phasar/PhasarLLVM/HelperAnalyses.h b/include/phasar/PhasarLLVM/HelperAnalyses.h index c3287ffe94..63b9044444 100644 --- a/include/phasar/PhasarLLVM/HelperAnalyses.h +++ b/include/phasar/PhasarLLVM/HelperAnalyses.h @@ -15,6 +15,8 @@ #include "phasar/PhasarLLVM/HelperAnalysisConfig.h" #include "phasar/PhasarLLVM/Pointer/LLVMAliasSetData.h" +#include "llvm/ADT/Twine.h" + #include #include #include diff --git a/include/phasar/PhasarLLVM/Pointer/LLVMAliasSetData.h b/include/phasar/PhasarLLVM/Pointer/LLVMAliasSetData.h index d895741ad2..282530f2dc 100644 --- a/include/phasar/PhasarLLVM/Pointer/LLVMAliasSetData.h +++ b/include/phasar/PhasarLLVM/Pointer/LLVMAliasSetData.h @@ -10,6 +10,7 @@ #ifndef PHASAR_PHASARLLVM_TYPEHIERARCHY_LLVMALIASSETDATA_H #define PHASAR_PHASARLLVM_TYPEHIERARCHY_LLVMALIASSETDATA_H +#include "llvm/ADT/Twine.h" #include "llvm/Support/raw_ostream.h" #include diff --git a/include/phasar/PhasarLLVM/TypeHierarchy/LLVMVFTableData.h b/include/phasar/PhasarLLVM/TypeHierarchy/LLVMVFTableData.h index e3997d9f53..c6ed7bdaa1 100644 --- a/include/phasar/PhasarLLVM/TypeHierarchy/LLVMVFTableData.h +++ b/include/phasar/PhasarLLVM/TypeHierarchy/LLVMVFTableData.h @@ -10,6 +10,7 @@ #ifndef PHASAR_PHASARLLVM_TYPEHIERARCHY_LLVMVFTABLEDATA_H_ #define PHASAR_PHASARLLVM_TYPEHIERARCHY_LLVMVFTABLEDATA_H_ +#include "llvm/ADT/Twine.h" #include "llvm/Support/raw_ostream.h" #include diff --git a/include/phasar/Utils/AdjacencyList.h b/include/phasar/Utils/AdjacencyList.h index b69abe74cf..4c4a29033a 100644 --- a/include/phasar/Utils/AdjacencyList.h +++ b/include/phasar/Utils/AdjacencyList.h @@ -10,13 +10,13 @@ #ifndef PHASAR_UTILS_ADJACENCYLIST_H #define PHASAR_UTILS_ADJACENCYLIST_H +#include "phasar/Utils/EmptyBaseOptimizationUtils.h" #include "phasar/Utils/GraphTraits.h" #include "phasar/Utils/IotaIterator.h" #include "phasar/Utils/RepeatIterator.h" #include "phasar/Utils/Utilities.h" #include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/None.h" #include "llvm/ADT/SmallVector.h" #include @@ -31,7 +31,7 @@ template struct AdjacencyList { llvm::SmallVector Roots{}; }; -template struct AdjacencyList { +template struct AdjacencyList { llvm::SmallVector, 0> Adj{}; llvm::SmallVector Roots{}; }; @@ -54,7 +54,7 @@ struct GraphTraits> { /// /// \returns The vertex-descriptor for the newly created node template >> + typename = std::enable_if_t>> static vertex_t addNode(graph_type &G, TT &&Val) { assert(G.Adj.size() == G.Nodes.size()); @@ -68,8 +68,8 @@ struct GraphTraits> { /// /// \returns The vertex-descriptor for the newly created node template >> - static vertex_t addNode(graph_type &G, llvm::NoneType /*Val*/ = llvm::None) { + typename = std::enable_if_t>> + static vertex_t addNode(graph_type &G, EmptyType /*Val*/ = {}) { auto Ret = G.Adj.size(); G.Adj.emplace_back(); return Ret; @@ -79,7 +79,7 @@ struct GraphTraits> { /// as root multiple times static void addRoot(graph_type &G, vertex_t Vtx) { assert(Vtx < G.Adj.size()); - if constexpr (!std::is_same_v) { + if constexpr (!std::is_same_v) { assert(G.Adj.size() == G.Nodes.size()); } G.Roots.push_back(Vtx); @@ -87,7 +87,7 @@ struct GraphTraits> { /// Gets a range of all root nodes of graph G static llvm::ArrayRef roots(const graph_type &G) noexcept { - if constexpr (!std::is_same_v) { + if constexpr (!std::is_same_v) { assert(G.Adj.size() == G.Nodes.size()); } return G.Roots; @@ -99,7 +99,7 @@ struct GraphTraits> { /// source-node, call dedupOutEdges() static void addEdge(graph_type &G, vertex_t From, edge_t To) { assert(From < G.Adj.size()); - if constexpr (!std::is_same_v) { + if constexpr (!std::is_same_v) { assert(G.Adj.size() == G.Nodes.size()); } G.Adj[From].push_back(std::move(To)); @@ -109,7 +109,7 @@ struct GraphTraits> { static llvm::ArrayRef outEdges(const graph_type &G, vertex_t Vtx) noexcept { assert(Vtx < G.Adj.size()); - if constexpr (!std::is_same_v) { + if constexpr (!std::is_same_v) { assert(G.Adj.size() == G.Nodes.size()); } return G.Adj[Vtx]; @@ -118,7 +118,7 @@ struct GraphTraits> { /// Gets the number of edges outgoing from node Vtx in graph G static size_t outDegree(const graph_type &G, vertex_t Vtx) noexcept { assert(Vtx < G.Adj.size()); - if constexpr (!std::is_same_v) { + if constexpr (!std::is_same_v) { assert(G.Adj.size() == G.Nodes.size()); } return G.Adj[Vtx].size(); @@ -128,7 +128,7 @@ struct GraphTraits> { /// based on operator< and operator== of the edge_t type static void dedupOutEdges(graph_type &G, vertex_t Vtx) noexcept { assert(Vtx < G.Adj.size()); - if constexpr (!std::is_same_v) { + if constexpr (!std::is_same_v) { assert(G.Adj.size() == G.Nodes.size()); } auto &OutEdges = G.Adj[Vtx]; @@ -139,28 +139,28 @@ struct GraphTraits> { /// Gets a const range of all nodes in graph G template >> + typename = std::enable_if_t>> static llvm::ArrayRef nodes(const graph_type &G) noexcept { assert(G.Adj.size() == G.Nodes.size()); return G.Nodes; } /// Gets a mutable range of all nodes in graph G template >> + typename = std::enable_if_t>> static llvm::MutableArrayRef nodes(graph_type &G) noexcept { assert(G.Adj.size() == G.Nodes.size()); return G.Nodes; } /// Gets a range of all nodes in graph G template >> + typename = std::enable_if_t>> static RepeatRangeType nodes(const graph_type &G) noexcept { - return repeat(llvm::None, G.Adj.size()); + return repeat({}, G.Adj.size()); } /// Gets a range of vertex-descriptors for all nodes in graph G static auto vertices(const graph_type &G) noexcept { - if constexpr (!std::is_same_v) { + if constexpr (!std::is_same_v) { assert(G.Adj.size() == G.Nodes.size()); } return psr::iota(vertex_t(0), G.Adj.size()); @@ -168,7 +168,7 @@ struct GraphTraits> { /// Gets the node-tag for node Vtx in graph G. Vtx must be part of G template >> + typename = std::enable_if_t>> static const value_type &node(const graph_type &G, vertex_t Vtx) noexcept { assert(Vtx < G.Nodes.size()); assert(G.Adj.size() == G.Nodes.size()); @@ -176,7 +176,7 @@ struct GraphTraits> { } /// Gets the node-tag for node Vtx in graph G. Vtx must be part of G template >> + typename = std::enable_if_t>> static value_type &node(graph_type &G, vertex_t Vtx) noexcept { assert(Vtx < G.Nodes.size()); assert(G.Adj.size() == G.Nodes.size()); @@ -185,16 +185,16 @@ struct GraphTraits> { /// Gets the node-tag for node Vtx in graph G. Vtx must be part of G template >> - static llvm::NoneType node([[maybe_unused]] const graph_type &G, - [[maybe_unused]] vertex_t Vtx) noexcept { + typename = std::enable_if_t>> + static EmptyType node([[maybe_unused]] const graph_type &G, + [[maybe_unused]] vertex_t Vtx) noexcept { assert(Vtx < G.Adj.size()); - return llvm::None; + return {}; } /// Gets the number of nodes in graph G static size_t size(const graph_type &G) noexcept { - if constexpr (!std::is_same_v) { + if constexpr (!std::is_same_v) { assert(G.Adj.size() == G.Nodes.size()); } return G.Adj.size(); @@ -202,7 +202,7 @@ struct GraphTraits> { /// Gets the number of nodes in graph G that are marked as root static size_t roots_size(const graph_type &G) noexcept { // NOLINT - if constexpr (!std::is_same_v) { + if constexpr (!std::is_same_v) { assert(G.Adj.size() == G.Nodes.size()); } return G.Roots.size(); @@ -210,7 +210,7 @@ struct GraphTraits> { /// Pre-allocates space to hold up to Capacity nodes static void reserve(graph_type &G, size_t Capacity) { - if constexpr (!std::is_same_v) { + if constexpr (!std::is_same_v) { assert(G.Adj.size() == G.Nodes.size()); G.Nodes.reserve(Capacity); } @@ -225,7 +225,7 @@ struct GraphTraits> { static bool pop(graph_type &G, vertex_t Vtx) { if (Vtx == G.Adj.size() - 1) { G.Adj.pop_back(); - if constexpr (!std::is_same_v) { + if constexpr (!std::is_same_v) { G.Nodes.pop_back(); } return true; @@ -250,9 +250,7 @@ struct GraphTraits> { } /// Gets the weight associated with the given edge - static llvm::NoneType weight(edge_t /*unused*/) noexcept { - return llvm::None; - } + static EmptyType weight(edge_t /*unused*/) noexcept { return {}; } /// Removes the edge denoted by It outgoing from source-vertex Vtx from the /// graph G. This function is not required by the is_graph_trait concept. @@ -262,7 +260,7 @@ struct GraphTraits> { static edge_iterator removeEdge(graph_type &G, vertex_t Vtx, edge_iterator It) noexcept { assert(Vtx < G.Adj.size()); - if constexpr (!std::is_same_v) { + if constexpr (!std::is_same_v) { assert(G.Adj.size() == G.Nodes.size()); } assert(G.Adj[Vtx].begin() <= It && It < G.Adj[Vtx].end()); @@ -279,7 +277,7 @@ struct GraphTraits> { /// \returns A roots_iterator directly following It that should be used to /// continue iteration instead of std::next(It) static roots_iterator removeRoot(graph_type &G, roots_iterator It) noexcept { - if constexpr (!std::is_same_v) { + if constexpr (!std::is_same_v) { assert(G.Adj.size() == G.Nodes.size()); } assert(G.Roots.begin() <= It && It < G.Roots.end()); diff --git a/include/phasar/Utils/GraphTraits.h b/include/phasar/Utils/GraphTraits.h index de96b9cc20..eb120608c1 100644 --- a/include/phasar/Utils/GraphTraits.h +++ b/include/phasar/Utils/GraphTraits.h @@ -12,7 +12,6 @@ #include "phasar/Utils/Utilities.h" -#include "llvm/ADT/None.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/raw_ostream.h" @@ -55,36 +54,36 @@ concept is_graph_trait = requires(typename GraphTrait::graph_type &graph, { GraphTrait::Invalid } -> std::convertible_to; { GraphTrait::addNode(graph, val) - } -> std::convertible_to; - {GraphTrait::addEdge(graph, vtx, edge)}; + } -> std::convertible_to; + { GraphTrait::addEdge(graph, vtx, edge) }; { GraphTrait::outEdges(cgraph, vtx) - } -> psr::is_iterable_over_v; + } -> psr::is_iterable_over_v; { GraphTrait::outDegree(cgraph, vtx) } -> std::convertible_to; - {GraphTrait::dedupOutEdges(graph, vtx)}; + { GraphTrait::dedupOutEdges(graph, vtx) }; { GraphTrait::nodes(cgraph) - } -> psr::is_iterable_over_v; + } -> psr::is_iterable_over_v; { GraphTrait::vertices(cgraph) - } -> psr::is_iterable_over_v; + } -> psr::is_iterable_over_v; { GraphTrait::node(cgraph, vtx) - } -> std::convertible_to; + } -> std::convertible_to; { GraphTrait::size(cgraph) } -> std::convertible_to; - {GraphTrait::addRoot(graph, vtx)}; + { GraphTrait::addRoot(graph, vtx) }; { GraphTrait::roots(cgraph) - } -> psr::is_iterable_over_v; + } -> psr::is_iterable_over_v; { GraphTrait::pop(graph, vtx) } -> std::same_as; { GraphTrait::roots_size(cgraph) } -> std::convertible_to; { GraphTrait::target(edge) - } -> std::convertible_to; + } -> std::convertible_to; { GraphTrait::withEdgeTarget(edge, vtx) - } -> std::convertible_to; - {GraphTrait::weight(edge)}; + } -> std::convertible_to; + { GraphTrait::weight(edge) }; }; template @@ -94,22 +93,23 @@ concept is_graph = requires(Graph g) { }; template -concept is_reservable_graph_trait_v = is_graph_trait && - requires(typename GraphTrait::graph_type &g) { - {GraphTrait::reserve(g, size_t(0))}; -}; +concept is_reservable_graph_trait_v = + is_graph_trait && requires(typename GraphTrait::graph_type &g) { + { GraphTrait::reserve(g, size_t(0)) }; + }; template -concept is_removable_graph_trait_v = is_graph_trait && +concept is_removable_graph_trait_v = + is_graph_trait && requires(typename GraphTrait::graph_type &g, typename GraphTrait::vertex_t vtx, typename GraphTrait::edge_iterator edge_it, typename GraphTrait::roots_iterator root_it) { - typename GraphTrait::edge_iterator; - typename GraphTrait::roots_iterator; - {GraphTrait::removeEdge(g, vtx, edge_it)}; - {GraphTrait::removeRoot(g, root_it)}; -}; + typename GraphTrait::edge_iterator; + typename GraphTrait::roots_iterator; + { GraphTrait::removeEdge(g, vtx, edge_it) }; + { GraphTrait::removeRoot(g, root_it) }; + }; #else namespace detail { @@ -155,7 +155,7 @@ static constexpr bool is_removable_graph_trait_v = template std::decay_t reverseGraph(GraphTy &&G) #if __cplusplus >= 202002L - requires is_graph + requires is_graph #endif { std::decay_t Ret; @@ -193,7 +193,7 @@ template void printGraph(const GraphTy &G, llvm::raw_ostream &OS, llvm::StringRef Name = "", NodeTransform NodeToString = {}) #if __cplusplus >= 202002L - requires is_graph + requires is_graph #endif { using traits_t = GraphTraits; @@ -205,8 +205,7 @@ void printGraph(const GraphTy &G, llvm::raw_ostream &OS, for (size_t I = 0; I < Sz; ++I) { OS << I; - if constexpr (!std::is_same_v) { + if constexpr (!std::is_empty_v) { OS << "[label=\""; OS.write_escaped(std::invoke(NodeToString, traits_t::node(G, I))); OS << "\"]"; diff --git a/lib/ControlFlow/CallGraphAnalysisType.cpp b/lib/ControlFlow/CallGraphAnalysisType.cpp index e244e28a86..52c1c1014f 100644 --- a/lib/ControlFlow/CallGraphAnalysisType.cpp +++ b/lib/ControlFlow/CallGraphAnalysisType.cpp @@ -11,6 +11,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSwitch.h" +#include "llvm/Support/ErrorHandling.h" std::string psr::toString(CallGraphAnalysisType CGA) { switch (CGA) { diff --git a/lib/PhasarLLVM/DB/LLVMProjectIRDB.cpp b/lib/PhasarLLVM/DB/LLVMProjectIRDB.cpp index 27c35db533..a6330a0b25 100644 --- a/lib/PhasarLLVM/DB/LLVMProjectIRDB.cpp +++ b/lib/PhasarLLVM/DB/LLVMProjectIRDB.cpp @@ -23,6 +23,7 @@ namespace psr { +[[deprecated]] static void setOpaquePointersForCtx(llvm::LLVMContext &Ctx, bool Enable) { #if LLVM_VERSION_MAJOR >= 15 && LLVM_VERSION_MAJOR < 17 if (!Enable) { @@ -137,17 +138,22 @@ LLVMProjectIRDB::getParsedIRModuleOrNull(const llvm::Twine &IRFileName, } llvm::ErrorOr -LLVMProjectIRDB::load(const llvm::Twine &IRFileName, - bool EnableOpaquePointers) { - auto FileOrErr = - llvm::MemoryBuffer::getFileOrSTDIN(IRFileName, /*IsText=*/true); - if (!FileOrErr) { - return FileOrErr.getError(); +LLVMProjectIRDB::load(const llvm::Twine &IRFileName) { + auto Ctx = std::make_unique(); + auto M = getParsedIRModuleOrErr(IRFileName, *Ctx); + if (!M) { + return M.getError(); } + return LLVMProjectIRDB(std::move(*M), std::move(Ctx)); +} + +llvm::ErrorOr +LLVMProjectIRDB::load(const llvm::Twine &IRFileName, + bool EnableOpaquePointers) { auto Ctx = std::make_unique(); - auto M = getParsedIRModuleOrErr(**FileOrErr, *Ctx); + auto M = getParsedIRModuleOrErr(IRFileName, *Ctx); if (!M) { return M.getError(); } @@ -155,6 +161,20 @@ LLVMProjectIRDB::load(const llvm::Twine &IRFileName, return LLVMProjectIRDB(std::move(*M), std::move(Ctx), EnableOpaquePointers); } +LLVMProjectIRDB::LLVMProjectIRDB(const llvm::Twine &IRFileName) + : Ctx(new llvm::LLVMContext()) { + auto M = getParsedIRModuleOrErr(IRFileName, *Ctx); + + if (!M) { + return; + } + + auto *NonConst = M->get(); + Mod = std::move(M.get()); + ModulesToSlotTracker::setMSTForModule(Mod.get()); + preprocessModule(NonConst); +} + LLVMProjectIRDB::LLVMProjectIRDB(const llvm::Twine &IRFileName, bool EnableOpaquePointers) : Ctx(new llvm::LLVMContext()) { @@ -258,6 +278,18 @@ LLVMProjectIRDB::LLVMProjectIRDB(std::unique_ptr Mod, this->Ctx = std::move(Ctx); } +LLVMProjectIRDB::LLVMProjectIRDB(llvm::MemoryBufferRef Buf) + : Ctx(new llvm::LLVMContext()) { + auto M = getParsedIRModuleOrErr(Buf, *Ctx); + if (!M) { + return; + } + + auto *NonConst = M->get(); + Mod = std::move(M.get()); + ModulesToSlotTracker::setMSTForModule(Mod.get()); + preprocessModule(NonConst); +} LLVMProjectIRDB::LLVMProjectIRDB(llvm::MemoryBufferRef Buf, bool EnableOpaquePointers) : Ctx(new llvm::LLVMContext()) { diff --git a/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/ExtendedTaintAnalysis/AbstractMemoryLocation.cpp b/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/ExtendedTaintAnalysis/AbstractMemoryLocation.cpp index da9898ee05..b01b8483fa 100644 --- a/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/ExtendedTaintAnalysis/AbstractMemoryLocation.cpp +++ b/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/ExtendedTaintAnalysis/AbstractMemoryLocation.cpp @@ -37,8 +37,7 @@ AbstractMemoryLocationImpl::AbstractMemoryLocationImpl( AbstractMemoryLocationImpl::AbstractMemoryLocationImpl( const llvm::Value *Baseptr, llvm::SmallVectorImpl &&Offsets, unsigned Lifetime) noexcept - : AbstractMemoryLocationImpl(Baseptr, llvm::makeArrayRef(Offsets), - Lifetime) {} + : AbstractMemoryLocationImpl(Baseptr, llvm::ArrayRef(Offsets), Lifetime) {} AbstractMemoryLocationImpl::AbstractMemoryLocationImpl( const llvm::Value *Baseptr, llvm::ArrayRef Offsets, unsigned Lifetime) noexcept @@ -52,7 +51,7 @@ bool AbstractMemoryLocationImpl::isZero() const { } llvm::ArrayRef AbstractMemoryLocationImpl::offsets() const { - return llvm::makeArrayRef(this->getTrailingObjects(), NumOffsets); + return llvm::ArrayRef(this->getTrailingObjects(), NumOffsets); } auto AbstractMemoryLocationImpl::computeOffset( diff --git a/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEExtendedTaintAnalysis.cpp b/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEExtendedTaintAnalysis.cpp index f1b5852f50..dde9cf8dec 100644 --- a/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEExtendedTaintAnalysis.cpp +++ b/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEExtendedTaintAnalysis.cpp @@ -350,7 +350,7 @@ IDEExtendedTaintAnalysis::getCallFlowFunction(n_t CallStmt, f_t DestFun) { /// padding for now. } Offs += - ptrdiff_t(DL.getTypeAllocSize(It->get()->getType()).getFixedSize()); + ptrdiff_t(DL.getTypeAllocSize(It->get()->getType()).getFixedValue()); } #ifdef XTAINT_DIAGNOSTICS allTaintedValues.insert(ret.begin(), ret.end()); diff --git a/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEGeneralizedLCA/EdgeValue.cpp b/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEGeneralizedLCA/EdgeValue.cpp index 93e4089eb3..c1f05d4b93 100644 --- a/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEGeneralizedLCA/EdgeValue.cpp +++ b/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEGeneralizedLCA/EdgeValue.cpp @@ -191,20 +191,6 @@ bool EdgeValue::isString() const { return VariantType == String; } EdgeValue::Type EdgeValue::getKind() const { return VariantType; } -EdgeValue::operator bool() { - switch (VariantType) { - case Integer: - return !std::get(ValVariant).isNullValue(); - case FloatingPoint: - return std::get(ValVariant).isNonZero(); - case String: - return !std::get(ValVariant).empty(); - default: - break; - } - return false; -} - bool operator==(const EdgeValue &Lhs, const EdgeValue &Rhs) { if (Lhs.VariantType != Rhs.VariantType) { return false; diff --git a/lib/PhasarLLVM/DataFlow/PathSensitivity/Z3BasedPathSensitivityManager.cpp b/lib/PhasarLLVM/DataFlow/PathSensitivity/Z3BasedPathSensitivityManager.cpp index 801a8e10f1..d69b3a38cc 100644 --- a/lib/PhasarLLVM/DataFlow/PathSensitivity/Z3BasedPathSensitivityManager.cpp +++ b/lib/PhasarLLVM/DataFlow/PathSensitivity/Z3BasedPathSensitivityManager.cpp @@ -95,7 +95,7 @@ z3::expr Z3BasedPathSensitivityManagerBase::filterOutUnreachableNodes( llvm_unreachable("Adj nonempty and Ys empty is unexpected"); } auto Y = Ys[0]; - for (const auto &Constr : llvm::makeArrayRef(Ys).drop_front()) { + for (const auto &Constr : llvm::ArrayRef(Ys).drop_front()) { Y = Y || Constr; } return Ctx.NodeConstraints[Vtx] = (X && Y).simplify(); diff --git a/lib/PhasarLLVM/Pointer/LLVMAliasSet.cpp b/lib/PhasarLLVM/Pointer/LLVMAliasSet.cpp index 5b246c3d8f..3974f59d1b 100644 --- a/lib/PhasarLLVM/Pointer/LLVMAliasSet.cpp +++ b/lib/PhasarLLVM/Pointer/LLVMAliasSet.cpp @@ -359,7 +359,7 @@ void LLVMAliasSet::addPointer(FunctionAliasView AA, const llvm::DataLayout &DL, Reps[ToMerge[0]]->getType()}; llvm::SmallVector ToRemove; - for (auto Idx : llvm::makeArrayRef(ToMerge).slice(1)) { + for (auto Idx : llvm::ArrayRef(ToMerge).slice(1)) { mergeAliasSets(PTS, AliasSets[Reps[Idx]]); if (auto [Unused, Inserted] = OccurringTypes.insert(Reps[Idx]->getType()); !Inserted) { diff --git a/lib/PhasarLLVM/Pointer/LLVMBasedAliasAnalysis.cpp b/lib/PhasarLLVM/Pointer/LLVMBasedAliasAnalysis.cpp index 38a79105b0..0406dbfbc9 100644 --- a/lib/PhasarLLVM/Pointer/LLVMBasedAliasAnalysis.cpp +++ b/lib/PhasarLLVM/Pointer/LLVMBasedAliasAnalysis.cpp @@ -45,7 +45,7 @@ bool LLVMBasedAliasAnalysis::hasAliasInfo(const llvm::Function &Fun) const { } void LLVMBasedAliasAnalysis::computeAliasInfo(llvm::Function &Fun) { - llvm::PreservedAnalyses PA = FPM.run(Fun, FAM); + // llvm::PreservedAnalyses PA = FPM.run(Fun, FAM); llvm::AAResults &AAR = FAM.getResult(Fun); AAInfos.insert(std::make_pair(&Fun, &AAR)); } @@ -81,6 +81,7 @@ LLVMBasedAliasAnalysis::LLVMBasedAliasAnalysis(LLVMProjectIRDB &IRDB, default: break; } + // Note: The order of the alias analyses is important. See LLVM's source // code for reference (e.g. registerAAAnalyses() in // llvm/CodeGen/CodeGenPassBuilder.h) @@ -90,7 +91,13 @@ LLVMBasedAliasAnalysis::LLVMBasedAliasAnalysis(LLVMProjectIRDB &IRDB, AA.registerFunctionAnalysis(); return AA; }); + PB.registerFunctionAnalyses(FAM); + if (PATy == AliasAnalysisType::CFLAnders) { + FAM.registerPass([] { return llvm::CFLAndersAA(); }); + } else if (PATy == AliasAnalysisType::CFLSteens) { + FAM.registerPass([] { return llvm::CFLSteensAA(); }); + } if (!UseLazyEvaluation) { for (auto &F : *IRDB.getModule()) { diff --git a/lib/PhasarLLVM/Pointer/external/README.md b/lib/PhasarLLVM/Pointer/external/README.md index b35f89681c..072dd8ea8c 100644 --- a/lib/PhasarLLVM/Pointer/external/README.md +++ b/lib/PhasarLLVM/Pointer/external/README.md @@ -3,8 +3,8 @@ All files in the `llvm` subfolder are 1:1 copied from LLVM 14.0.6 and are subject to the LLVM license. You can find a copy of the LLVM license [here](./LLVM-LICENSE.txt). -Note that we needed to copy these files, as LLVM removed them in the transition from version 14 to 15. +Note that we needed to copy these files, as LLVM removed them in the transition from version 14 to more recent LLVM versions. To avoid LLVM from blocking PhASAR releases, we provide these files ourselves as a *temporary solution*. -We, as the PhASAR development core team, do not aim for maintaining the here provided LLVM code and will not add any modifications to it (bugfixes, enhancements, etc.). +We, as the PhASAR development core team, do not aim for maintaining the here provided LLVM code and will not add any modifications to it, except for compilation fixes when changing the LLVM version (bugfixes, enhancements, etc.). Rather, we will add a custom replacement eventually. diff --git a/lib/PhasarLLVM/Pointer/external/llvm/AliasAnalysisSummary.cpp b/lib/PhasarLLVM/Pointer/external/llvm/AliasAnalysisSummary.cpp new file mode 100644 index 0000000000..66b25a6567 --- /dev/null +++ b/lib/PhasarLLVM/Pointer/external/llvm/AliasAnalysisSummary.cpp @@ -0,0 +1,105 @@ +#include "AliasAnalysisSummary.h" + +#include "llvm/IR/Argument.h" +#include "llvm/IR/InstrTypes.h" +#include "llvm/IR/Type.h" +#include "llvm/Support/Compiler.h" + +namespace llvm { +namespace cflaa { + +namespace { +const unsigned AttrEscapedIndex = 0; +const unsigned AttrUnknownIndex = 1; +const unsigned AttrGlobalIndex = 2; +const unsigned AttrCallerIndex = 3; +const unsigned AttrFirstArgIndex = 4; +const unsigned AttrLastArgIndex = NumAliasAttrs; +const unsigned AttrMaxNumArgs = AttrLastArgIndex - AttrFirstArgIndex; + +// It would be *slightly* prettier if we changed these to AliasAttrs, but it +// seems that both GCC and MSVC emit dynamic initializers for const bitsets. +using AliasAttr = unsigned; +const AliasAttr AttrNone = 0; +const AliasAttr AttrEscaped = 1 << AttrEscapedIndex; +const AliasAttr AttrUnknown = 1 << AttrUnknownIndex; +const AliasAttr AttrGlobal = 1 << AttrGlobalIndex; +const AliasAttr AttrCaller = 1 << AttrCallerIndex; +const AliasAttr ExternalAttrMask = AttrEscaped | AttrUnknown | AttrGlobal; +} // namespace + +AliasAttrs getAttrNone() { return AttrNone; } + +AliasAttrs getAttrUnknown() { return AttrUnknown; } +bool hasUnknownAttr(AliasAttrs Attr) { return Attr.test(AttrUnknownIndex); } + +AliasAttrs getAttrCaller() { return AttrCaller; } +bool hasCallerAttr(AliasAttrs Attr) { return Attr.test(AttrCaller); } +bool hasUnknownOrCallerAttr(AliasAttrs Attr) { + return Attr.test(AttrUnknownIndex) || Attr.test(AttrCallerIndex); +} + +AliasAttrs getAttrEscaped() { return AttrEscaped; } +bool hasEscapedAttr(AliasAttrs Attr) { return Attr.test(AttrEscapedIndex); } + +static AliasAttr argNumberToAttr(unsigned ArgNum) { + if (ArgNum >= AttrMaxNumArgs) + return AttrUnknown; + // N.B. MSVC complains if we use `1U` here, since AliasAttr' ctor takes + // an unsigned long long. + return AliasAttr(1ULL << (ArgNum + AttrFirstArgIndex)); +} + +AliasAttrs getGlobalOrArgAttrFromValue(const Value &Val) { + if (isa(Val)) + return AttrGlobal; + + if (auto *Arg = dyn_cast(&Val)) + // Only pointer arguments should have the argument attribute, + // because things can't escape through scalars without us seeing a + // cast, and thus, interaction with them doesn't matter. + if (!Arg->hasNoAliasAttr() && Arg->getType()->isPointerTy()) + return argNumberToAttr(Arg->getArgNo()); + return AttrNone; +} + +bool isGlobalOrArgAttr(AliasAttrs Attr) { + return Attr.reset(AttrEscapedIndex) + .reset(AttrUnknownIndex) + .reset(AttrCallerIndex) + .any(); +} + +AliasAttrs getExternallyVisibleAttrs(AliasAttrs Attr) { + return Attr & AliasAttrs(ExternalAttrMask); +} + +std::optional +instantiateInterfaceValue(InterfaceValue IValue, CallBase &Call) { + auto Index = IValue.Index; + auto *V = (Index == 0) ? &Call : Call.getArgOperand(Index - 1); + if (V->getType()->isPointerTy()) + return InstantiatedValue{V, IValue.DerefLevel}; + return std::nullopt; +} + +std::optional +instantiateExternalRelation(ExternalRelation ERelation, CallBase &Call) { + auto From = instantiateInterfaceValue(ERelation.From, Call); + if (!From) + return std::nullopt; + auto To = instantiateInterfaceValue(ERelation.To, Call); + if (!To) + return std::nullopt; + return InstantiatedRelation{*From, *To, ERelation.Offset}; +} + +std::optional +instantiateExternalAttribute(ExternalAttribute EAttr, CallBase &Call) { + auto Value = instantiateInterfaceValue(EAttr.IValue, Call); + if (!Value) + return std::nullopt; + return InstantiatedAttr{*Value, EAttr.Attr}; +} +} // namespace cflaa +} // namespace llvm diff --git a/lib/PhasarLLVM/Pointer/external/llvm/AliasAnalysisSummary.h b/lib/PhasarLLVM/Pointer/external/llvm/AliasAnalysisSummary.h index 6fcb6cc4b4..5f5ea0516e 100644 --- a/lib/PhasarLLVM/Pointer/external/llvm/AliasAnalysisSummary.h +++ b/lib/PhasarLLVM/Pointer/external/llvm/AliasAnalysisSummary.h @@ -35,10 +35,10 @@ #define LLVM_ANALYSIS_ALIASANALYSISSUMMARY_H #include "llvm/ADT/DenseMapInfo.h" -#include "llvm/ADT/Optional.h" #include "llvm/ADT/SmallVector.h" #include +#include namespace llvm { @@ -204,8 +204,8 @@ struct InstantiatedValue { Value *Val; unsigned DerefLevel; }; -Optional instantiateInterfaceValue(InterfaceValue IValue, - CallBase &Call); +std::optional +instantiateInterfaceValue(InterfaceValue IValue, CallBase &Call); inline bool operator==(InstantiatedValue LHS, InstantiatedValue RHS) { return LHS.Val == RHS.Val && LHS.DerefLevel == RHS.DerefLevel; @@ -233,7 +233,7 @@ struct InstantiatedRelation { InstantiatedValue From, To; int64_t Offset; }; -Optional +std::optional instantiateExternalRelation(ExternalRelation ERelation, CallBase &Call); /// This is the result of instantiating ExternalAttribute at a particular @@ -242,8 +242,8 @@ struct InstantiatedAttr { InstantiatedValue IValue; AliasAttrs Attr; }; -Optional instantiateExternalAttribute(ExternalAttribute EAttr, - CallBase &Call); +std::optional +instantiateExternalAttribute(ExternalAttribute EAttr, CallBase &Call); } // namespace cflaa template <> struct DenseMapInfo { diff --git a/lib/PhasarLLVM/Pointer/external/llvm/CFLAndersAliasAnalysis.cpp b/lib/PhasarLLVM/Pointer/external/llvm/CFLAndersAliasAnalysis.cpp index 404e0df3aa..36796b40e6 100644 --- a/lib/PhasarLLVM/Pointer/external/llvm/CFLAndersAliasAnalysis.cpp +++ b/lib/PhasarLLVM/Pointer/external/llvm/CFLAndersAliasAnalysis.cpp @@ -52,13 +52,11 @@ // run on. Realistically, this likely isn't a problem until we allow // FunctionPasses to run concurrently. -#include "llvm/Analysis/CFLAndersAliasAnalysis.h" +#include "CFLAndersAliasAnalysis.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseMapInfo.h" #include "llvm/ADT/DenseSet.h" -#include "llvm/ADT/None.h" -#include "llvm/ADT/Optional.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/iterator_range.h" @@ -336,7 +334,7 @@ class CFLAndersAAResult::FunctionInfo { /// Summary of externally visible effects. AliasSummary Summary; - Optional getAttrs(const Value *) const; + std::optional getAttrs(const Value *) const; public: FunctionInfo(const Function &, const SmallVectorImpl &, @@ -354,12 +352,12 @@ static bool hasWriteOnlyState(StateSet Set) { return (Set & StateSet(WriteOnlyStateMask)).any(); } -static Optional +static std::optional getInterfaceValue(InstantiatedValue IValue, const SmallVectorImpl &RetVals) { auto Val = IValue.Val; - Optional Index; + std::optional Index; if (auto Arg = dyn_cast(Val)) Index = Arg->getArgNo() + 1; else if (is_contained(RetVals, Val)) @@ -367,7 +365,7 @@ getInterfaceValue(InstantiatedValue IValue, if (Index) return InterfaceValue{*Index, IValue.DerefLevel}; - return None; + return {}; } static void populateAttrMap(DenseMap &AttrMap, @@ -510,14 +508,14 @@ CFLAndersAAResult::FunctionInfo::FunctionInfo( populateExternalRelations(Summary.RetParamRelations, Fn, RetVals, ReachSet); } -Optional +std::optional CFLAndersAAResult::FunctionInfo::getAttrs(const Value *V) const { assert(V != nullptr); auto Itr = AttrMap.find(V); if (Itr != AttrMap.end()) return Itr->second; - return None; + return {}; } bool CFLAndersAAResult::FunctionInfo::mayAlias( @@ -628,12 +626,12 @@ static void initializeWorkList(std::vector &WorkList, } } -static Optional getNodeBelow(const CFLGraph &Graph, - InstantiatedValue V) { +static std::optional getNodeBelow(const CFLGraph &Graph, + InstantiatedValue V) { auto NodeBelow = InstantiatedValue{V.Val, V.DerefLevel + 1}; if (Graph.getNode(NodeBelow)) return NodeBelow; - return None; + return {}; } static void processWorkListItem(const WorkListItem &Item, const CFLGraph &Graph, @@ -812,7 +810,8 @@ CFLAndersAAResult::buildInfoFrom(const Function &Fn) { } void CFLAndersAAResult::scan(const Function &Fn) { - auto InsertPair = Cache.insert(std::make_pair(&Fn, Optional())); + auto InsertPair = + Cache.insert(std::make_pair(&Fn, std::optional())); (void)InsertPair; assert(InsertPair.second && "Trying to scan a function that has already been cached"); @@ -827,21 +826,21 @@ void CFLAndersAAResult::scan(const Function &Fn) { void CFLAndersAAResult::evict(const Function *Fn) { Cache.erase(Fn); } -const Optional & +const std::optional & CFLAndersAAResult::ensureCached(const Function &Fn) { auto Iter = Cache.find(&Fn); if (Iter == Cache.end()) { scan(Fn); Iter = Cache.find(&Fn); assert(Iter != Cache.end()); - assert(Iter->second.hasValue()); + assert(Iter->second.has_value()); } return Iter->second; } const AliasSummary *CFLAndersAAResult::getAliasSummary(const Function &Fn) { auto &FunInfo = ensureCached(Fn); - if (FunInfo.hasValue()) + if (FunInfo.has_value()) return &FunInfo->getAliasSummary(); else return nullptr; @@ -881,7 +880,8 @@ AliasResult CFLAndersAAResult::query(const MemoryLocation &LocA, AliasResult CFLAndersAAResult::alias(const MemoryLocation &LocA, const MemoryLocation &LocB, - AAQueryInfo &AAQI) { + AAQueryInfo &AAQI, + const Instruction *CtxI) { if (LocA.Ptr == LocB.Ptr) return AliasResult::MustAlias; @@ -891,11 +891,11 @@ AliasResult CFLAndersAAResult::alias(const MemoryLocation &LocA, // ConstantExpr, but every query needs to have at least one Value tied to a // Function, and neither GlobalValues nor ConstantExprs are. if (isa(LocA.Ptr) && isa(LocB.Ptr)) - return AAResultBase::alias(LocA, LocB, AAQI); + return AAResultBase::alias(LocA, LocB, AAQI, CtxI); AliasResult QueryResult = query(LocA, LocB); if (QueryResult == AliasResult::MayAlias) - return AAResultBase::alias(LocA, LocB, AAQI); + return AAResultBase::alias(LocA, LocB, AAQI, CtxI); return QueryResult; } @@ -908,27 +908,3 @@ CFLAndersAAResult CFLAndersAA::run(Function &F, FunctionAnalysisManager &AM) { }; return CFLAndersAAResult(GetTLI); } - -char CFLAndersAAWrapperPass::ID = 0; -INITIALIZE_PASS(CFLAndersAAWrapperPass, "cfl-anders-aa", - "Inclusion-Based CFL Alias Analysis", false, true) - -ImmutablePass *llvm::createCFLAndersAAWrapperPass() { - return new CFLAndersAAWrapperPass(); -} - -CFLAndersAAWrapperPass::CFLAndersAAWrapperPass() : ImmutablePass(ID) { - initializeCFLAndersAAWrapperPassPass(*PassRegistry::getPassRegistry()); -} - -void CFLAndersAAWrapperPass::initializePass() { - auto GetTLI = [this](Function &F) -> TargetLibraryInfo & { - return this->getAnalysis().getTLI(F); - }; - Result.reset(new CFLAndersAAResult(GetTLI)); -} - -void CFLAndersAAWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const { - AU.setPreservesAll(); - AU.addRequired(); -} diff --git a/lib/PhasarLLVM/Pointer/external/llvm/CFLAndersAliasAnalysis.h b/lib/PhasarLLVM/Pointer/external/llvm/CFLAndersAliasAnalysis.h index ddc2908855..fca6cb7711 100644 --- a/lib/PhasarLLVM/Pointer/external/llvm/CFLAndersAliasAnalysis.h +++ b/lib/PhasarLLVM/Pointer/external/llvm/CFLAndersAliasAnalysis.h @@ -15,12 +15,12 @@ #define LLVM_ANALYSIS_CFLANDERSALIASANALYSIS_H #include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/Optional.h" #include "llvm/Analysis/AliasAnalysis.h" -#include "llvm/Analysis/CFLAliasAnalysisUtils.h" #include "llvm/IR/PassManager.h" #include "llvm/Pass.h" +#include "CFLAliasAnalysisUtils.h" + #include #include @@ -36,9 +36,7 @@ struct AliasSummary; } // end namespace cflaa -class CFLAndersAAResult : public AAResultBase { - friend AAResultBase; - +class CFLAndersAAResult : public AAResultBase { class FunctionInfo; public: @@ -63,12 +61,12 @@ class CFLAndersAAResult : public AAResultBase { AliasResult query(const MemoryLocation &, const MemoryLocation &); AliasResult alias(const MemoryLocation &, const MemoryLocation &, - AAQueryInfo &); + AAQueryInfo &, const Instruction *CtxI); private: /// Ensures that the given function is available in the cache. /// Returns the appropriate entry from the cache. - const Optional &ensureCached(const Function &); + const std::optional &ensureCached(const Function &); /// Inserts the given Function into the cache. void scan(const Function &); @@ -83,7 +81,7 @@ class CFLAndersAAResult : public AAResultBase { /// in the cache as an Optional without a value. This way, if we /// have any kind of recursion, it is discernable from a function /// that simply has empty sets. - DenseMap> Cache; + DenseMap> Cache; std::forward_list> Handles; }; @@ -103,26 +101,6 @@ class CFLAndersAA : public AnalysisInfoMixin { CFLAndersAAResult run(Function &F, FunctionAnalysisManager &AM); }; -/// Legacy wrapper pass to provide the CFLAndersAAResult object. -class CFLAndersAAWrapperPass : public ImmutablePass { - std::unique_ptr Result; - -public: - static char ID; - - CFLAndersAAWrapperPass(); - - CFLAndersAAResult &getResult() { return *Result; } - const CFLAndersAAResult &getResult() const { return *Result; } - - void initializePass() override; - void getAnalysisUsage(AnalysisUsage &AU) const override; -}; - -// createCFLAndersAAWrapperPass - This pass implements a set-based approach to -// alias analysis. -ImmutablePass *createCFLAndersAAWrapperPass(); - } // end namespace llvm #endif // LLVM_ANALYSIS_CFLANDERSALIASANALYSIS_H diff --git a/lib/PhasarLLVM/Pointer/external/llvm/CFLGraph.h b/lib/PhasarLLVM/Pointer/external/llvm/CFLGraph.h index c3e53c1146..999a420a89 100644 --- a/lib/PhasarLLVM/Pointer/external/llvm/CFLGraph.h +++ b/lib/PhasarLLVM/Pointer/external/llvm/CFLGraph.h @@ -405,7 +405,7 @@ template class CFLGraphBuilder { auto &RetParamRelations = Summary->RetParamRelations; for (auto &Relation : RetParamRelations) { auto IRelation = instantiateExternalRelation(Relation, Call); - if (IRelation.hasValue()) { + if (IRelation.has_value()) { Graph.addNode(IRelation->From); Graph.addNode(IRelation->To); Graph.addEdge(IRelation->From, IRelation->To); @@ -415,7 +415,7 @@ template class CFLGraphBuilder { auto &RetParamAttributes = Summary->RetParamAttributes; for (auto &Attribute : RetParamAttributes) { auto IAttr = instantiateExternalAttribute(Attribute, Call); - if (IAttr.hasValue()) + if (IAttr.has_value()) Graph.addNode(IAttr->IValue, IAttr->Attr); } } @@ -649,8 +649,8 @@ template class CFLGraphBuilder { void buildGraphFrom(Function &Fn) { GetEdgesVisitor Visitor(*this, Fn.getParent()->getDataLayout()); - for (auto &Bb : Fn.getBasicBlockList()) - for (auto &Inst : Bb.getInstList()) + for (auto &Bb : Fn) + for (auto &Inst : Bb) addInstructionToGraph(Visitor, Inst); for (auto &Arg : Fn.args()) diff --git a/lib/PhasarLLVM/Pointer/external/llvm/CFLSteensAliasAnalysis.cpp b/lib/PhasarLLVM/Pointer/external/llvm/CFLSteensAliasAnalysis.cpp index 1a17153b3c..33fd1e6b11 100644 --- a/lib/PhasarLLVM/Pointer/external/llvm/CFLSteensAliasAnalysis.cpp +++ b/lib/PhasarLLVM/Pointer/external/llvm/CFLSteensAliasAnalysis.cpp @@ -34,10 +34,9 @@ // run on. Realistically, this likely isn't a problem until we allow // FunctionPasses to run concurrently. -#include "llvm/Analysis/CFLSteensAliasAnalysis.h" +#include "CFLSteensAliasAnalysis.h" #include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/Optional.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/IR/Constants.h" @@ -168,7 +167,7 @@ CFLSteensAAResult::FunctionInfo::FunctionInfo( assert(RetVal != nullptr); assert(RetVal->getType()->isPointerTy()); auto RetInfo = Sets.find(InstantiatedValue{RetVal, 0}); - if (RetInfo.hasValue()) + if (RetInfo.has_value()) AddToRetParamRelations(0, RetInfo->Index); } @@ -177,7 +176,7 @@ CFLSteensAAResult::FunctionInfo::FunctionInfo( for (auto &Param : Fn.args()) { if (Param.getType()->isPointerTy()) { auto ParamInfo = Sets.find(InstantiatedValue{&Param, 0}); - if (ParamInfo.hasValue()) + if (ParamInfo.has_value()) AddToRetParamRelations(I + 1, ParamInfo->Index); } ++I; @@ -228,7 +227,8 @@ CFLSteensAAResult::FunctionInfo CFLSteensAAResult::buildSetsFrom(Function *Fn) { } void CFLSteensAAResult::scan(Function *Fn) { - auto InsertPair = Cache.insert(std::make_pair(Fn, Optional())); + auto InsertPair = + Cache.insert(std::make_pair(Fn, std::optional())); (void)InsertPair; assert(InsertPair.second && "Trying to scan a function that has already been cached"); @@ -246,21 +246,21 @@ void CFLSteensAAResult::evict(Function *Fn) { Cache.erase(Fn); } /// Ensures that the given function is available in the cache, and returns the /// entry. -const Optional & +const std::optional & CFLSteensAAResult::ensureCached(Function *Fn) { auto Iter = Cache.find(Fn); if (Iter == Cache.end()) { scan(Fn); Iter = Cache.find(Fn); assert(Iter != Cache.end()); - assert(Iter->second.hasValue()); + assert(Iter->second.has_value()); } return Iter->second; } const AliasSummary *CFLSteensAAResult::getAliasSummary(Function &Fn) { auto &FunInfo = ensureCached(&Fn); - if (FunInfo.hasValue()) + if (FunInfo.has_value()) return &FunInfo->getAliasSummary(); else return nullptr; @@ -296,15 +296,15 @@ AliasResult CFLSteensAAResult::query(const MemoryLocation &LocA, assert(Fn != nullptr); auto &MaybeInfo = ensureCached(Fn); - assert(MaybeInfo.hasValue()); + assert(MaybeInfo.has_value()); auto &Sets = MaybeInfo->getStratifiedSets(); auto MaybeA = Sets.find(InstantiatedValue{ValA, 0}); - if (!MaybeA.hasValue()) + if (!MaybeA.has_value()) return AliasResult::MayAlias; auto MaybeB = Sets.find(InstantiatedValue{ValB, 0}); - if (!MaybeB.hasValue()) + if (!MaybeB.has_value()) return AliasResult::MayAlias; auto SetA = *MaybeA; @@ -341,27 +341,3 @@ CFLSteensAAResult CFLSteensAA::run(Function &F, FunctionAnalysisManager &AM) { }; return CFLSteensAAResult(GetTLI); } - -char CFLSteensAAWrapperPass::ID = 0; -INITIALIZE_PASS(CFLSteensAAWrapperPass, "cfl-steens-aa", - "Unification-Based CFL Alias Analysis", false, true) - -ImmutablePass *llvm::createCFLSteensAAWrapperPass() { - return new CFLSteensAAWrapperPass(); -} - -CFLSteensAAWrapperPass::CFLSteensAAWrapperPass() : ImmutablePass(ID) { - initializeCFLSteensAAWrapperPassPass(*PassRegistry::getPassRegistry()); -} - -void CFLSteensAAWrapperPass::initializePass() { - auto GetTLI = [this](Function &F) -> const TargetLibraryInfo & { - return this->getAnalysis().getTLI(F); - }; - Result.reset(new CFLSteensAAResult(GetTLI)); -} - -void CFLSteensAAWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const { - AU.setPreservesAll(); - AU.addRequired(); -} diff --git a/lib/PhasarLLVM/Pointer/external/llvm/CFLSteensAliasAnalysis.h b/lib/PhasarLLVM/Pointer/external/llvm/CFLSteensAliasAnalysis.h index b0ab37baa4..c405209e1c 100644 --- a/lib/PhasarLLVM/Pointer/external/llvm/CFLSteensAliasAnalysis.h +++ b/lib/PhasarLLVM/Pointer/external/llvm/CFLSteensAliasAnalysis.h @@ -15,14 +15,14 @@ #define LLVM_ANALYSIS_CFLSTEENSALIASANALYSIS_H #include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/Optional.h" #include "llvm/Analysis/AliasAnalysis.h" -#include "llvm/Analysis/CFLAliasAnalysisUtils.h" #include "llvm/Analysis/MemoryLocation.h" #include "llvm/IR/PassManager.h" #include "llvm/Pass.h" #include "llvm/Support/Casting.h" +#include "CFLAliasAnalysisUtils.h" + #include #include @@ -37,9 +37,7 @@ struct AliasSummary; } // end namespace cflaa -class CFLSteensAAResult : public AAResultBase { - friend AAResultBase; - +class CFLSteensAAResult : public AAResultBase { class FunctionInfo; public: @@ -63,7 +61,7 @@ class CFLSteensAAResult : public AAResultBase { /// Ensures that the given function is available in the cache. /// Returns the appropriate entry from the cache. - const Optional &ensureCached(Function *Fn); + const std::optional &ensureCached(Function *Fn); /// Get the alias summary for the given function /// Return nullptr if the summary is not found or not available @@ -72,7 +70,7 @@ class CFLSteensAAResult : public AAResultBase { AliasResult query(const MemoryLocation &LocA, const MemoryLocation &LocB); AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB, - AAQueryInfo &AAQI) { + AAQueryInfo &AAQI, const Instruction *CtxI) { if (LocA.Ptr == LocB.Ptr) return AliasResult::MustAlias; @@ -82,11 +80,11 @@ class CFLSteensAAResult : public AAResultBase { // ConstantExpr, but every query needs to have at least one Value tied to a // Function, and neither GlobalValues nor ConstantExprs are. if (isa(LocA.Ptr) && isa(LocB.Ptr)) - return AAResultBase::alias(LocA, LocB, AAQI); + return AAResultBase::alias(LocA, LocB, AAQI, CtxI); AliasResult QueryResult = query(LocA, LocB); if (QueryResult == AliasResult::MayAlias) - return AAResultBase::alias(LocA, LocB, AAQI); + return AAResultBase::alias(LocA, LocB, AAQI, CtxI); return QueryResult; } @@ -99,7 +97,7 @@ class CFLSteensAAResult : public AAResultBase { /// in the cache as an Optional without a value. This way, if we /// have any kind of recursion, it is discernable from a function /// that simply has empty sets. - DenseMap> Cache; + DenseMap> Cache; std::forward_list> Handles; FunctionInfo buildSetsFrom(Function *F); @@ -120,26 +118,6 @@ class CFLSteensAA : public AnalysisInfoMixin { CFLSteensAAResult run(Function &F, FunctionAnalysisManager &AM); }; -/// Legacy wrapper pass to provide the CFLSteensAAResult object. -class CFLSteensAAWrapperPass : public ImmutablePass { - std::unique_ptr Result; - -public: - static char ID; - - CFLSteensAAWrapperPass(); - - CFLSteensAAResult &getResult() { return *Result; } - const CFLSteensAAResult &getResult() const { return *Result; } - - void initializePass() override; - void getAnalysisUsage(AnalysisUsage &AU) const override; -}; - -// createCFLSteensAAWrapperPass - This pass implements a set-based approach to -// alias analysis. -ImmutablePass *createCFLSteensAAWrapperPass(); - } // end namespace llvm #endif // LLVM_ANALYSIS_CFLSTEENSALIASANALYSIS_H diff --git a/lib/PhasarLLVM/Pointer/external/llvm/StratifiedSets.h b/lib/PhasarLLVM/Pointer/external/llvm/StratifiedSets.h index 71f07af543..78ac53f88a 100644 --- a/lib/PhasarLLVM/Pointer/external/llvm/StratifiedSets.h +++ b/lib/PhasarLLVM/Pointer/external/llvm/StratifiedSets.h @@ -10,7 +10,6 @@ #define LLVM_ADT_STRATIFIEDSETS_H #include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/Optional.h" #include "llvm/ADT/SmallSet.h" #include "llvm/ADT/SmallVector.h" @@ -19,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -93,10 +93,10 @@ template class StratifiedSets { std::vector Links) : Values(std::move(Map)), Links(std::move(Links)) {} - Optional find(const T &Elem) const { + std::optional find(const T &Elem) const { auto Iter = Values.find(Elem); if (Iter == Values.end()) - return None; + return std::nullopt; return Iter->second; } @@ -342,10 +342,10 @@ template class StratifiedSetsBuilder { return StratifiedSets(std::move(Values), std::move(StratLinks)); } - bool has(const T &Elem) const { return get(Elem).hasValue(); } + bool has(const T &Elem) const { return get(Elem).has_value(); } bool add(const T &Main) { - if (get(Main).hasValue()) + if (get(Main).has_value()) return false; auto NewIndex = getNewUnlinkedIndex(); @@ -546,24 +546,24 @@ template class StratifiedSetsBuilder { return true; } - Optional get(const T &Val) const { + std::optional get(const T &Val) const { auto Result = Values.find(Val); if (Result == Values.end()) - return None; + return std::nullopt; return &Result->second; } - Optional get(const T &Val) { + std::optional get(const T &Val) { auto Result = Values.find(Val); if (Result == Values.end()) - return None; + return std::nullopt; return &Result->second; } - Optional indexOf(const T &Val) { + std::optional indexOf(const T &Val) { auto MaybeVal = get(Val); - if (!MaybeVal.hasValue()) - return None; + if (!MaybeVal.has_value()) + return std::nullopt; auto *Info = *MaybeVal; auto &Link = linksAt(Info->Index); return Link.Number; diff --git a/lib/PhasarLLVM/TaintConfig/LLVMTaintConfig.cpp b/lib/PhasarLLVM/TaintConfig/LLVMTaintConfig.cpp index 7528eb9c5d..f8a392c4db 100644 --- a/lib/PhasarLLVM/TaintConfig/LLVMTaintConfig.cpp +++ b/lib/PhasarLLVM/TaintConfig/LLVMTaintConfig.cpp @@ -16,6 +16,7 @@ #include "phasar/PhasarLLVM/Utils/LLVMShorthands.h" #include "phasar/Utils/Logger.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/BinaryFormat/Dwarf.h" #include "llvm/IR/DebugInfo.h" #include "llvm/IR/Function.h" @@ -182,9 +183,20 @@ LLVMTaintConfig::LLVMTaintConfig(const psr::LLVMProjectIRDB &Code, } LLVMTaintConfig::LLVMTaintConfig(const psr::LLVMProjectIRDB &AnnotatedCode) { + + llvm::SmallVector VarAnnotations{}; + llvm::SmallVector PtrAnnotations{}; + for (const auto *F : AnnotatedCode.getAllFunctions()) { + if (F->getName().startswith("llvm.var.annotation")) { + VarAnnotations.push_back(F); + } + if (F->getName().startswith("llvm.ptr.annotation")) { + PtrAnnotations.push_back(F); + } + } + // handle "local" annotation declarations - const auto *Annotation = AnnotatedCode.getFunction("llvm.var.annotation"); - if (Annotation) { + for (const auto *Annotation : VarAnnotations) { for (const auto *VarAnnotationUser : Annotation->users()) { if (const auto *AnnotationCall = llvm::dyn_cast(VarAnnotationUser)) { @@ -221,14 +233,6 @@ LLVMTaintConfig::LLVMTaintConfig(const psr::LLVMProjectIRDB &AnnotatedCode) { } } - std::vector PtrAnnotations{}; - PtrAnnotations.reserve(AnnotatedCode.getNumFunctions()); - for (const auto *F : AnnotatedCode.getAllFunctions()) { - if (F->getName().startswith("llvm.ptr.annotation")) { - PtrAnnotations.push_back(F); - } - } - for (const auto *Annotation : PtrAnnotations) { for (const auto *VarAnnotationUser : Annotation->users()) { if (const auto *AnnotationCall = diff --git a/lib/PhasarLLVM/Utils/Annotation.cpp b/lib/PhasarLLVM/Utils/Annotation.cpp index b97f2429a7..3d522f98fe 100644 --- a/lib/PhasarLLVM/Utils/Annotation.cpp +++ b/lib/PhasarLLVM/Utils/Annotation.cpp @@ -18,6 +18,7 @@ #include "llvm/IR/GlobalVariable.h" #include "llvm/IR/InstrTypes.h" #include "llvm/IR/Instructions.h" +#include "llvm/IR/Intrinsics.h" #include "llvm/IR/Operator.h" #include "llvm/IR/Value.h" #include "llvm/Support/Casting.h" @@ -31,7 +32,7 @@ VarAnnotation::VarAnnotation(const llvm::CallBase *AnnotationCall) noexcept : AnnotationCall(AnnotationCall) { auto *Callee = AnnotationCall->getCalledFunction(); assert(Callee && Callee->hasName() && - (Callee->getName() == "llvm.var.annotation" || + (Callee->getName().starts_with("llvm.var.annotation") || Callee->getName().startswith("llvm.ptr.annotation"))); } diff --git a/unittests/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchyTest.cpp b/unittests/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchyTest.cpp index 5e0c1f890c..bacb4008b8 100644 --- a/unittests/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchyTest.cpp +++ b/unittests/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchyTest.cpp @@ -366,7 +366,11 @@ TEST(DBTHTest, BasicTHReconstruction_12_b) { // check for all subtypes const auto &SubTypes = DBTH.getSubTypes(BaseType); +#if LLVM_VERSION_MAJOR < 16 + // In LLVM 16, the metadata is pruned to the relations that are actually + // *used* in the code EXPECT_TRUE(SubTypes.find(ChildType) != SubTypes.end()); +#endif const auto &SubTypesChild = DBTH.getSubTypes(ChildType); EXPECT_TRUE(SubTypesChild.find(ChildsChildType) != SubTypesChild.end()); } @@ -1097,12 +1101,16 @@ TEST(DBTHTest, TransitivelyReachableTypes_12_b) { auto ReachableTypesChild = DBTH.getSubTypes(ChildType); auto ReachableTypesChildsChild = DBTH.getSubTypes(ChildsChildType); - EXPECT_EQ(ReachableTypesBase.size(), 3U); + EXPECT_EQ(ReachableTypesBase.size(), LLVM_VERSION_MAJOR < 16 ? 3U : 1U); EXPECT_EQ(ReachableTypesChild.size(), 2U); EXPECT_EQ(ReachableTypesChildsChild.size(), 1U); EXPECT_TRUE(ReachableTypesBase.count(BaseType)); +#if LLVM_VERSION_MAJOR < 16 + // In LLVM 16, the metadata is pruned to the relations that are actually + // *used* in the code EXPECT_TRUE(ReachableTypesBase.count(ChildType)); EXPECT_TRUE(ReachableTypesBase.count(ChildsChildType)); +#endif EXPECT_FALSE(ReachableTypesChild.count(BaseType)); EXPECT_TRUE(ReachableTypesChild.count(ChildType)); EXPECT_TRUE(ReachableTypesChild.count(ChildsChildType)); diff --git a/unittests/TestUtils/SrcCodeLocationEntry.h b/unittests/TestUtils/SrcCodeLocationEntry.h index c13ca7f8d4..9cfafd1cb8 100644 --- a/unittests/TestUtils/SrcCodeLocationEntry.h +++ b/unittests/TestUtils/SrcCodeLocationEntry.h @@ -363,7 +363,7 @@ testingLocInIR(TestingSrcLocation Loc, }, [&](RetVal R) -> llvm::Value const * { const auto *InFun = GetFunction(R.InFunction); - for (const auto &BB : llvm::reverse(InFun->getBasicBlockList())) { + for (const auto &BB : llvm::reverse(*InFun)) { if (const auto *Ret = llvm::dyn_cast(BB.getTerminator())) { return Ret->getReturnValue(); @@ -374,7 +374,7 @@ testingLocInIR(TestingSrcLocation Loc, }, [&](RetStmt R) -> llvm::Value const * { const auto *InFun = GetFunction(R.InFunction); - for (const auto &BB : llvm::reverse(InFun->getBasicBlockList())) { + for (const auto &BB : llvm::reverse(*InFun)) { if (const auto *Ret = llvm::dyn_cast(BB.getTerminator())) { return Ret; diff --git a/utils/InstallAptDependencies.sh b/utils/InstallAptDependencies.sh index 8317271ff2..d5e9fa35c7 100755 --- a/utils/InstallAptDependencies.sh +++ b/utils/InstallAptDependencies.sh @@ -7,7 +7,7 @@ if printf "%s\n" "$@" | grep -Eqe '^--noninteractive|-ni$'; then else readonly noninteractive="false" fi -readonly LLVM_IR_VERSION=15 +readonly LLVM_IR_VERSION=16 additional_dependencies=("$@") (