diff --git a/.editorconfig b/.editorconfig index de09e86963..c723e0d1ee 100644 --- a/.editorconfig +++ b/.editorconfig @@ -14,7 +14,7 @@ indent_size = 4 tab_width = 4 # C. CPP source code -[{*.{h,c,cpp}] +[**/*.{h,c,cpp}] indent_style=space indent_size = 4 tab_width = 4 diff --git a/.github/workflows/github-action.yml b/.github/workflows/github-action.yml index f9eb36587e..4b4c9bd879 100644 --- a/.github/workflows/github-action.yml +++ b/.github/workflows/github-action.yml @@ -22,7 +22,7 @@ jobs: sanitizer: address steps: # checkout the repo - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 # setup the environment - name: mac-setup if: runner.os == 'macOS' @@ -37,16 +37,15 @@ jobs: - name: ubuntu-setup if: runner.os == 'Linux' run: | - sudo apt-get update - sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test - sudo apt-get update - sudo apt-get install cmake gcc g++ nodejs doxygen graphviz lcov libncurses5-dev libtinfo6 libzstd-dev + echo "ubuntu-setup has been moved to build.sh" # build-svf - name: build-svf run: | cd $GITHUB_WORKSPACE - echo $(pwd) + echo "Current directory: $(pwd)" + echo "GITHUB_WORKSPACE: $GITHUB_WORKSPACE" + echo "Location of build.sh: $(find . -name build.sh)" if [ "${{matrix.sanitizer}}" != "" ]; then export SVF_SANITIZER="${{matrix.sanitizer}}"; fi if [ "$RUNNER_OS" == "Linux" ] && [ "${{matrix.sanitizer}}" == "" ]; then export SVF_COVERAGE=1; fi git clone "https://github.com/SVF-tools/Test-Suite.git"; diff --git a/build.sh b/build.sh old mode 100644 new mode 100755 index 5a2ecd7d57..adda6018e5 --- a/build.sh +++ b/build.sh @@ -12,23 +12,23 @@ # If the LLVM_DIR variable is not set, LLVM will be downloaded or built from source. # # Dependencies include: build-essential libncurses5 libncurses-dev cmake zlib1g-dev -set -e # exit on first error +set -euo pipefail #exit on first error and strict checks jobs=8 ######### # Variables and Paths ######## -SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) -SVFHOME="${SCRIPT_DIR}" +SCRIPT_DIR=$( cd -- "$( dirname -- "$0" )" &> /dev/null && pwd ) +SVFHOME="${GITHUB_WORKSPACE:-$SCRIPT_DIR}" sysOS=$(uname -s) arch=$(uname -m) -MajorLLVMVer=16 -LLVMVer=${MajorLLVMVer}.0.4 -UbuntuArmLLVM_RTTI="https://github.com/SVF-tools/SVF/releases/download/SVF-3.0/llvm-${MajorLLVMVer}.0.0-ubuntu24-rtti-aarch64.tar.gz" +MajorLLVMVer=20 +LLVMVer=${MajorLLVMVer}.1.0 +UbuntuArmLLVM_RTTI="https://github.com/SVF-tools/SVF/releases/download/SVF-3.0/llvm-${MajorLLVMVer}.1.0-ubuntu24-rtti-aarch64.tar.gz" UbuntuArmLLVM="https://github.com/llvm/llvm-project/releases/download/llvmorg-${LLVMVer}/clang+llvm-${LLVMVer}-aarch64-linux-gnu.tar.xz" -UbuntuLLVM_RTTI="https://github.com/SVF-tools/SVF/releases/download/SVF-3.0/llvm-${MajorLLVMVer}.0.0-ubuntu24-rtti-x86-64.tar.gz" -UbuntuLLVM="https://github.com/llvm/llvm-project/releases/download/llvmorg-${LLVMVer}/clang+llvm-${LLVMVer}-x86_64-linux-gnu-ubuntu-22.04.tar.xz" +UbuntuLLVM_RTTI="https://github.com/SVF-tools/SVF/releases/download/SVF-3.0/llvm-${MajorLLVMVer}.1.0-ubuntu24-rtti-x86-64.tar.gz" +UbuntuLLVM="https://github.com/llvm/llvm-project/releases/download/llvmorg-${LLVMVer}/clang+llvm-${LLVMVer}-x86_64-linux-gnu-ubuntu-24.04.tar.xz" SourceLLVM="https://github.com/llvm/llvm-project/archive/refs/tags/llvmorg-${LLVMVer}.zip" UbuntuZ3="https://github.com/Z3Prover/z3/releases/download/z3-4.8.8/z3-4.8.8-x64-ubuntu-16.04.zip" UbuntuZ3Arm="https://github.com/SVF-tools/SVF-npm/raw/prebuilt-libs/z3-4.8.7-aarch64-ubuntu.zip" @@ -36,9 +36,69 @@ SourceZ3="https://github.com/Z3Prover/z3/archive/refs/tags/z3-4.8.8.zip" # Keep LLVM version suffix for version checking and better debugging # keep the version consistent with LLVM_DIR in setup.sh and llvm_version in Dockerfile -LLVMHome="llvm-${MajorLLVMVer}.0.0.obj" +LLVMHome="llvm-${LLVMVer}.obj" Z3Home="z3.obj" +Z3_BIN="$Z3Home/bin" + +# Verify SVFHOME contains CMakeLists.txt +if [ ! -f "${SVFHOME}/CMakeLists.txt" ]; then + echo "Error: CMakeLists.txt not found in SVFHOME (${SVFHOME})" + exit 1 +fi + +function installing_dependencies() { + local OSDisplayName="$1" + + if [ -z "$OSDisplayName" ]; then + echo "Error: OSDisplayName argument is required" + return 1 + fi + + if [ "$OSDisplayName" = "Ubuntu" ]; then + echo "Installing dependencies for Ubuntu..." + # Update package list + sudo apt-get update + sudo apt-get install -y software-properties-common + sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test + + # Install basic development dependencies + sudo apt-get install -y unzip build-essential libncurses6 libncurses-dev zlib1g-dev gcc g++ nodejs doxygen graphviz lcov libtinfo6 libzstd-dev curl gnupg xz-utils + + # Get Ubuntu codename for cmake installation + CODENAME=$(source /etc/os-release && echo "$VERSION_CODENAME") + + # Install cmake + echo "Installing cmake..." + curl -fsSL https://apt.kitware.com/keys/kitware-archive-latest.asc | gpg --dearmor | sudo tee /usr/share/keyrings/kitware-archive-keyring.gpg > /dev/null + echo "deb [signed-by=/usr/share/keyrings/kitware-archive-keyring.gpg] https://apt.kitware.com/ubuntu/ $CODENAME main" | sudo tee /etc/apt/sources.list.d/kitware.list > /dev/null + sudo apt-get update + sudo apt-get install -y cmake + + echo "Dependencies installed successfully for Ubuntu" + + else + if [ "$OSDisplayName" = "Darwin" ]; then + echo "Detected macOS system. Installing dependencies using Homebrew..." + # Install dependencies + brew install ncurses zlib cmake + echo "Dependencies installed successfully for macOS" + fi + fi +} + +# Detect OS and set a display name +sysOS="$(uname)" +if [[ "$sysOS" == "Darwin" ]]; then + OSDisplayName="macOS" + installing_dependencies "$OSDisplayName" +elif [[ "$sysOS" == "Linux" ]]; then + OSDisplayName="Ubuntu" + installing_dependencies "$OSDisplayName" +else + echo "Unsupported OS: $sysOS" + exit 1 +fi # Parse arguments BUILD_TYPE='Release' @@ -71,7 +131,7 @@ fi function generic_download_file { if [[ $# -ne 2 ]]; then echo "$0: bad args to generic_download_file!" - exit 1 + return 1 fi if [[ -f "$2" ]]; then @@ -81,7 +141,7 @@ function generic_download_file { local download_failed=false if type curl &> /dev/null; then - if ! curl -L "$1" -o "$2"; then + if ! curl -L --fail "$1" -o "$2"; then download_failed=true fi elif type wget &> /dev/null; then @@ -90,13 +150,13 @@ function generic_download_file { fi else echo "Cannot find download tool. Please install curl or wget." - exit 1 + return 1 fi if $download_failed; then echo "Failed to download $1" rm -f "$2" - exit 1 + return 1 fi } @@ -119,7 +179,9 @@ function check_xz { function build_z3_from_source { mkdir "$Z3Home" echo "Downloading Z3 source..." - generic_download_file "$SourceZ3" z3.zip + if ! generic_download_file "$SourceZ3" z3.zip; then + exit 1 + fi check_unzip echo "Unzipping Z3 source..." mkdir z3-source @@ -140,7 +202,9 @@ function build_z3_from_source { function build_llvm_from_source { mkdir "$LLVMHome" echo "Downloading LLVM source..." - generic_download_file "$SourceLLVM" llvm.zip + if ! generic_download_file "$SourceLLVM" llvm.zip; then + exit 1 + fi check_unzip echo "Unzipping LLVM source..." mkdir llvm-source @@ -214,17 +278,44 @@ else echo "Builds outside Ubuntu and macOS are not supported." fi +######## +# install LLVM from APT repository +####### +function download_llvm_from_apt_repo() { + echo "LLVM binary download failed. Falling back to APT install of Clang 20.1.0." + + CODENAME=$(source /etc/os-release && echo "$VERSION_CODENAME") + sudo mkdir -p /etc/apt/keyrings + curl -fsSL https://apt.llvm.org/llvm-snapshot.gpg.key | gpg --dearmor | sudo tee /etc/apt/keyrings/llvm.gpg > /dev/null + echo "deb [signed-by=/etc/apt/keyrings/llvm.gpg] https://apt.llvm.org/${CODENAME}/ llvm-toolchain-${CODENAME}-${MajorLLVMVer} main" | sudo tee /etc/apt/sources.list.d/llvm.list > /dev/null + sudo apt-get update -y + sudo apt-get install -y clang-"$MajorLLVMVer" llvm-"$MajorLLVMVer" llvm-"$MajorLLVMVer"-dev + + # set Clang latest (20+) as default + sudo update-alternatives --install /usr/bin/clang clang /usr/bin/clang-"$MajorLLVMVer" 100 + sudo update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-"$MajorLLVMVer" 100 + sudo update-alternatives --install /usr/bin/opt opt /usr/bin/opt-"$MajorLLVMVer" 100 + + # Set the specified version as default without user prompt + sudo update-alternatives --set clang /usr/bin/clang-"$MajorLLVMVer" + sudo update-alternatives --set clang++ /usr/bin/clang++-"$MajorLLVMVer" + sudo update-alternatives --set opt /usr/bin/opt-"$MajorLLVMVer" + echo "Clang "$LLVMVer" installed via APT repository fallback." +} + ######## # Download LLVM if need be. ####### -if [[ ! -d "$LLVM_DIR" ]]; then +if [[ -z "${LLVM_DIR:-}" || ! -d "$LLVM_DIR" ]]; then if [[ ! -d "$LLVMHome" ]]; then if [[ "$sysOS" = "Darwin" ]]; then echo "Installing LLVM binary for $OSDisplayName" + brew update brew install llvm@${MajorLLVMVer} # check whether llvm is installed if [ $? -eq 0 ]; then echo "LLVM binary installation completed." + export LLVM_DIR="$(brew --prefix llvm)@${MajorLLVMVer}/lib/cmake/llvm" else echo "LLVM binary installation failed." exit 1 @@ -234,51 +325,58 @@ if [[ ! -d "$LLVM_DIR" ]]; then else # everything else downloads pre-built lib includ osx "arm64" echo "Downloading LLVM binary for $OSDisplayName" - generic_download_file "$urlLLVM" llvm.tar.xz - check_xz - echo "Unzipping llvm package..." - mkdir -p "./$LLVMHome" && tar -xf llvm.tar.xz -C "./$LLVMHome" --strip-components 1 - rm llvm.tar.xz + if ! generic_download_file "$urlLLVM" llvm.tar.xz; then + download_llvm_from_apt_repo + export LLVM_DIR="/usr/lib/llvm-$MajorLLVMVer/bin" + else + check_xz + echo "Unzipping llvm package..." + mkdir -p "./$LLVMHome" && tar -xf llvm.tar.xz -C "./$LLVMHome" --strip-components 1 + rm llvm.tar.xz + export LLVM_DIR="$SVFHOME/$LLVMHome" + fi fi fi - export LLVM_DIR="$SVFHOME/$LLVMHome" fi ######## # Download Z3 if need be. ####### -if [[ ! -d "$Z3_DIR" ]]; then +if [[ -z "${Z3_DIR:-}" || ! -d "$Z3_DIR" ]]; then if [[ ! -d "$Z3Home" ]]; then # M1 Macs give back arm64, some Linuxes can give aarch64. if [[ "$sysOS" = "Darwin" ]]; then echo "Downloading Z3 binary for $OSDisplayName" - brew install z3 + brew update + brew install z3 #already installed as a part of llvm dependency on macOS if [ $? -eq 0 ]; then - echo "z3 binary installation completed." - else - echo "z3 binary installation failed." - exit 1 - fi + echo "z3 binary installation completed." + export Z3_DIR="$(brew --prefix z3)" + else + echo "z3 binary installation failed." + exit 1 + fi mkdir -p $SVFHOME/$Z3Home ln -s $(brew --prefix z3)/* $SVFHOME/$Z3Home else # everything else downloads pre-built lib echo "Downloading Z3 binary for $OSDisplayName" - generic_download_file "$urlZ3" z3.zip + if ! generic_download_file "$urlZ3" z3.zip; then + exit 1 + fi check_unzip echo "Unzipping z3 package..." unzip -q "z3.zip" && mv ./z3-* ./$Z3Home rm z3.zip + export Z3_DIR="$SVFHOME/$Z3Home" fi fi - - export Z3_DIR="$SVFHOME/$Z3Home" fi # Add LLVM & Z3 to $PATH and $LD_LIBRARY_PATH (prepend so that selected instances will be used first) PATH=$LLVM_DIR/bin:$Z3_DIR/bin:$PATH -LD_LIBRARY_PATH=$LLVM_DIR/lib:$Z3_BIN/lib:$LD_LIBRARY_PATH +LD_LIBRARY_PATH=$LLVM_DIR/lib:$Z3_BIN/lib:${LD_LIBRARY_PATH:-} echo "LLVM_DIR=$LLVM_DIR" echo "Z3_DIR=$Z3_DIR" @@ -286,19 +384,15 @@ echo "Z3_DIR=$Z3_DIR" ######## # Build SVF ######## -if [[ $1 =~ ^[Dd]ebug$ ]]; then - BUILD_TYPE='Debug' -else - BUILD_TYPE='Release' -fi -BUILD_DIR="./${BUILD_TYPE}-build" +# Always use $SVFHOME for deterministic path +BUILD_DIR="${SVFHOME}/${BUILD_TYPE}-build" rm -rf "${BUILD_DIR}" mkdir "${BUILD_DIR}" # If you need shared libs, turn BUILD_SHARED_LIBS on cmake -D CMAKE_BUILD_TYPE:STRING="${BUILD_TYPE}" \ -DSVF_ENABLE_ASSERTIONS:BOOL=true \ - -DSVF_SANITIZE="${SVF_SANITIZER}" \ + -DSVF_SANITIZE="${SVF_SANITIZER:-}" \ -DBUILD_SHARED_LIBS=${BUILD_DYN_LIB} \ -S "${SVFHOME}" -B "${BUILD_DIR}" cmake --build "${BUILD_DIR}" -j ${jobs} @@ -311,4 +405,4 @@ source ${SVFHOME}/setup.sh ${BUILD_TYPE} ######### # Optionally, you can also specify a CXX_COMPILER and your $LLVM_HOME for your build # cmake -DCMAKE_CXX_COMPILER=$LLVM_DIR/bin/clang++ -DLLVM_DIR=$LLVM_DIR -######### \ No newline at end of file +######### diff --git a/setup.sh b/setup.sh index 69ff2cce61..26e5df7829 100755 --- a/setup.sh +++ b/setup.sh @@ -1,7 +1,8 @@ #!/usr/bin/env bash echo "Setting up environment for SVF" - +MajorLLVMVer=20 +LLVMVer=${MajorLLVMVer}.1.0 ######### # export SVF_DIR, LLVM_DIR and Z3_DIR @@ -9,7 +10,7 @@ echo "Setting up environment for SVF" ######## # in a local installation $SVF_DIR is the directory containing setup.sh -SVF_DIR="$(cd -- "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1; pwd -P)" +SVF_DIR="$(cd -- "$(dirname "$0")" >/dev/null 2>&1; pwd -P)" export SVF_DIR echo "SVF_DIR=$SVF_DIR" @@ -18,7 +19,7 @@ function set_llvm { [[ -n "$LLVM_DIR" ]] && return 0 # use local download directory - LLVM_DIR="$SVF_DIR/llvm-16.0.0.obj" + LLVM_DIR="$SVF_DIR/$LLVMVer.obj" [[ -d "$LLVM_DIR" ]] && return 0 # ... otherwise don't set LLVM_DIR @@ -67,10 +68,10 @@ Build="${PTAOBJTY}-build" # Add LLVM & Z3 to $PATH and $LD_LIBRARY_PATH (prepend so that selected instances will be used first) export PATH=$LLVM_DIR/bin:$Z3_DIR/bin:$PATH export LD_LIBRARY_PATH=$LLVM_DIR/lib:$Z3_DIR/bin:$LD_LIBRARY_PATH -export DYLD_LIBRARY_PATH=$LLVM_DIR/lib:$Z3_DIR/bin:$DYLD_LIBRARY_PATH +export DYLD_LIBRARY_PATH=$LLVM_DIR/lib:$Z3_DIR/bin:${DYLD_LIBRARY_PATH:-} # Add compiled SVF binaries dir to $PATH export PATH=$SVF_DIR/$Build/bin:$PATH # Add compiled library directories to $LD_LIBRARY_PATH -export LD_LIBRARY_PATH=$SVF_DIR/$Build/svf:$SVF_DIR/$Build/svf-llvm:$LD_LIBRARY_PATH +export LD_LIBRARY_PATH=$SVF_DIR/$Build/svf:$SVF_DIR/$Build/svf-llvm:${LD_LIBRARY_PATH:-} diff --git a/svf-llvm/CMakeLists.txt b/svf-llvm/CMakeLists.txt index 53608f6629..b00caefe21 100644 --- a/svf-llvm/CMakeLists.txt +++ b/svf-llvm/CMakeLists.txt @@ -42,22 +42,30 @@ if(LLVM_LINK_LLVM_DYLIB) endif() else() message(STATUS "Linking to separate LLVM static libraries") - llvm_map_components_to_libnames( - llvm_libs - analysis - bitwriter - core - instcombine - instrumentation - ipo - irreader - linker - scalaropts - support - target - transformutils - demangle + # Define base LLVM components + set(llvm_components + analysis + bitwriter + core + instcombine + instrumentation + ipo + irreader + linker + scalaropts + support + target + transformutils + demangle ) + + # Conditionally add 'passes' for macOS + if(CMAKE_SYSTEM_NAME STREQUAL "Darwin") + list(APPEND llvm_components passes) + endif() + + # Map components to library names + llvm_map_components_to_libnames(llvm_libs ${llvm_components}) endif() # Make the "add_llvm_library()" command available and configure LLVM/CMake diff --git a/svf-llvm/include/SVF-LLVM/BasicTypes.h b/svf-llvm/include/SVF-LLVM/BasicTypes.h index 20cd8fc49c..467eccf9d3 100644 --- a/svf-llvm/include/SVF-LLVM/BasicTypes.h +++ b/svf-llvm/include/SVF-LLVM/BasicTypes.h @@ -72,8 +72,10 @@ typedef llvm::GlobalObject GlobalObject; typedef llvm::Use Use; typedef llvm::ModulePass ModulePass; typedef llvm::IRBuilder<> IRBuilder; -#if LLVM_VERSION_MAJOR >= 12 +#if LLVM_VERSION_MAJOR >= 12 && LLVM_VERSION_MAJOR <= 16 typedef llvm::UnifyFunctionExitNodesLegacyPass UnifyFunctionExitNodes; +#elif LLVM_VERSION_MAJOR > 16 +typedef llvm::UnifyFunctionExitNodesPass UnifyFunctionExitNodes; #else typedef llvm::UnifyFunctionExitNodes UnifyFunctionExitNodes; #endif diff --git a/svf-llvm/include/SVF-LLVM/BreakConstantExpr.h b/svf-llvm/include/SVF-LLVM/BreakConstantExpr.h index 5725546516..200944d4f5 100644 --- a/svf-llvm/include/SVF-LLVM/BreakConstantExpr.h +++ b/svf-llvm/include/SVF-LLVM/BreakConstantExpr.h @@ -15,6 +15,10 @@ #ifndef BREAKCONSTANTGEPS_H #define BREAKCONSTANTGEPS_H +#if LLVM_VERSION_MAJOR > 16 +#include // For NPM infrastructure +#include // For UnifyFunctionExitNodesPass +#endif namespace SVF { @@ -77,15 +81,34 @@ class MergeFunctionRets : public ModulePass const Function& fun = *iter; if(fun.isDeclaration()) continue; +#if LLVM_VERSION_MAJOR >= 12 && LLVM_VERSION_MAJOR <= 16 getUnifyExit(fun)->runOnFunction(const_cast(fun)); +#else + // New Pass Manager (LLVM 20+) + llvm::PassBuilder PB; + llvm::FunctionPassManager FPM; + FPM.addPass(llvm::UnifyFunctionExitNodesPass()); + llvm::LoopAnalysisManager LAM; + llvm::FunctionAnalysisManager FAM; + llvm::CGSCCAnalysisManager CGAM; + llvm::ModuleAnalysisManager MAM; + PB.registerModuleAnalyses(MAM); + PB.registerCGSCCAnalyses(CGAM); + PB.registerFunctionAnalyses(FAM); + PB.registerLoopAnalyses(LAM); + PB.crossRegisterProxies(LAM, FAM, CGAM, MAM); + FPM.run(const_cast(fun), FAM); +#endif } } +#if LLVM_VERSION_MAJOR >= 12 && LLVM_VERSION_MAJOR <= 16 /// Get Unified Exit basic block node inline UnifyFunctionExitNodes* getUnifyExit(const Function& fn) { assert(!fn.isDeclaration() && "external function does not have DF"); return &getAnalysis(const_cast(fn)); } +#endif }; } // End namespace SVF diff --git a/svf-llvm/include/SVF-LLVM/LLVMUtil.h b/svf-llvm/include/SVF-LLVM/LLVMUtil.h index 1f0127f02a..bb3d6f636a 100644 --- a/svf-llvm/include/SVF-LLVM/LLVMUtil.h +++ b/svf-llvm/include/SVF-LLVM/LLVMUtil.h @@ -310,6 +310,7 @@ inline const ConstantExpr* isUnaryConstantExpr(const Value* val) } //@} +#if LLVM_VERSION_MAJOR >= 12 && LLVM_VERSION_MAJOR <= 16 inline static DataLayout* getDataLayout(Module* mod) { static DataLayout *dl = nullptr; @@ -317,6 +318,14 @@ inline static DataLayout* getDataLayout(Module* mod) dl = new DataLayout(mod); return dl; } +#else +inline static std::unique_ptr getDataLayout(Module* mod) +{ + if (mod) + return std::make_unique(mod->getDataLayout()); + return nullptr; +} +#endif /// Get the next instructions following control flow void getNextInsts(const Instruction* curInst, diff --git a/svf-llvm/lib/LLVMModule.cpp b/svf-llvm/lib/LLVMModule.cpp index 6e82161c39..00932e8e6a 100644 --- a/svf-llvm/lib/LLVMModule.cpp +++ b/svf-llvm/lib/LLVMModule.cpp @@ -43,6 +43,11 @@ #include "Graphs/CallGraph.h" #include "Util/CallGraphBuilder.h" +#if LLVM_VERSION_MAJOR > 16 +#include +#include +#endif + using namespace std; using namespace SVF; @@ -265,7 +270,23 @@ void LLVMModuleSet::prePassSchedule() Function &fun = *F; if (fun.isDeclaration()) continue; +#if LLVM_VERSION_MAJOR <= 16 p2->runOnFunction(fun); +#else + llvm::PassBuilder PB; + llvm::FunctionPassManager FPM; + FPM.addPass(llvm::UnifyFunctionExitNodesPass()); + llvm::LoopAnalysisManager LAM; + llvm::FunctionAnalysisManager FAM; + llvm::CGSCCAnalysisManager CGAM; + llvm::ModuleAnalysisManager MAM; + PB.registerModuleAnalyses(MAM); + PB.registerCGSCCAnalyses(CGAM); + PB.registerFunctionAnalyses(FAM); + PB.registerLoopAnalyses(LAM); + PB.crossRegisterProxies(LAM, FAM, CGAM, MAM); + FPM.run(fun, FAM); +#endif } } } @@ -496,11 +517,19 @@ void LLVMModuleSet::addSVFMain() // Collect ctor and dtor functions for (const GlobalVariable& global : mod.globals()) { +#if LLVM_VERSION_MAJOR >= 12 && LLVM_VERSION_MAJOR <= 16 if (global.getName().equals(SVF_GLOBAL_CTORS) && global.hasInitializer()) +#else + if ((global.getName() == SVF_GLOBAL_CTORS) && global.hasInitializer()) +#endif { ctor_funcs = getLLVMGlobalFunctions(&global); } +#if LLVM_VERSION_MAJOR >= 12 && LLVM_VERSION_MAJOR <= 16 else if (global.getName().equals(SVF_GLOBAL_DTORS) && global.hasInitializer()) +#else + else if ((global.getName() == SVF_GLOBAL_DTORS) && global.hasInitializer()) +#endif { dtor_funcs = getLLVMGlobalFunctions(&global); } @@ -511,9 +540,17 @@ void LLVMModuleSet::addSVFMain() { auto funName = func.getName(); +#if LLVM_VERSION_MAJOR >= 12 && LLVM_VERSION_MAJOR <= 16 assert(!funName.equals(SVF_MAIN_FUNC_NAME) && SVF_MAIN_FUNC_NAME " already defined"); +#else + assert(!(funName == SVF_MAIN_FUNC_NAME) && SVF_MAIN_FUNC_NAME " already defined"); +#endif +#if LLVM_VERSION_MAJOR >= 12 && LLVM_VERSION_MAJOR <= 16 if (funName.equals("main")) +#else + if (funName == "main") +#endif { orgMain = &func; mainMod = &mod; @@ -1505,4 +1542,4 @@ bool LLVMModuleSet::is_ext(const Function* F) return false; else return !getExtFuncAnnotations(F).empty(); -} \ No newline at end of file +} diff --git a/svf-llvm/lib/LLVMUtil.cpp b/svf-llvm/lib/LLVMUtil.cpp index 51989778a1..2159b92944 100644 --- a/svf-llvm/lib/LLVMUtil.cpp +++ b/svf-llvm/lib/LLVMUtil.cpp @@ -33,6 +33,10 @@ #include #include "SVF-LLVM/LLVMModule.h" +#if LLVM_VERSION_MAJOR > 16 +#include +#include +#endif using namespace SVF; @@ -461,6 +465,7 @@ const std::string LLVMUtil::getSourceLoc(const Value* val ) { if (SVFUtil::isa(inst)) { +#if LLVM_VERSION_MAJOR >= 12 && LLVM_VERSION_MAJOR <= 16 for (llvm::DbgInfoIntrinsic *DII : FindDbgDeclareUses(const_cast(inst))) { if (llvm::DbgDeclareInst *DDI = SVFUtil::dyn_cast(DII)) @@ -470,6 +475,15 @@ const std::string LLVMUtil::getSourceLoc(const Value* val ) break; } } +#else + // for LLVM 20+ + for (llvm::DbgDeclareInst *DDI : llvm::findDbgDeclares(const_cast(inst))) + { + llvm::DIVariable *DIVar = SVFUtil::cast(DDI->getVariable()); + rawstr << "\"ln\": " << DIVar->getLine() << ", \"fl\": \"" << DIVar->getFilename().str() << "\""; + break; + } +#endif } else if (MDNode *N = inst->getMetadata("dbg")) // Here I is an LLVM instruction { diff --git a/svf-llvm/lib/SVFIRBuilder.cpp b/svf-llvm/lib/SVFIRBuilder.cpp index 527e4878bf..1c491dbe45 100644 --- a/svf-llvm/lib/SVFIRBuilder.cpp +++ b/svf-llvm/lib/SVFIRBuilder.cpp @@ -40,6 +40,10 @@ #include "Util/Options.h" #include "Util/SVFUtil.h" +#if LLVM_VERSION_MAJOR > 16 +#include +#endif + using namespace std; using namespace SVF; using namespace SVFUtil; @@ -274,7 +278,11 @@ void SVFIRBuilder::initDomTree(FunObjVar* svffun, const Function* fun) for (DominanceFrontierBase::const_iterator dfIter = df.begin(), eDfIter = df.end(); dfIter != eDfIter; dfIter++) { const BasicBlock* keyBB = dfIter->first; +#if LLVM_VERSION_MAJOR > 16 + const llvm::SetVector& domSet = dfIter->second; +#else const std::set& domSet = dfIter->second; +#endif Set& valueBasicBlocks = dfBBsMap[llvmModuleSet()->getSVFBasicBlock(keyBB)]; for (const BasicBlock* bbValue:domSet) { @@ -642,7 +650,11 @@ bool SVFIRBuilder::computeGepOffset(const User *V, AccessPath& ap) assert(V); const llvm::GEPOperator *gepOp = SVFUtil::dyn_cast(V); +#if LLVM_VERSION_MAJOR <= 16 DataLayout * dataLayout = getDataLayout(llvmModuleSet()->getMainLLVMModule()); +#else + std::unique_ptr dataLayout = getDataLayout(llvmModuleSet()->getMainLLVMModule()); +#endif llvm::APInt byteOffset(dataLayout->getIndexSizeInBits(gepOp->getPointerAddressSpace()),0,true); if(gepOp && dataLayout && gepOp->accumulateConstantOffset(*dataLayout,byteOffset)) { diff --git a/svf-llvm/tools/Example/svf-ex.cpp b/svf-llvm/tools/Example/svf-ex.cpp index 7e6953cd2a..5d4f6444d1 100644 --- a/svf-llvm/tools/Example/svf-ex.cpp +++ b/svf-llvm/tools/Example/svf-ex.cpp @@ -213,7 +213,9 @@ int main(int argc, char ** argv) LLVMModuleSet::getLLVMModuleSet()->dumpModulesToFile(".svf.bc"); SVF::LLVMModuleSet::releaseLLVMModuleSet(); +#if LLVM_VERSION_MAJOR >= 12 && LLVM_VERSION_MAJOR <= 16 llvm::llvm_shutdown(); +#endif return 0; }