From d2c7bcbe985825278f982ecdcb2eb9e675ecf610 Mon Sep 17 00:00:00 2001 From: mxHuber Date: Wed, 15 May 2024 20:25:10 +0200 Subject: [PATCH 01/78] replaced llvm-14 with llvm-15 in relevant files --- Dockerfile | 25 +++++++++++++------------ bootstrap.sh | 5 +++-- cmake/add_llvm.cmake | 4 +++- cmake/phasar_macros.cmake | 10 ++-------- utils/install-llvm-only.sh | 8 ++++++++ 5 files changed, 29 insertions(+), 23 deletions(-) mode change 100755 => 100644 bootstrap.sh create mode 100644 utils/install-llvm-only.sh diff --git a/Dockerfile b/Dockerfile index 2bed11717..45cb80d40 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ FROM ubuntu:22.04 -ARG LLVM_INSTALL_DIR="/usr/local/llvm-14" +ARG LLVM_INSTALL_DIR="/usr/local/llvm-15" LABEL Name=phasar Version=2403 RUN apt -y update && apt install bash sudo -y @@ -24,17 +24,17 @@ RUN apt-get update && \ apt-get install -y software-properties-common RUN apt-key adv --fetch-keys https://apt.llvm.org/llvm-snapshot.gpg.key && \ - add-apt-repository -y 'deb http://apt.llvm.org/focal/ llvm-toolchain-focal-14 main' && \ + add-apt-repository -y 'deb http://apt.llvm.org/focal/ llvm-toolchain-focal-15 main' && \ apt-get update && \ apt-get -y install --no-install-recommends \ - clang-14 \ - llvm-14-dev \ - libllvm14 \ - libclang-common-14-dev \ - libclang-14-dev \ - libclang-cpp14-dev \ - clang-tidy-14 \ - libclang-rt-14-dev + clang-15 \ + llvm-15-dev \ + libllvm15 \ + libclang-common-15-dev \ + libclang-15-dev \ + libclang-cpp15-dev \ + clang-tidy-15 \ + libclang-rt-15-dev RUN pip3 install Pygments pyyaml @@ -43,8 +43,8 @@ RUN pip3 install Pygments pyyaml # installing wllvm RUN pip3 install wllvm -ENV CC=/usr/bin/clang-14 -ENV CXX=/usr/bin/clang++-14 +ENV CC=/usr/bin/clang-15 +ENV CXX=/usr/bin/clang++-15 COPY . /usr/src/phasar @@ -59,3 +59,4 @@ RUN mkdir -p build && cd build && \ cmake --build . ENTRYPOINT [ "./build/tools/phasar-cli/phasar-cli" ] + diff --git a/bootstrap.sh b/bootstrap.sh old mode 100755 new mode 100644 index 345d88570..5c8b6db62 --- 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-14" +LLVM_INSTALL_DIR="/usr/local/llvm-15" NUM_THREADS=$(nproc) -LLVM_RELEASE=llvmorg-14.0.6 +LLVM_RELEASE=llvmorg-15.0.7 DO_UNIT_TEST=true DO_INSTALL=false BUILD_TYPE=Release @@ -216,3 +216,4 @@ if ${DO_INSTALL}; then fi echo "done." + diff --git a/cmake/add_llvm.cmake b/cmake/add_llvm.cmake index 7cf3ceb94..107deac11 100644 --- a/cmake/add_llvm.cmake +++ b/cmake/add_llvm.cmake @@ -2,7 +2,8 @@ macro(add_llvm) if (NOT PHASAR_IN_TREE) # Only search for LLVM if we build out of tree - find_package(LLVM 14 REQUIRED CONFIG) + set(LLVM 15 "/usr/local/llvm-15") + find_package(LLVM 15 REQUIRED CONFIG) find_library(LLVM_LIBRARY NAMES LLVM PATHS ${LLVM_LIBRARY_DIRS} NO_DEFAULT_PATH) if(USE_LLVM_FAT_LIB AND ${LLVM_LIBRARY} STREQUAL "LLVM_LIBRARY-NOTFOUND") @@ -94,3 +95,4 @@ macro(add_clang) ) endif() endmacro(add_clang) + diff --git a/cmake/phasar_macros.cmake b/cmake/phasar_macros.cmake index 2ce5cd45f..1c20a9196 100644 --- a/cmake/phasar_macros.cmake +++ b/cmake/phasar_macros.cmake @@ -76,13 +76,6 @@ function(generate_ll_file) set(GEN_C_FLAGS -fno-discard-value-names -emit-llvm -S -w) set(GEN_CMD_COMMENT "[LL]") - if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 15) - list(APPEND GEN_CXX_FLAGS -Xclang -no-opaque-pointers) - endif() - if (CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 15) - list(APPEND GEN_C_FLAGS -Xclang -no-opaque-pointers) - endif() - if(GEN_LL_MEM2REG) list(APPEND GEN_CXX_FLAGS -Xclang -disable-O0-optnone) list(APPEND GEN_C_FLAGS -Xclang -disable-O0-optnone) @@ -128,7 +121,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 -opaque-pointers=0 ${test_code_ll_file} -o ${test_code_ll_file} + COMMAND ${CMAKE_CXX_COMPILER_LAUNCHER} opt -mem2reg -S ${test_code_ll_file} -o ${test_code_ll_file} COMMENT ${GEN_CMD_COMMENT} DEPENDS ${GEN_LL_FILE} VERBATIM @@ -261,3 +254,4 @@ macro(subdirlist result curdir) set(${result} ${dirlist}) endmacro(subdirlist) + diff --git a/utils/install-llvm-only.sh b/utils/install-llvm-only.sh new file mode 100644 index 000000000..fe0b2d177 --- /dev/null +++ b/utils/install-llvm-only.sh @@ -0,0 +1,8 @@ +NUM_THREADS=$(nproc) +LLVM_INSTALL_DIR="/usr/local/llvm-15" +LLVM_RELEASE=llvmorg-15.0.7 + +# installing LLVM +tmp_dir=$(mktemp -d "llvm-build.XXXXXXXX" --tmpdir) +./utils/install-llvm.sh "${NUM_THREADS}" "${tmp_dir}" ${LLVM_INSTALL_DIR} ${LLVM_RELEASE} +rm -rf "${tmp_dir}" From 8056664b546e90fbd2422d26652492fc2fc91cfc Mon Sep 17 00:00:00 2001 From: Fabian Schiebel Date: Fri, 17 May 2024 09:46:24 +0200 Subject: [PATCH 02/78] some changes --- include/phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h | 8 ++++---- .../phasar/PhasarLLVM/TaintConfig/TaintConfigData.h | 6 +++--- .../PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.h | 5 ++++- lib/PhasarLLVM/ControlFlow/LLVMBasedICFG.cpp | 8 ++++---- .../ControlFlow/LLVMBasedICFGGlobalsImpl.cpp | 10 ++++++---- lib/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.cpp | 11 ++++++++++- 6 files changed, 31 insertions(+), 17 deletions(-) diff --git a/include/phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h b/include/phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h index 92e964e14..b52a11d9e 100644 --- a/include/phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h +++ b/include/phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h @@ -95,7 +95,7 @@ class LLVMBasedICFG : public LLVMBasedCFG, public ICFGBase { bool IncludeGlobals = true); /// Creates an ICFG with an already given call-graph - explicit LLVMBasedICFG(CallGraph CG, LLVMProjectIRDB *IRDB, + explicit LLVMBasedICFG(CallGraph CG, const LLVMProjectIRDB *IRDB, LLVMTypeHierarchy *TH = nullptr); explicit LLVMBasedICFG(LLVMProjectIRDB *IRDB, @@ -133,7 +133,7 @@ class LLVMBasedICFG : public LLVMBasedCFG, public ICFGBase { } /// Gets the underlying IRDB - [[nodiscard]] LLVMProjectIRDB *getIRDB() const noexcept { return IRDB; } + [[nodiscard]] const LLVMProjectIRDB *getIRDB() const noexcept { return IRDB; } /// Returns true, if a function was generated by phasar. [[nodiscard]] static bool isPhasarGenerated(const llvm::Function &) noexcept; @@ -161,7 +161,7 @@ class LLVMBasedICFG : public LLVMBasedCFG, public ICFGBase { } [[nodiscard]] llvm::Function *buildCRuntimeGlobalCtorsDtorsModel( - llvm::Module &M, llvm::ArrayRef UserEntryPoints); + LLVMProjectIRDB &IRDB, llvm::ArrayRef UserEntryPoints); void initialize(LLVMProjectIRDB *IRDB, Resolver &CGResolver, llvm::ArrayRef EntryPoints, @@ -170,7 +170,7 @@ class LLVMBasedICFG : public LLVMBasedCFG, public ICFGBase { // --- CallGraph CG; - LLVMProjectIRDB *IRDB = nullptr; + const LLVMProjectIRDB *IRDB = nullptr; MaybeUniquePtr TH; }; diff --git a/include/phasar/PhasarLLVM/TaintConfig/TaintConfigData.h b/include/phasar/PhasarLLVM/TaintConfig/TaintConfigData.h index ba92829e5..3e255c2fc 100644 --- a/include/phasar/PhasarLLVM/TaintConfig/TaintConfigData.h +++ b/include/phasar/PhasarLLVM/TaintConfig/TaintConfigData.h @@ -22,9 +22,9 @@ struct FunctionData { std::string Name; TaintCategory ReturnCat{}; - std::vector SourceValues; - std::vector SinkValues; - std::vector SanitizerValues; + std::vector SourceValues{}; + std::vector SinkValues{}; + std::vector SanitizerValues{}; bool HasAllSinkParam = false; }; diff --git a/include/phasar/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.h b/include/phasar/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.h index c5b744e12..39d16892d 100644 --- a/include/phasar/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.h +++ b/include/phasar/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.h @@ -139,7 +139,7 @@ class LLVMTypeHierarchy * given ProjectIRCompiledDB. * @param IRDB ProjectIRCompiledDB object. */ - LLVMTypeHierarchy(LLVMProjectIRDB &IRDB); + LLVMTypeHierarchy(const LLVMProjectIRDB &IRDB); /** * @brief Creates a LLVMStructTypeHierarchy based on the @@ -196,6 +196,9 @@ class LLVMTypeHierarchy [[nodiscard]] const LLVMVFTable * getVFTable(const llvm::StructType *Type) const override; + [[nodiscard]] const llvm::GlobalVariable * + getVFTableGlobal(const llvm::StructType *Type) const; + [[nodiscard]] inline size_t size() const override { return boost::num_vertices(TypeGraph); }; diff --git a/lib/PhasarLLVM/ControlFlow/LLVMBasedICFG.cpp b/lib/PhasarLLVM/ControlFlow/LLVMBasedICFG.cpp index eadc987db..92f1ab1ad 100644 --- a/lib/PhasarLLVM/ControlFlow/LLVMBasedICFG.cpp +++ b/lib/PhasarLLVM/ControlFlow/LLVMBasedICFG.cpp @@ -98,8 +98,8 @@ void LLVMBasedICFG::Builder::initGlobalsAndWorkList(LLVMBasedICFG *ICFG, bool IncludeGlobals) { FunctionWL.reserve(IRDB->getNumFunctions()); if (IncludeGlobals) { - const auto *GlobCtor = ICFG->buildCRuntimeGlobalCtorsDtorsModel( - *IRDB->getModule(), UserEntryPoints); + const auto *GlobCtor = + ICFG->buildCRuntimeGlobalCtorsDtorsModel(*IRDB, UserEntryPoints); FunctionWL.push_back(GlobCtor); } else { FunctionWL.insert(FunctionWL.end(), UserEntryPoints.begin(), @@ -374,8 +374,8 @@ LLVMBasedICFG::LLVMBasedICFG(LLVMProjectIRDB *IRDB, Resolver &CGResolver, initialize(IRDB, CGResolver, EntryPoints, TH, S, IncludeGlobals); } -LLVMBasedICFG::LLVMBasedICFG(CallGraph CG, LLVMProjectIRDB *IRDB, - LLVMTypeHierarchy *TH) +LLVMBasedICFG::LLVMBasedICFG(CallGraph CG, + const LLVMProjectIRDB *IRDB, LLVMTypeHierarchy *TH) : CG(std::move(CG)), IRDB(IRDB), TH(TH) { if (!TH) { this->TH = std::make_unique(*IRDB); diff --git a/lib/PhasarLLVM/ControlFlow/LLVMBasedICFGGlobalsImpl.cpp b/lib/PhasarLLVM/ControlFlow/LLVMBasedICFGGlobalsImpl.cpp index eeb0b2393..1a948cbac 100644 --- a/lib/PhasarLLVM/ControlFlow/LLVMBasedICFGGlobalsImpl.cpp +++ b/lib/PhasarLLVM/ControlFlow/LLVMBasedICFGGlobalsImpl.cpp @@ -218,18 +218,20 @@ static std::pair buildCRuntimeGlobalDtorsModel( } llvm::Function *LLVMBasedICFG::buildCRuntimeGlobalCtorsDtorsModel( - llvm::Module &M, llvm::ArrayRef UserEntryPoints) { + LLVMProjectIRDB &IRDB, llvm::ArrayRef UserEntryPoints) { + auto &M = *IRDB.getModule(); + auto GlobalCtors = collectGlobalCtors(M); auto GlobalDtors = collectGlobalDtors(M); auto *RegisteredDtorCaller = collectRegisteredDtors(GlobalDtors, M); if (RegisteredDtorCaller) { - IRDB->insertFunction(RegisteredDtorCaller); + IRDB.insertFunction(RegisteredDtorCaller); } auto [GlobalCleanupFn, Inserted] = buildCRuntimeGlobalDtorsModel(M, GlobalDtors); if (Inserted) { - IRDB->insertFunction(GlobalCleanupFn); + IRDB.insertFunction(GlobalCleanupFn); } auto &CTX = M.getContext(); @@ -335,7 +337,7 @@ llvm::Function *LLVMBasedICFG::buildCRuntimeGlobalCtorsDtorsModel( IRB.CreateRetVoid(); } - IRDB->insertFunction(GlobModel); + IRDB.insertFunction(GlobModel); ModulesToSlotTracker::updateMSTForModule(&M); return GlobModel; diff --git a/lib/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.cpp b/lib/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.cpp index bc2e32534..e9b768e6e 100644 --- a/lib/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.cpp +++ b/lib/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.cpp @@ -68,7 +68,7 @@ std::string LLVMTypeHierarchy::VertexProperties::getTypeName() const { return Type->getStructName().str(); } -LLVMTypeHierarchy::LLVMTypeHierarchy(LLVMProjectIRDB &IRDB) { +LLVMTypeHierarchy::LLVMTypeHierarchy(const LLVMProjectIRDB &IRDB) { PHASAR_LOG_LEVEL(INFO, "Construct type hierarchy"); buildLLVMTypeHierarchy(*IRDB.getModule()); } @@ -301,6 +301,15 @@ LLVMTypeHierarchy::getVFTable(const llvm::StructType *Type) const { return nullptr; } +const llvm::GlobalVariable * +LLVMTypeHierarchy::getVFTableGlobal(const llvm::StructType *Type) const { + auto Name = removeStructOrClassPrefix(*Type); + if (auto It = ClearNameTVMap.find(Name); It != ClearNameTVMap.end()) { + return It->second; + } + return nullptr; +} + void LLVMTypeHierarchy::print(llvm::raw_ostream &OS) const { OS << "Type Hierarchy:\n"; vertex_iterator UI; From 54a56bc60a076b2edfc8b5b29916fd9979bc283a Mon Sep 17 00:00:00 2001 From: Fabian Schiebel Date: Fri, 17 May 2024 10:24:24 +0200 Subject: [PATCH 03/78] more efficient call-graph --- .../ControlFlow/Resolver/CHAResolver.h | 2 + .../ControlFlow/Resolver/DTAResolver.h | 4 +- .../ControlFlow/Resolver/NOResolver.h | 2 + .../ControlFlow/Resolver/OTFResolver.h | 2 + .../ControlFlow/Resolver/RTAResolver.h | 2 + .../ControlFlow/Resolver/Resolver.h | 6 ++ lib/PhasarLLVM/ControlFlow/LLVMBasedICFG.cpp | 59 +++++++++++-------- 7 files changed, 50 insertions(+), 27 deletions(-) diff --git a/include/phasar/PhasarLLVM/ControlFlow/Resolver/CHAResolver.h b/include/phasar/PhasarLLVM/ControlFlow/Resolver/CHAResolver.h index 46c752d3e..66c6777d6 100644 --- a/include/phasar/PhasarLLVM/ControlFlow/Resolver/CHAResolver.h +++ b/include/phasar/PhasarLLVM/ControlFlow/Resolver/CHAResolver.h @@ -33,6 +33,8 @@ class CHAResolver : public Resolver { FunctionSetTy resolveVirtualCall(const llvm::CallBase *CallSite) override; + [[nodiscard]] bool isIndependent() const noexcept override { return true; } + [[nodiscard]] std::string str() const override; }; } // namespace psr diff --git a/include/phasar/PhasarLLVM/ControlFlow/Resolver/DTAResolver.h b/include/phasar/PhasarLLVM/ControlFlow/Resolver/DTAResolver.h index 3cfd888ca..f539e1a57 100644 --- a/include/phasar/PhasarLLVM/ControlFlow/Resolver/DTAResolver.h +++ b/include/phasar/PhasarLLVM/ControlFlow/Resolver/DTAResolver.h @@ -20,7 +20,7 @@ #include "phasar/PhasarLLVM/ControlFlow/Resolver/CHAResolver.h" #include "phasar/PhasarLLVM/Pointer/TypeGraphs/CachedTypeGraph.h" // To switch the TypeGraph -//#include "phasar/PhasarLLVM/Pointer/TypeGraphs/LazyTypeGraph.h" +// #include "phasar/PhasarLLVM/Pointer/TypeGraphs/LazyTypeGraph.h" #include @@ -63,6 +63,8 @@ class DTAResolver : public CHAResolver { void otherInst(const llvm::Instruction *Inst) override; + [[nodiscard]] bool isIndependent() const noexcept override { return true; } + [[nodiscard]] std::string str() const override; }; } // namespace psr diff --git a/include/phasar/PhasarLLVM/ControlFlow/Resolver/NOResolver.h b/include/phasar/PhasarLLVM/ControlFlow/Resolver/NOResolver.h index 1b23477ee..ed1ad0612 100644 --- a/include/phasar/PhasarLLVM/ControlFlow/Resolver/NOResolver.h +++ b/include/phasar/PhasarLLVM/ControlFlow/Resolver/NOResolver.h @@ -43,6 +43,8 @@ class NOResolver final : public Resolver { FunctionSetTy resolveFunctionPointer(const llvm::CallBase *CallSite) override; + [[nodiscard]] bool isIndependent() const noexcept override { return true; } + void otherInst(const llvm::Instruction *Inst) override; [[nodiscard]] std::string str() const override; diff --git a/include/phasar/PhasarLLVM/ControlFlow/Resolver/OTFResolver.h b/include/phasar/PhasarLLVM/ControlFlow/Resolver/OTFResolver.h index 13c75d8f3..d32834194 100644 --- a/include/phasar/PhasarLLVM/ControlFlow/Resolver/OTFResolver.h +++ b/include/phasar/PhasarLLVM/ControlFlow/Resolver/OTFResolver.h @@ -65,6 +65,8 @@ class OTFResolver : public Resolver { getActualFormalPointerPairs(const llvm::CallBase *CallSite, const llvm::Function *CalleeTarget); + [[nodiscard]] bool isIndependent() const noexcept override { return false; } + [[nodiscard]] std::string str() const override; }; } // namespace psr diff --git a/include/phasar/PhasarLLVM/ControlFlow/Resolver/RTAResolver.h b/include/phasar/PhasarLLVM/ControlFlow/Resolver/RTAResolver.h index 5b67a4c92..85aa0ca31 100644 --- a/include/phasar/PhasarLLVM/ControlFlow/Resolver/RTAResolver.h +++ b/include/phasar/PhasarLLVM/ControlFlow/Resolver/RTAResolver.h @@ -37,6 +37,8 @@ class RTAResolver : public CHAResolver { FunctionSetTy resolveVirtualCall(const llvm::CallBase *CallSite) override; + [[nodiscard]] bool isIndependent() const noexcept override { return true; } + [[nodiscard]] std::string str() const override; private: diff --git a/include/phasar/PhasarLLVM/ControlFlow/Resolver/Resolver.h b/include/phasar/PhasarLLVM/ControlFlow/Resolver/Resolver.h index 73adbd37e..b453b1b62 100644 --- a/include/phasar/PhasarLLVM/ControlFlow/Resolver/Resolver.h +++ b/include/phasar/PhasarLLVM/ControlFlow/Resolver/Resolver.h @@ -80,6 +80,12 @@ class Resolver { virtual void otherInst(const llvm::Instruction *Inst); + /// Whether the ICFG needs to reconsider all dynamic call-sites once there + /// have been changes through handlePossibleTargets(). + /// + /// Make true for performance (may be less sound then) + [[nodiscard]] virtual bool isIndependent() const noexcept { return false; } + [[nodiscard]] virtual std::string str() const = 0; static std::unique_ptr create(CallGraphAnalysisType Ty, diff --git a/lib/PhasarLLVM/ControlFlow/LLVMBasedICFG.cpp b/lib/PhasarLLVM/ControlFlow/LLVMBasedICFG.cpp index 92f1ab1ad..d3cfecee0 100644 --- a/lib/PhasarLLVM/ControlFlow/LLVMBasedICFG.cpp +++ b/lib/PhasarLLVM/ControlFlow/LLVMBasedICFG.cpp @@ -116,6 +116,8 @@ auto LLVMBasedICFG::Builder::buildCallGraph(Soundness /*S*/) "Starting CallGraphAnalysisType: " << Res->str()); VisitedFunctions.reserve(IRDB->getNumFunctions()); + bool RequiresSecondFixpoint = !Res->isIndependent(); + bool FixpointReached; do { @@ -128,8 +130,10 @@ auto LLVMBasedICFG::Builder::buildCallGraph(Soundness /*S*/) /// XXX This can probably be done more efficiently. /// However, we cannot just work on the IndirectCalls-delta as we are /// mutating the points-to-info on the fly - for (auto [CS, _] : IndirectCalls) { - FixpointReached &= !constructDynamicCall(CS); + if (RequiresSecondFixpoint) { + for (auto [CS, _] : IndirectCalls) { + FixpointReached &= !constructDynamicCall(CS); + } } } while (!FixpointReached); @@ -150,6 +154,27 @@ auto LLVMBasedICFG::Builder::buildCallGraph(Soundness /*S*/) return CGBuilder.consumeCallGraph(); } +static bool internalIsVirtualFunctionCall(const llvm::Instruction *Inst, + const LLVMTypeHierarchy &TH) { + assert(Inst != nullptr); + const auto *CallSite = llvm::dyn_cast(Inst); + if (!CallSite) { + return false; + } + // check potential receiver type + const auto *RecType = getReceiverType(CallSite); + if (!RecType) { + return false; + } + if (!TH.hasType(RecType)) { + return false; + } + if (!TH.hasVFTable(RecType)) { + return false; + } + return getVFTIndex(CallSite) >= 0; +} + bool LLVMBasedICFG::Builder::processFunction(const llvm::Function *F) { PHASAR_LOG_LEVEL_CAT(DEBUG, "LLVMBasedICFG", "Walking in function: " << F->getName()); @@ -198,11 +223,14 @@ bool LLVMBasedICFG::Builder::processFunction(const llvm::Function *F) { PHASAR_LOG_LEVEL_CAT(DEBUG, "LLVMBasedICFG", "Found dynamic call-site: " << " " << llvmIRToString(CS)); - IndirectCalls[CS] = 0; - std::ignore = CGBuilder.addInstructionVertex(CS); + assert(TH != nullptr); + PossibleTargets = internalIsVirtualFunctionCall(CS, *TH) + ? Res->resolveVirtualCall(CS) + : Res->resolveFunctionPointer(CS); + + IndirectCalls[CS] = PossibleTargets.size(); FixpointReached = false; - continue; } } @@ -232,27 +260,6 @@ bool LLVMBasedICFG::Builder::processFunction(const llvm::Function *F) { return FixpointReached; } -static bool internalIsVirtualFunctionCall(const llvm::Instruction *Inst, - const LLVMTypeHierarchy &TH) { - assert(Inst != nullptr); - const auto *CallSite = llvm::dyn_cast(Inst); - if (!CallSite) { - return false; - } - // check potential receiver type - const auto *RecType = getReceiverType(CallSite); - if (!RecType) { - return false; - } - if (!TH.hasType(RecType)) { - return false; - } - if (!TH.hasVFTable(RecType)) { - return false; - } - return getVFTIndex(CallSite) >= 0; -} - bool LLVMBasedICFG::Builder::constructDynamicCall(const llvm::Instruction *CS) { bool NewTargetsFound = false; // Find vertex of calling function. From 4fd9d39731500abfc2cdafc20a5a1a0920f9e39a Mon Sep 17 00:00:00 2001 From: Fabian Schiebel Date: Fri, 17 May 2024 14:54:25 +0200 Subject: [PATCH 04/78] String-nbased vtable getter + CG-test with dbg info --- .../phasar/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.h | 3 +++ lib/PhasarLLVM/ControlFlow/LLVMBasedICFG.cpp | 1 - lib/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.cpp | 8 +++++++- test/llvm_test_code/call_graphs/CMakeLists.txt | 4 ++++ 4 files changed, 14 insertions(+), 2 deletions(-) diff --git a/include/phasar/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.h b/include/phasar/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.h index 39d16892d..0e1f3b031 100644 --- a/include/phasar/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.h +++ b/include/phasar/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.h @@ -199,6 +199,9 @@ class LLVMTypeHierarchy [[nodiscard]] const llvm::GlobalVariable * getVFTableGlobal(const llvm::StructType *Type) const; + [[nodiscard]] const llvm::GlobalVariable * + getVFTableGlobal(const std::string &ClearTypeName) const; + [[nodiscard]] inline size_t size() const override { return boost::num_vertices(TypeGraph); }; diff --git a/lib/PhasarLLVM/ControlFlow/LLVMBasedICFG.cpp b/lib/PhasarLLVM/ControlFlow/LLVMBasedICFG.cpp index d3cfecee0..7ca738f67 100644 --- a/lib/PhasarLLVM/ControlFlow/LLVMBasedICFG.cpp +++ b/lib/PhasarLLVM/ControlFlow/LLVMBasedICFG.cpp @@ -246,7 +246,6 @@ bool LLVMBasedICFG::Builder::processFunction(const llvm::Function *F) { // the current function for (const auto *PossibleTarget : PossibleTargets) { CGBuilder.addCallEdge(CS, CallSiteId, PossibleTarget); - FunctionWL.push_back(PossibleTarget); } diff --git a/lib/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.cpp b/lib/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.cpp index e9b768e6e..39cd86ed8 100644 --- a/lib/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.cpp +++ b/lib/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.cpp @@ -304,7 +304,13 @@ LLVMTypeHierarchy::getVFTable(const llvm::StructType *Type) const { const llvm::GlobalVariable * LLVMTypeHierarchy::getVFTableGlobal(const llvm::StructType *Type) const { auto Name = removeStructOrClassPrefix(*Type); - if (auto It = ClearNameTVMap.find(Name); It != ClearNameTVMap.end()) { + return getVFTableGlobal(Name); +} + +const llvm::GlobalVariable * +LLVMTypeHierarchy::getVFTableGlobal(const std::string &ClearTypeName) const { + if (auto It = ClearNameTVMap.find(ClearTypeName); + It != ClearNameTVMap.end()) { return It->second; } return nullptr; diff --git a/test/llvm_test_code/call_graphs/CMakeLists.txt b/test/llvm_test_code/call_graphs/CMakeLists.txt index 9b1b58ebe..9a4557b17 100644 --- a/test/llvm_test_code/call_graphs/CMakeLists.txt +++ b/test/llvm_test_code/call_graphs/CMakeLists.txt @@ -36,3 +36,7 @@ set(NoMem2regSources foreach(TEST_SRC ${NoMem2regSources}) generate_ll_file(FILE ${TEST_SRC}) endforeach(TEST_SRC) + +foreach(TEST_SRC ${NoMem2regSources}) + generate_ll_file(FILE ${TEST_SRC} DEBUG) +endforeach(TEST_SRC) From 70734dcfb388b3bdc4e4e568375598c12810001f Mon Sep 17 00:00:00 2001 From: Fabian Schiebel Date: Tue, 21 May 2024 10:55:23 +0200 Subject: [PATCH 05/78] minor in CG --- lib/PhasarLLVM/ControlFlow/LLVMBasedICFG.cpp | 44 +++++++++----------- 1 file changed, 19 insertions(+), 25 deletions(-) diff --git a/lib/PhasarLLVM/ControlFlow/LLVMBasedICFG.cpp b/lib/PhasarLLVM/ControlFlow/LLVMBasedICFG.cpp index 7ca738f67..1380da51e 100644 --- a/lib/PhasarLLVM/ControlFlow/LLVMBasedICFG.cpp +++ b/lib/PhasarLLVM/ControlFlow/LLVMBasedICFG.cpp @@ -28,6 +28,7 @@ #include "llvm/ADT/StringSwitch.h" #include "llvm/IR/Function.h" #include "llvm/IR/Instruction.h" +#include "llvm/Support/Casting.h" #include "llvm/Support/ErrorHandling.h" #include @@ -199,8 +200,9 @@ bool LLVMBasedICFG::Builder::processFunction(const llvm::Function *F) { Res->preCall(&I); // check if function call can be resolved statically - if (CS->getCalledFunction() != nullptr) { - PossibleTargets.insert(CS->getCalledFunction()); + if (const auto *StaticCallee = llvm::dyn_cast( + CS->getCalledOperand()->stripPointerCastsAndAliases())) { + PossibleTargets.insert(StaticCallee); PHASAR_LOG_LEVEL_CAT(DEBUG, "LLVMBasedICFG", "Found static call-site: " @@ -208,30 +210,22 @@ bool LLVMBasedICFG::Builder::processFunction(const llvm::Function *F) { } else { // still try to resolve the called function statically const llvm::Value *SV = CS->getCalledOperand()->stripPointerCasts(); - const llvm::Function *ValueFunction = - !SV->hasName() ? nullptr : IRDB->getFunction(SV->getName()); - if (ValueFunction) { - PossibleTargets.insert(ValueFunction); - PHASAR_LOG_LEVEL_CAT( - DEBUG, "LLVMBasedICFG", - "Found static call-site: " << llvmIRToString(CS)); - } else { - if (llvm::isa(SV)) { - continue; - } - // the function call must be resolved dynamically - PHASAR_LOG_LEVEL_CAT(DEBUG, "LLVMBasedICFG", - "Found dynamic call-site: " - << " " << llvmIRToString(CS)); - - assert(TH != nullptr); - PossibleTargets = internalIsVirtualFunctionCall(CS, *TH) - ? Res->resolveVirtualCall(CS) - : Res->resolveFunctionPointer(CS); - - IndirectCalls[CS] = PossibleTargets.size(); - FixpointReached = false; + + if (llvm::isa(SV)) { + continue; } + // the function call must be resolved dynamically + PHASAR_LOG_LEVEL_CAT(DEBUG, "LLVMBasedICFG", + "Found dynamic call-site: " + << " " << llvmIRToString(CS)); + + assert(TH != nullptr); + PossibleTargets = internalIsVirtualFunctionCall(CS, *TH) + ? Res->resolveVirtualCall(CS) + : Res->resolveFunctionPointer(CS); + + IndirectCalls[CS] = PossibleTargets.size(); + FixpointReached = false; } PHASAR_LOG_LEVEL_CAT(DEBUG, "LLVMBasedICFG", From ab3fa86f89657e3cabd21dac4ac105f6840fd5a0 Mon Sep 17 00:00:00 2001 From: mxHuber Date: Wed, 29 May 2024 10:45:21 +0200 Subject: [PATCH 06/78] annotation fix + test fix --- bootstrap.sh | 0 cmake/add_llvm.cmake | 1 - lib/PhasarLLVM/Utils/Annotation.cpp | 18 +++++---------- .../Problems/IFDSTaintAnalysisTest.cpp | 22 +++++++++---------- 4 files changed, 17 insertions(+), 24 deletions(-) mode change 100644 => 100755 bootstrap.sh diff --git a/bootstrap.sh b/bootstrap.sh old mode 100644 new mode 100755 diff --git a/cmake/add_llvm.cmake b/cmake/add_llvm.cmake index 107deac11..bd05dcb49 100644 --- a/cmake/add_llvm.cmake +++ b/cmake/add_llvm.cmake @@ -2,7 +2,6 @@ macro(add_llvm) if (NOT PHASAR_IN_TREE) # Only search for LLVM if we build out of tree - set(LLVM 15 "/usr/local/llvm-15") find_package(LLVM 15 REQUIRED CONFIG) find_library(LLVM_LIBRARY NAMES LLVM PATHS ${LLVM_LIBRARY_DIRS} NO_DEFAULT_PATH) diff --git a/lib/PhasarLLVM/Utils/Annotation.cpp b/lib/PhasarLLVM/Utils/Annotation.cpp index 07b5127b3..833ee453f 100644 --- a/lib/PhasarLLVM/Utils/Annotation.cpp +++ b/lib/PhasarLLVM/Utils/Annotation.cpp @@ -75,20 +75,14 @@ llvm::StringRef VarAnnotation::retrieveString(unsigned Idx) const { const llvm::Value *VarAnnotation::getOriginalValueOrOriginalArg( const llvm::Value *AnnotatedValue) { - if (const auto *BitCast = - llvm::dyn_cast(AnnotatedValue)) { - // this may be already the original value - const auto *Value = BitCast->getOperand(0); - // check if that values originates from a formal parameter - for (const auto &User : Value->users()) { - if (const auto *Store = llvm::dyn_cast(User); - Store && llvm::isa(Store->getValueOperand())) { - return Store->getValueOperand(); - } + // check if that values originates from a formal parameter + for (const auto &User : AnnotatedValue->users()) { + if (const auto *Store = llvm::dyn_cast(User); + Store && llvm::isa(Store->getValueOperand())) { + return Store->getValueOperand(); } - return Value; } - return nullptr; + return AnnotatedValue; } GlobalAnnotation::GlobalAnnotation( diff --git a/unittests/PhasarLLVM/DataFlow/IfdsIde/Problems/IFDSTaintAnalysisTest.cpp b/unittests/PhasarLLVM/DataFlow/IfdsIde/Problems/IFDSTaintAnalysisTest.cpp index 0812fafcf..69ea7f0d2 100644 --- a/unittests/PhasarLLVM/DataFlow/IfdsIde/Problems/IFDSTaintAnalysisTest.cpp +++ b/unittests/PhasarLLVM/DataFlow/IfdsIde/Problems/IFDSTaintAnalysisTest.cpp @@ -193,7 +193,7 @@ TEST_F(IFDSTaintAnalysisTest, TaintTest_ExceptionHandling_01) { IFDSSolver TaintSolver(*TaintProblem, &HA->getICFG()); TaintSolver.solve(); map> GroundTruth; - GroundTruth[15] = set{"14"}; + GroundTruth[14] = set{"13"}; compareResults(GroundTruth); } @@ -203,7 +203,7 @@ TEST_F(IFDSTaintAnalysisTest, TaintTest_ExceptionHandling_01_m2r) { IFDSSolver TaintSolver(*TaintProblem, &HA->getICFG()); TaintSolver.solve(); map> GroundTruth; - GroundTruth[6] = set{"0"}; + GroundTruth[5] = set{"0"}; compareResults(GroundTruth); } @@ -213,7 +213,7 @@ TEST_F(IFDSTaintAnalysisTest, TaintTest_ExceptionHandling_02) { IFDSSolver TaintSolver(*TaintProblem, &HA->getICFG()); TaintSolver.solve(); map> GroundTruth; - GroundTruth[17] = set{"16"}; + GroundTruth[16] = set{"15"}; compareResults(GroundTruth); } @@ -224,7 +224,7 @@ TEST_F(IFDSTaintAnalysisTest, TaintTest_ExceptionHandling_03) { TaintSolver.solve(); map> GroundTruth; GroundTruth[11] = set{"10"}; - GroundTruth[21] = set{"20"}; + GroundTruth[20] = set{"19"}; compareResults(GroundTruth); } @@ -234,7 +234,7 @@ TEST_F(IFDSTaintAnalysisTest, TaintTest_ExceptionHandling_04) { IFDSSolver TaintSolver(*TaintProblem, &HA->getICFG()); TaintSolver.solve(); map> GroundTruth; - GroundTruth[33] = set{"32"}; + GroundTruth[32] = set{"31"}; compareResults(GroundTruth); } @@ -245,7 +245,7 @@ TEST_F(IFDSTaintAnalysisTest, TaintTest_ExceptionHandling_05) { TaintSolver.solve(); map> GroundTruth; - GroundTruth[33] = set{"32"}; + GroundTruth[32] = set{"31"}; compareResults(GroundTruth); } @@ -255,7 +255,7 @@ TEST_F(IFDSTaintAnalysisTest, TaintTest_ExceptionHandling_06) { IFDSSolver TaintSolver(*TaintProblem, &HA->getICFG()); TaintSolver.solve(); map> GroundTruth; - GroundTruth[15] = set{"14"}; + GroundTruth[14] = set{"13"}; compareResults(GroundTruth); } @@ -265,7 +265,7 @@ TEST_F(IFDSTaintAnalysisTest, TaintTest_ExceptionHandling_07) { IFDSSolver TaintSolver(*TaintProblem, &HA->getICFG()); TaintSolver.solve(); map> GroundTruth; - GroundTruth[31] = set{"30"}; + GroundTruth[30] = set{"29"}; compareResults(GroundTruth); } @@ -275,7 +275,7 @@ TEST_F(IFDSTaintAnalysisTest, TaintTest_ExceptionHandling_08) { IFDSSolver TaintSolver(*TaintProblem, &HA->getICFG()); TaintSolver.solve(); map> GroundTruth; - GroundTruth[33] = set{"32"}; + GroundTruth[32] = set{"31"}; compareResults(GroundTruth); } @@ -285,7 +285,7 @@ TEST_F(IFDSTaintAnalysisTest, TaintTest_ExceptionHandling_09) { IFDSSolver TaintSolver(*TaintProblem, &HA->getICFG()); TaintSolver.solve(); map> GroundTruth; - GroundTruth[64] = set{"63"}; + GroundTruth[62] = set{"61"}; compareResults(GroundTruth); } @@ -295,7 +295,7 @@ TEST_F(IFDSTaintAnalysisTest, TaintTest_ExceptionHandling_10) { IFDSSolver TaintSolver(*TaintProblem, &HA->getICFG()); TaintSolver.solve(); map> GroundTruth; - GroundTruth[62] = set{"61"}; + GroundTruth[60] = set{"59"}; compareResults(GroundTruth); } From f703041d6d7f38a80dad1b0cb5032fd92ec93f8a Mon Sep 17 00:00:00 2001 From: mxHuber Date: Mon, 3 Jun 2024 22:51:09 +0200 Subject: [PATCH 07/78] removed bitcasts and fixed tests --- .../Problems/IDEInstInteractionAnalysis.cpp | 3 ++- .../TypeHierarchy/LLVMTypeHierarchy.cpp | 15 ++++++--------- lib/PhasarLLVM/TypeHierarchy/LLVMVFTable.cpp | 17 +++++++---------- lib/PhasarLLVM/Utils/Annotation.cpp | 10 +++++----- .../ControlFlow/LLVMBasedICFGExportTest.cpp | 8 +++++++- .../Problems/IDEExtendedTaintAnalysisTest.cpp | 2 +- .../IfdsIde/Problems/IDEGeneralizedLCATest.cpp | 1 + 7 files changed, 29 insertions(+), 27 deletions(-) diff --git a/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEInstInteractionAnalysis.cpp b/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEInstInteractionAnalysis.cpp index d65e8ea9c..c6efc8783 100644 --- a/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEInstInteractionAnalysis.cpp +++ b/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEInstInteractionAnalysis.cpp @@ -69,7 +69,8 @@ IDEIIAFlowFact IDEIIAFlowFact::create(const llvm::Value *BaseVal) { } return {BaseVal, FieldDesc}; } - llvm::report_fatal_error("Unexpected instruction!"); + llvm::report_fatal_error("Unexpected instruction!" + + llvm::Twine(llvmIRToString(BaseVal))); } bool IDEIIAFlowFact::flowFactEqual(const IDEIIAFlowFact &Other) const { diff --git a/lib/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.cpp b/lib/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.cpp index bc2e32534..f18476fb9 100644 --- a/lib/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.cpp +++ b/lib/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.cpp @@ -166,15 +166,12 @@ LLVMTypeHierarchy::getSubTypes(const llvm::Module & /*M*/, llvm::dyn_cast(TI->getInitializer())) { for (const auto &Op : I->operands()) { if (auto *CE = llvm::dyn_cast(Op)) { - if (auto *BC = llvm::dyn_cast(CE)) { - if (BC->getOperand(0)->hasName()) { - auto Name = BC->getOperand(0)->getName(); - if (Name.find(TypeInfoPrefix) != llvm::StringRef::npos) { - auto ClearName = - removeTypeInfoPrefix(llvm::demangle(Name.str())); - if (const auto *Type = ClearNameTypeMap[ClearName]) { - SubTypes.push_back(Type); - } + if (CE->getOperand(0)->hasName()) { + auto Name = CE->getOperand(0)->getName(); + if (Name.find(TypeInfoPrefix) != llvm::StringRef::npos) { + auto ClearName = removeTypeInfoPrefix(llvm::demangle(Name.str())); + if (const auto *Type = ClearNameTypeMap[ClearName]) { + SubTypes.push_back(Type); } } } diff --git a/lib/PhasarLLVM/TypeHierarchy/LLVMVFTable.cpp b/lib/PhasarLLVM/TypeHierarchy/LLVMVFTable.cpp index 76c2f7c82..921b59c98 100644 --- a/lib/PhasarLLVM/TypeHierarchy/LLVMVFTable.cpp +++ b/lib/PhasarLLVM/TypeHierarchy/LLVMVFTable.cpp @@ -60,17 +60,14 @@ LLVMVFTable::getVFVectorFromIRVTable(const llvm::ConstantStruct &VT) { It != CA->operands().end(); ++It) { const auto &COp = *It; if (const auto *CE = llvm::dyn_cast(COp)) { - if (const auto *BC = llvm::dyn_cast(CE)) { - // if the entry is a GlobalAlias, get its Aliasee - auto *Entry = BC->getOperand(0); - while (auto *GA = llvm::dyn_cast(Entry)) { - Entry = GA->getAliasee(); - } - auto *F = llvm::dyn_cast(Entry); - VFS.push_back(F); - } else { - VFS.push_back(nullptr); + // if the entry is a GlobalAlias, get its Aliasee + auto *Entry = CE->getOperand(0); + while (auto *GA = llvm::dyn_cast(Entry)) { + Entry = GA->getAliasee(); } + auto *F = llvm::dyn_cast(Entry); + VFS.push_back(F); + } else { VFS.push_back(nullptr); } diff --git a/lib/PhasarLLVM/Utils/Annotation.cpp b/lib/PhasarLLVM/Utils/Annotation.cpp index 833ee453f..bfb152226 100644 --- a/lib/PhasarLLVM/Utils/Annotation.cpp +++ b/lib/PhasarLLVM/Utils/Annotation.cpp @@ -91,12 +91,12 @@ GlobalAnnotation::GlobalAnnotation( const llvm::Function *GlobalAnnotation::getFunction() const { const auto *FunCastOp = AnnotationStruct->getOperand(0); - if (const auto *BitCast = llvm::dyn_cast(FunCastOp)) { - if (const auto *Fun = - llvm::dyn_cast(BitCast->getOperand(0))) { - return Fun; - } + + if (const auto *Fun = + llvm::dyn_cast(FunCastOp->getOperand(0))) { + return Fun; } + return nullptr; } diff --git a/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFGExportTest.cpp b/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFGExportTest.cpp index 18f503fc3..7eb5463a7 100644 --- a/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFGExportTest.cpp +++ b/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFGExportTest.cpp @@ -151,6 +151,12 @@ class LLVMBasedICFGExportTest : public ::testing::Test { const nlohmann::json &GroundTruth) { ASSERT_TRUE(ExportedICFG.is_array()); + // llvm::outs() << "JSONs: GroundTruth\n"; + // llvm::outs() << GroundTruth.dump() << "\n"; + // llvm::outs() << "\n\n------------------------------------------\n\n"; + // llvm::outs() << "JSONs: ExportedICFG\n"; + // llvm::outs() << ExportedICFG.dump() << "\n"; + EXPECT_EQ(GroundTruth.size(), ExportedICFG.size()); bool HasError = false; for (const auto >Json : GroundTruth) { @@ -172,7 +178,7 @@ class LLVMBasedICFGExportTest : public ::testing::Test { } if (HasError) { - llvm::errs() << "Errorneous json: " << ExportedICFG.dump(4) << '\n'; + // llvm::errs() << "Errorneous json: " << ExportedICFG.dump(4) << '\n'; } } diff --git a/unittests/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEExtendedTaintAnalysisTest.cpp b/unittests/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEExtendedTaintAnalysisTest.cpp index 806cb58e2..f6755e304 100644 --- a/unittests/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEExtendedTaintAnalysisTest.cpp +++ b/unittests/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEExtendedTaintAnalysisTest.cpp @@ -57,7 +57,7 @@ class IDETaintAnalysisTest : public ::testing::Test { void doAnalysis( const llvm::Twine &IRFile, const map> &GroundTruth, std::variant Config, - bool DumpResults = false) { + bool DumpResults = true) { HelperAnalyses HA(IRFile, EntryPoints); auto TC = diff --git a/unittests/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEGeneralizedLCATest.cpp b/unittests/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEGeneralizedLCATest.cpp index 17a74b610..c0f91e102 100644 --- a/unittests/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEGeneralizedLCATest.cpp +++ b/unittests/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEGeneralizedLCATest.cpp @@ -133,6 +133,7 @@ TEST_F(IDEGeneralizedLCATest, StringTestCpp) { 3, std::stoi(getMetaDataID(LastMainInstruction))}); compareResults(GroundTruth); + LCASolver->dumpResults(); } TEST_F(IDEGeneralizedLCATest, FloatDivisionTest) { From b78d077ace9e95e5708ee298d72cb8d6154d171d Mon Sep 17 00:00:00 2001 From: Fabian Schiebel Date: Tue, 4 Jun 2024 15:24:11 +0200 Subject: [PATCH 08/78] Fix Annotation.cpp + TaintConfigTest --- lib/PhasarLLVM/Utils/Annotation.cpp | 62 ++++++++----------- .../TaintConfig/TaintConfigTest.cpp | 20 +++--- 2 files changed, 37 insertions(+), 45 deletions(-) diff --git a/lib/PhasarLLVM/Utils/Annotation.cpp b/lib/PhasarLLVM/Utils/Annotation.cpp index bfb152226..b97f2429a 100644 --- a/lib/PhasarLLVM/Utils/Annotation.cpp +++ b/lib/PhasarLLVM/Utils/Annotation.cpp @@ -10,6 +10,7 @@ #include "phasar/PhasarLLVM/Utils/Annotation.h" #include "llvm/ADT/StringRef.h" +#include "llvm/Analysis/ValueTracking.h" #include "llvm/IR/Argument.h" #include "llvm/IR/Constants.h" #include "llvm/IR/Function.h" @@ -54,21 +55,18 @@ uint64_t VarAnnotation::getLine() const { } llvm::StringRef VarAnnotation::retrieveString(unsigned Idx) const { - if (const auto *ConstExpr = llvm::dyn_cast( - AnnotationCall->getArgOperand(Idx))) { - if (llvm::isa(ConstExpr)) { - if (const auto *GlobalVar = - llvm::dyn_cast(ConstExpr->getOperand(0))) { - if (GlobalVar->hasInitializer()) { - const auto *ConstData = GlobalVar->getInitializer(); - if (const auto *Data = - llvm::dyn_cast(ConstData)) { - return Data->getAsCString(); - } - } - } - } + assert(Idx < AnnotationCall->arg_size()); + const auto *StringPointer = llvm::dyn_cast( + llvm::getUnderlyingObject(AnnotationCall->getArgOperand(Idx))); + if (!StringPointer || !StringPointer->hasInitializer()) { + return ""; + } + + const auto *ConstData = StringPointer->getInitializer(); + if (const auto *Data = llvm::dyn_cast(ConstData)) { + return Data->getAsCString(); } + return ""; } @@ -90,33 +88,25 @@ GlobalAnnotation::GlobalAnnotation( : AnnotationStruct(AnnotationStruct) {} const llvm::Function *GlobalAnnotation::getFunction() const { - const auto *FunCastOp = AnnotationStruct->getOperand(0); - - if (const auto *Fun = - llvm::dyn_cast(FunCastOp->getOperand(0))) { - return Fun; - } + const auto *FunCastOp = + AnnotationStruct->getOperand(0)->stripPointerCastsAndAliases(); - return nullptr; + return llvm::dyn_cast(FunCastOp); } llvm::StringRef GlobalAnnotation::retrieveString(unsigned Idx) const { - const auto *AnnotationGepOp = AnnotationStruct->getOperand(Idx); - if (const auto *ConstExpr = - llvm::dyn_cast(AnnotationGepOp)) { - if (llvm::isa(ConstExpr)) { - if (const auto *GlobalVar = - llvm::dyn_cast(ConstExpr->getOperand(0))) { - if (GlobalVar->hasInitializer()) { - const auto *ConstData = GlobalVar->getInitializer(); - if (const auto *Data = - llvm::dyn_cast(ConstData)) { - return Data->getAsCString(); - } - } - } - } + assert(Idx < AnnotationStruct->getNumOperands()); + const auto *StringPointer = llvm::dyn_cast( + llvm::getUnderlyingObject(AnnotationStruct->getOperand(Idx))); + if (!StringPointer || !StringPointer->hasInitializer()) { + return ""; } + + const auto *ConstData = StringPointer->getInitializer(); + if (const auto *Data = llvm::dyn_cast(ConstData)) { + return Data->getAsCString(); + } + return ""; } diff --git a/unittests/PhasarLLVM/TaintConfig/TaintConfigTest.cpp b/unittests/PhasarLLVM/TaintConfig/TaintConfigTest.cpp index bc722d66e..c7af226d5 100644 --- a/unittests/PhasarLLVM/TaintConfig/TaintConfigTest.cpp +++ b/unittests/PhasarLLVM/TaintConfig/TaintConfigTest.cpp @@ -79,7 +79,7 @@ TEST_F(TaintConfigTest, Basic_02) { psr::LLVMTaintConfig Config(IR); llvm::outs() << Config << '\n'; const llvm::Value *I1 = IR.getInstruction(9); - const llvm::Value *I2 = IR.getInstruction(23); + const llvm::Value *I2 = IR.getInstruction(21); ASSERT_TRUE(Config.isSource(I1)); ASSERT_TRUE(Config.isSource(I2)); } @@ -143,10 +143,10 @@ TEST_F(TaintConfigTest, FunMember_02) { psr::LLVMTaintConfig TConfig(IR); // IR.emitPreprocessedIR(llvm::outs(), false); llvm::outs() << TConfig << '\n'; - const llvm::Value *I1 = IR.getInstruction(22); - const llvm::Value *I2 = IR.getInstruction(61); - const llvm::Value *I3 = IR.getInstruction(73); - const llvm::Value *I4 = IR.getInstruction(84); + const llvm::Value *I1 = IR.getInstruction(20); + const llvm::Value *I2 = IR.getInstruction(57); + const llvm::Value *I3 = IR.getInstruction(67); + const llvm::Value *I4 = IR.getInstruction(76); ASSERT_TRUE(TConfig.isSource(I1)); ASSERT_TRUE(TConfig.isSource(I2)); ASSERT_TRUE(TConfig.isSource(I3)); @@ -365,10 +365,12 @@ TEST_F(TaintConfigTest, FunMember_02_Json) { psr::LLVMProjectIRDB IR({PathToJsonTaintConfigTestCode + File}); // IR.emitPreprocessedIR(llvm::outs(), false); psr::LLVMTaintConfig TConfig(IR, JsonConfig); - const llvm::Value *I1 = IR.getInstruction(18); - const llvm::Value *I2 = IR.getInstruction(54); - const llvm::Value *I3 = IR.getInstruction(63); - const llvm::Value *I4 = IR.getInstruction(71); + llvm::outs() << TConfig << '\n'; + + const llvm::Value *I1 = IR.getInstruction(16); + const llvm::Value *I2 = IR.getInstruction(52); + const llvm::Value *I3 = IR.getInstruction(61); + const llvm::Value *I4 = IR.getInstruction(69); ASSERT_TRUE(TConfig.isSource(I1)); ASSERT_TRUE(TConfig.isSource(I2)); ASSERT_TRUE(TConfig.isSource(I3)); From 09e34aac245ac2b14a0c7821bd80d6b97dad2695 Mon Sep 17 00:00:00 2001 From: Fabian Schiebel Date: Tue, 4 Jun 2024 16:01:26 +0200 Subject: [PATCH 09/78] Quick-fix LLVMTypeHierarchyTest --- .../TypeHierarchy/LLVMTypeHierarchy.cpp | 39 ++++++++++++------- lib/PhasarLLVM/TypeHierarchy/LLVMVFTable.cpp | 15 ++----- .../TypeHierarchy/LLVMTypeHierarchyTest.cpp | 20 +++++----- 3 files changed, 40 insertions(+), 34 deletions(-) diff --git a/lib/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.cpp b/lib/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.cpp index f18476fb9..5a2cf2387 100644 --- a/lib/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.cpp +++ b/lib/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.cpp @@ -88,12 +88,14 @@ std::string LLVMTypeHierarchy::removeStructOrClassPrefix(const std::string &TypeName) { llvm::StringRef SR(TypeName); if (SR.startswith(StructPrefix)) { - return SR.drop_front(StructPrefix.size()).str(); + SR = SR.drop_front(StructPrefix.size()); + } else if (SR.startswith(ClassPrefix)) { + SR = SR.drop_front(ClassPrefix.size()); } - if (SR.startswith(ClassPrefix)) { - return SR.drop_front(ClassPrefix.size()).str(); + if (SR.endswith(".base")) { + SR = SR.drop_back(llvm::StringRef(".base").size()); } - return TypeName; + return SR.str(); } std::string LLVMTypeHierarchy::removeTypeInfoPrefix(std::string VarName) { @@ -165,14 +167,14 @@ LLVMTypeHierarchy::getSubTypes(const llvm::Module & /*M*/, if (const auto *I = llvm::dyn_cast(TI->getInitializer())) { for (const auto &Op : I->operands()) { - if (auto *CE = llvm::dyn_cast(Op)) { - if (CE->getOperand(0)->hasName()) { - auto Name = CE->getOperand(0)->getName(); - if (Name.find(TypeInfoPrefix) != llvm::StringRef::npos) { - auto ClearName = removeTypeInfoPrefix(llvm::demangle(Name.str())); - if (const auto *Type = ClearNameTypeMap[ClearName]) { - SubTypes.push_back(Type); - } + const auto *CE = Op->stripPointerCastsAndAliases(); + + if (CE->hasName()) { + auto Name = CE->getName(); + if (Name.find(TypeInfoPrefix) != llvm::StringRef::npos) { + auto ClearName = removeTypeInfoPrefix(llvm::demangle(Name.str())); + if (const auto *Type = ClearNameTypeMap[ClearName]) { + SubTypes.push_back(Type); } } } @@ -262,7 +264,9 @@ LLVMTypeHierarchy::getSuperTypes(const llvm::StructType * /*Type*/) { return ReachableTypes; } -const llvm::StructType *LLVMTypeHierarchy::getType(std::string TypeName) const { +template +static const llvm::StructType *getTypeImpl(const GraphT &TypeGraph, + llvm::StringRef TypeName) { for (auto V : boost::make_iterator_range(boost::vertices(TypeGraph))) { if (TypeGraph[V].Type->getName() == TypeName) { return TypeGraph[V].Type; @@ -271,6 +275,15 @@ const llvm::StructType *LLVMTypeHierarchy::getType(std::string TypeName) const { return nullptr; } +const llvm::StructType *LLVMTypeHierarchy::getType(std::string TypeName) const { + if (const auto *Ty = getTypeImpl(TypeGraph, TypeName)) { + return Ty; + } + + TypeName += ".base"; + return getTypeImpl(TypeGraph, TypeName); +} + std::set LLVMTypeHierarchy::getAllTypes() const { std::set Types; for (auto V : boost::make_iterator_range(boost::vertices(TypeGraph))) { diff --git a/lib/PhasarLLVM/TypeHierarchy/LLVMVFTable.cpp b/lib/PhasarLLVM/TypeHierarchy/LLVMVFTable.cpp index 921b59c98..20d09dff2 100644 --- a/lib/PhasarLLVM/TypeHierarchy/LLVMVFTable.cpp +++ b/lib/PhasarLLVM/TypeHierarchy/LLVMVFTable.cpp @@ -58,19 +58,10 @@ LLVMVFTable::getVFVectorFromIRVTable(const llvm::ConstantStruct &VT) { // is RTTI for (const auto *It = std::next(CA->operands().begin(), 2); It != CA->operands().end(); ++It) { - const auto &COp = *It; - if (const auto *CE = llvm::dyn_cast(COp)) { - // if the entry is a GlobalAlias, get its Aliasee - auto *Entry = CE->getOperand(0); - while (auto *GA = llvm::dyn_cast(Entry)) { - Entry = GA->getAliasee(); - } - auto *F = llvm::dyn_cast(Entry); - VFS.push_back(F); + const auto *Entry = It->get()->stripPointerCastsAndAliases(); - } else { - VFS.push_back(nullptr); - } + const auto *F = llvm::dyn_cast(Entry); + VFS.push_back(F); } } } diff --git a/unittests/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchyTest.cpp b/unittests/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchyTest.cpp index 3dd219fde..a11555de6 100644 --- a/unittests/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchyTest.cpp +++ b/unittests/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchyTest.cpp @@ -27,8 +27,9 @@ TEST(LTHTest, BasicTHReconstruction_1) { LLVMProjectIRDB IRDB(unittest::PathToLLTestFiles + "type_hierarchies/type_hierarchy_1_cpp.ll"); LLVMTypeHierarchy LTH(IRDB); - EXPECT_EQ(LTH.hasType(LTH.getType("struct.Base")), true); - EXPECT_EQ(LTH.hasType(LTH.getType("struct.Child")), true); + + ASSERT_EQ(LTH.hasType(LTH.getType("struct.Base")), true); + ASSERT_EQ(LTH.hasType(LTH.getType("struct.Child")), true); EXPECT_EQ(LTH.getAllTypes().size(), 2U); EXPECT_EQ( LTH.isSubType(LTH.getType("struct.Base"), LTH.getType("struct.Child")), @@ -319,16 +320,15 @@ TEST(LTHTest, BasicTHReconstruction_7) { LLVMTypeHierarchy LTH(IRDB); EXPECT_EQ(LTH.hasType(LTH.getType("struct.Base")), true); EXPECT_EQ(LTH.hasType(LTH.getType("struct.Child")), true); - // has three types because of padding (introduction of intermediate type) - EXPECT_EQ(LTH.getAllTypes().size(), 3U); + EXPECT_EQ(LTH.getAllTypes().size(), 2U); EXPECT_EQ( LTH.isSubType(LTH.getType("struct.Base"), LTH.getType("struct.Child")), true); EXPECT_EQ( LTH.isSuperType(LTH.getType("struct.Child"), LTH.getType("struct.Base")), true); - EXPECT_EQ(LTH.hasVFTable(LTH.getType("struct.Base")), true); - EXPECT_EQ(LTH.hasVFTable(LTH.getType("struct.Child")), true); + ASSERT_EQ(LTH.hasVFTable(LTH.getType("struct.Base")), true); + ASSERT_EQ(LTH.hasVFTable(LTH.getType("struct.Child")), true); EXPECT_EQ(LTH.getVFTable(LTH.getType("struct.Base")) ->getFunction(0) ->getName() @@ -521,7 +521,10 @@ TEST(LTHTest, VTableConstruction) { ->getName() .str()) == "Child::baz()"); ASSERT_TRUE(TH5.getVFTable(TH5.getType("struct.Child"))->size() == 3U); - ASSERT_TRUE(TH6.getVFTable(TH6.getType("class.Base"))->size() == 3U); + + // FIXME: TH6 has no structs in the IR anymore + // ASSERT_TRUE(TH6.hasVFTable(TH6.getType("class.Base"))); + // ASSERT_TRUE(TH6.getVFTable(TH6.getType("class.Base"))->size() == 3U); } TEST(LTHTest, TransitivelyReachableTypes) { @@ -613,8 +616,7 @@ TEST(LTHTest, TransitivelyReachableTypes) { TH3.getType("struct.NonvirtualStruct"))); ASSERT_TRUE(ReachableTypesNonvirtualstruct3.size() == 1U); - ASSERT_TRUE(ReachableTypesBase4.count(TH4.getType("struct.Base"))); - ASSERT_FALSE(ReachableTypesBase4.count(TH4.getType("struct.Base.base"))); + ASSERT_TRUE(ReachableTypesBase4.count(TH4.getType("struct.Base.base"))); ASSERT_TRUE(ReachableTypesBase4.count(TH4.getType("struct.Child"))); ASSERT_TRUE(ReachableTypesBase4.size() == 2U); ASSERT_TRUE(ReachableTypesChild4.count(TH4.getType("struct.Child"))); From 147ecd11a1e36a6d117b356c395b4be518b21362 Mon Sep 17 00:00:00 2001 From: Fabian Schiebel Date: Tue, 4 Jun 2024 16:17:54 +0200 Subject: [PATCH 10/78] fix one IIA test --- .../IfdsIde/Problems/IDEInstInteractionAnalysisTest.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/unittests/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEInstInteractionAnalysisTest.cpp b/unittests/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEInstInteractionAnalysisTest.cpp index d0ca110ab..fab423848 100644 --- a/unittests/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEInstInteractionAnalysisTest.cpp +++ b/unittests/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEInstInteractionAnalysisTest.cpp @@ -143,11 +143,11 @@ TEST_F(IDEInstInteractionAnalysisTest, FieldSensArrayConstruction_01) { llvm::outs() << "Instruction to create flow fact from: " << *Inst << '\n'; auto FlowFact = IDEIIAFlowFact::create(Inst); llvm::outs() << FlowFact << '\n'; - Inst = getNthInstruction(Main, 14); + Inst = getNthInstruction(Main, 13); llvm::outs() << "Instruction to create flow fact from: " << *Inst << '\n'; FlowFact = IDEIIAFlowFact::create(Inst); llvm::outs() << FlowFact << '\n'; - Inst = getNthInstruction(Main, 17); + Inst = getNthInstruction(Main, 16); llvm::outs() << "Instruction to create flow fact from: " << *Inst << '\n'; FlowFact = IDEIIAFlowFact::create(Inst); llvm::outs() << FlowFact << '\n'; From fda53ef41eb790701807e1dca1ac88ebef54e7cb Mon Sep 17 00:00:00 2001 From: Fabian Schiebel Date: Tue, 4 Jun 2024 16:25:34 +0200 Subject: [PATCH 11/78] Fix StringtestCpp for generalized LCA --- .../IDEGeneralizedLCA/IDEGeneralizedLCA.cpp | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEGeneralizedLCA/IDEGeneralizedLCA.cpp b/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEGeneralizedLCA/IDEGeneralizedLCA.cpp index 7ce08382f..b4f0ddfcb 100644 --- a/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEGeneralizedLCA/IDEGeneralizedLCA.cpp +++ b/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEGeneralizedLCA/IDEGeneralizedLCA.cpp @@ -30,6 +30,7 @@ #include "llvm/Demangle/Demangle.h" #include "llvm/IR/Constants.h" +#include "llvm/IR/GlobalValue.h" #include "llvm/IR/GlobalVariable.h" #include "llvm/IR/InstrTypes.h" #include "llvm/IR/Instructions.h" @@ -424,21 +425,20 @@ IDEGeneralizedLCA::getCallToRetEdgeFunction(IDEGeneralizedLCA::n_t CallSite, // found correct place and time if (CallNode == getZeroValue() && RetSiteNode == CS->getArgOperand(0)) { // find string literal that is used to initialize the string - if (auto *User = llvm::dyn_cast(CS->getArgOperand(1))) { - if (auto *GV = - llvm::dyn_cast(User->getOperand(0))) { - if (!GV->hasInitializer()) { - // in this case we don't know the initial value statically - // return ALLBOTTOM; - return AllBottom{}; - } - if (auto *CDA = llvm::dyn_cast( - GV->getInitializer())) { - if (CDA->isCString()) { - // here we statically know the string literal the std::string is - // initialized with - return GenConstant{l_t({EdgeValue(CDA->getAsCString().str())})}; - } + const auto *Arg1 = CS->getArgOperand(1)->stripPointerCastsAndAliases(); + + if (const auto *GV = llvm::dyn_cast(Arg1)) { + if (!GV->hasInitializer()) { + // in this case we don't know the initial value statically + // return ALLBOTTOM; + return AllBottom{}; + } + if (const auto *CDA = + llvm::dyn_cast(GV->getInitializer())) { + if (CDA->isCString()) { + // here we statically know the string literal the std::string is + // initialized with + return GenConstant{l_t({EdgeValue(CDA->getAsCString().str())})}; } } } From 9b449d1c70ff8cae2e14d6343ea67c8abd72722c Mon Sep 17 00:00:00 2001 From: mxHuber Date: Wed, 5 Jun 2024 22:20:30 +0200 Subject: [PATCH 12/78] first half of tests fixed --- .../DataFlow/IfdsIde/Solver/IDESolver.h | 2 +- .../Problems/IDEExtendedTaintAnalysisTest.cpp | 24 +++++++++---------- .../Problems/IFDSConstAnalysisTest.cpp | 4 ++-- .../Pointer/LLVMAliasSetSerializationTest.cpp | 6 ++--- unittests/Utils/AnalysisPrinterTest.cpp | 2 +- unittests/Utils/LLVMShorthandsTest.cpp | 2 +- 6 files changed, 20 insertions(+), 20 deletions(-) diff --git a/include/phasar/DataFlow/IfdsIde/Solver/IDESolver.h b/include/phasar/DataFlow/IfdsIde/Solver/IDESolver.h index 3274ced1a..e6e7bb58e 100644 --- a/include/phasar/DataFlow/IfdsIde/Solver/IDESolver.h +++ b/include/phasar/DataFlow/IfdsIde/Solver/IDESolver.h @@ -117,7 +117,7 @@ class IDESolver llvm::StringRef(NToString(Cells[I].getRowKey())).trim().str(); std::string NodeStr = - ICF->getFunctionName(ICF->getFunctionOf(Curr)) + "::" + NStr; + ICF->getFunctionName(ICF->getFunctionOf(Curr)).str() + "::" + NStr; J[DataFlowID][NodeStr]; std::string FactStr = llvm::StringRef(DToString(Cells[I].getColumnKey())).trim().str(); diff --git a/unittests/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEExtendedTaintAnalysisTest.cpp b/unittests/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEExtendedTaintAnalysisTest.cpp index f6755e304..b6b9cb075 100644 --- a/unittests/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEExtendedTaintAnalysisTest.cpp +++ b/unittests/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEExtendedTaintAnalysisTest.cpp @@ -140,7 +140,7 @@ TEST_F(IDETaintAnalysisTest, XTaint01_Json) { TEST_F(IDETaintAnalysisTest, XTaint01) { map> Gt; - Gt[15] = {"14"}; + Gt[13] = {"12"}; doAnalysis({PathToLLFiles + "xtaint01_cpp.ll"}, Gt, std::monostate{}); } @@ -148,14 +148,14 @@ TEST_F(IDETaintAnalysisTest, XTaint01) { TEST_F(IDETaintAnalysisTest, XTaint02) { map> Gt; - Gt[20] = {"19"}; + Gt[18] = {"17"}; doAnalysis({PathToLLFiles + "xtaint02_cpp.ll"}, Gt, std::monostate{}, true); } TEST_F(IDETaintAnalysisTest, XTaint03) { map> Gt; - Gt[23] = {"22"}; + Gt[21] = {"20"}; doAnalysis({PathToLLFiles + "xtaint03_cpp.ll"}, Gt, std::monostate{}); } @@ -163,7 +163,7 @@ TEST_F(IDETaintAnalysisTest, XTaint03) { TEST_F(IDETaintAnalysisTest, XTaint04) { map> Gt; - Gt[17] = {"16"}; + Gt[16] = {"15"}; doAnalysis({PathToLLFiles + "xtaint04_cpp.ll"}, Gt, std::monostate{}); } @@ -200,7 +200,7 @@ TEST_F(IDETaintAnalysisTest, DISABLED_XTaint08) { TEST_F(IDETaintAnalysisTest, XTaint09_1) { map> Gt; - Gt[27] = {"26"}; + Gt[25] = {"24"}; doAnalysis({PathToLLFiles + "xtaint09_1_cpp.ll"}, Gt, std::monostate{}); } @@ -241,7 +241,7 @@ TEST_F(IDETaintAnalysisTest, XTaint12) { // We sanitize an alias - since we don't have must-alias relations, we cannot // kill aliases at all - Gt[30] = {"29"}; + Gt[28] = {"27"}; doAnalysis({PathToLLFiles + "xtaint12_cpp.ll"}, Gt, std::monostate{}); } @@ -249,7 +249,7 @@ TEST_F(IDETaintAnalysisTest, XTaint12) { TEST_F(IDETaintAnalysisTest, XTaint13) { map> Gt; - Gt[32] = {"31"}; + Gt[30] = {"29"}; doAnalysis({PathToLLFiles + "xtaint13_cpp.ll"}, Gt, std::monostate{}); } @@ -257,7 +257,7 @@ TEST_F(IDETaintAnalysisTest, XTaint13) { TEST_F(IDETaintAnalysisTest, XTaint14) { map> Gt; - Gt[35] = {"34"}; + Gt[33] = {"32"}; doAnalysis({PathToLLFiles + "xtaint14_cpp.ll"}, Gt, std::monostate{}); } @@ -275,7 +275,7 @@ TEST_F(IDETaintAnalysisTest, DISABLED_XTaint15) { TEST_F(IDETaintAnalysisTest, XTaint16) { map> Gt; - Gt[26] = {"25"}; + Gt[24] = {"23"}; doAnalysis({PathToLLFiles + "xtaint16_cpp.ll"}, Gt, std::monostate{}); } @@ -283,7 +283,7 @@ TEST_F(IDETaintAnalysisTest, XTaint16) { TEST_F(IDETaintAnalysisTest, XTaint17) { map> Gt; - Gt[29] = {"28"}; + Gt[27] = {"26"}; doAnalysis({PathToLLFiles + "xtaint17_cpp.ll"}, Gt, std::monostate{}); } @@ -309,8 +309,8 @@ PHASAR_SKIP_TEST(TEST_F(IDETaintAnalysisTest, XTaint19) { TEST_F(IDETaintAnalysisTest, XTaint20) { map> Gt; - Gt[25] = {"17"}; - Gt[27] = {"26"}; + Gt[22] = {"14"}; + Gt[24] = {"23"}; doAnalysis({PathToLLFiles + "xtaint20_cpp.ll"}, Gt, std::monostate{}); } diff --git a/unittests/PhasarLLVM/DataFlow/IfdsIde/Problems/IFDSConstAnalysisTest.cpp b/unittests/PhasarLLVM/DataFlow/IfdsIde/Problems/IFDSConstAnalysisTest.cpp index 77f858c30..25cf40461 100644 --- a/unittests/PhasarLLVM/DataFlow/IfdsIde/Problems/IFDSConstAnalysisTest.cpp +++ b/unittests/PhasarLLVM/DataFlow/IfdsIde/Problems/IFDSConstAnalysisTest.cpp @@ -175,7 +175,7 @@ TEST_F(IFDSConstAnalysisTest, HandlePointerTest_04) { initialize({PathToLlFiles + "pointer/pointer_04_cpp_m2r_dbg.ll"}); IFDSSolver Llvmconstsolver(*Constproblem, &HA->getICFG()); Llvmconstsolver.solve(); - compareResults({4}, Llvmconstsolver); + compareResults({3}, Llvmconstsolver); } /* ============== GLOBAL TESTS ============== */ @@ -352,7 +352,7 @@ TEST_F(IFDSConstAnalysisTest, HandleArrayTest_08) { initialize({PathToLlFiles + "array/array_08_cpp_m2r_dbg.ll"}); IFDSSolver Llvmconstsolver(*Constproblem, &HA->getICFG()); Llvmconstsolver.solve(); - compareResults({}, Llvmconstsolver); + compareResults({0}, Llvmconstsolver); } TEST_F(IFDSConstAnalysisTest, HandleArrayTest_09) { diff --git a/unittests/PhasarLLVM/Pointer/LLVMAliasSetSerializationTest.cpp b/unittests/PhasarLLVM/Pointer/LLVMAliasSetSerializationTest.cpp index 1da745937..f0ee361b0 100644 --- a/unittests/PhasarLLVM/Pointer/LLVMAliasSetSerializationTest.cpp +++ b/unittests/PhasarLLVM/Pointer/LLVMAliasSetSerializationTest.cpp @@ -103,11 +103,11 @@ TEST(LLVMAliasSetSerializationTest, Ser_Inter01) { TEST(LLVMAliasSetSerializationTest, Ser_Global01) { analyze("pointers/global_01_cpp.ll", - {{{"0", "15", "17", "2", "3", "9", "_Z3fooPi.0"}, + {{{"0", "14", "16", "2", "8", "_Z3fooPi.0"}, {"1"}, + {"11"}, {"12"}, - {"13"}, - {"7"}}, + {"6"}}, {"_GLOBAL__sub_I_global_01.cpp", "_Z3fooPi", "__cxx_global_var_init", "main"}}); } diff --git a/unittests/Utils/AnalysisPrinterTest.cpp b/unittests/Utils/AnalysisPrinterTest.cpp index 34a110d53..546c9d304 100644 --- a/unittests/Utils/AnalysisPrinterTest.cpp +++ b/unittests/Utils/AnalysisPrinterTest.cpp @@ -120,7 +120,7 @@ TEST_F(AnalysisPrinterTest, HandleBasicTest_01) { TEST_F(AnalysisPrinterTest, XTaint01) { llvm::DenseMap> GroundTruth; - GroundTruth[15] = {"8"}; + GroundTruth[13] = {"7"}; GroundTruthCollector GroundTruthPrinter = {GroundTruth}; doAnalysisTest("xtaint01_cpp.ll", GroundTruthPrinter, std::monostate{}); } diff --git a/unittests/Utils/LLVMShorthandsTest.cpp b/unittests/Utils/LLVMShorthandsTest.cpp index 2c19ff675..e6678d43a 100644 --- a/unittests/Utils/LLVMShorthandsTest.cpp +++ b/unittests/Utils/LLVMShorthandsTest.cpp @@ -52,7 +52,7 @@ TEST(SlotTrackerTest, HandleTwoReferences) { ASSERT_NE(F, nullptr); const auto *Inst = getNthInstruction(F, 6); - llvm::StringRef InstStr = "%0 = load i32, i32* @i, align 4 | ID: 6"; + llvm::StringRef InstStr = "%0 = load i32, ptr @i, align 4 | ID: 6"; { LLVMProjectIRDB IRDB2(IRDB.getModule()); From 6b12b7b150e1ca69b0e3c4171ad8324990ddeeba Mon Sep 17 00:00:00 2001 From: mxHuber Date: Wed, 5 Jun 2024 22:22:30 +0200 Subject: [PATCH 13/78] fixed first half of tests --- Dockerfile | 1 - bootstrap.sh | 1 - cmake/add_llvm.cmake | 1 - cmake/phasar_macros.cmake | 1 - test/build_systems_tests/advanced_project/main.c | 1 + test/build_systems_tests/cmake_project/main.c | 1 + test/build_systems_tests/nomechanism_project/main.cpp | 1 + test/build_systems_tests/nomechanism_project/source_1.cpp | 1 + test/clang_test_code/SimpleProject/main.cpp | 1 + test/llvm_test_code/globals/globals_ctor_2_2.cpp | 4 ++-- .../openssl/key_derivation/key-derivation1.c | 5 ++--- .../openssl/key_derivation/key-derivation2.c | 7 +++---- .../openssl/key_derivation/key-derivation3.c | 7 +++---- .../openssl/key_derivation/key-derivation4.c | 7 +++---- .../openssl/key_derivation/key-derivation5.c | 7 +++---- .../openssl/key_derivation/key-derivation6.c | 7 +++---- .../openssl/key_derivation/key-derivation7.c | 7 +++---- .../openssl/key_derivation/key-derivation8.c | 7 +++---- test/llvm_test_code/openssl/secure_heap/memory6.c | 3 +-- test/llvm_test_code/openssl/secure_heap/memory7.c | 3 +-- test/llvm_test_code/openssl/secure_memory/memory1.c | 3 +-- test/llvm_test_code/openssl/secure_memory/memory2.c | 3 +-- test/llvm_test_code/openssl/secure_memory/memory3.c | 3 +-- test/llvm_test_code/openssl/secure_memory/memory4.c | 3 +-- test/llvm_test_code/openssl/secure_memory/memory5.c | 3 +-- test/llvm_test_code/xtaint/xtaint08.cpp | 1 + 26 files changed, 38 insertions(+), 51 deletions(-) diff --git a/Dockerfile b/Dockerfile index 45cb80d40..9317cbbad 100644 --- a/Dockerfile +++ b/Dockerfile @@ -59,4 +59,3 @@ RUN mkdir -p build && cd build && \ cmake --build . ENTRYPOINT [ "./build/tools/phasar-cli/phasar-cli" ] - diff --git a/bootstrap.sh b/bootstrap.sh index 5c8b6db62..0d829f265 100755 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -216,4 +216,3 @@ if ${DO_INSTALL}; then fi echo "done." - diff --git a/cmake/add_llvm.cmake b/cmake/add_llvm.cmake index bd05dcb49..b4544620a 100644 --- a/cmake/add_llvm.cmake +++ b/cmake/add_llvm.cmake @@ -94,4 +94,3 @@ macro(add_clang) ) endif() endmacro(add_clang) - diff --git a/cmake/phasar_macros.cmake b/cmake/phasar_macros.cmake index 1c20a9196..3a6d28dbb 100644 --- a/cmake/phasar_macros.cmake +++ b/cmake/phasar_macros.cmake @@ -254,4 +254,3 @@ macro(subdirlist result curdir) set(${result} ${dirlist}) endmacro(subdirlist) - diff --git a/test/build_systems_tests/advanced_project/main.c b/test/build_systems_tests/advanced_project/main.c index 3392c6793..d2acc3e97 100644 --- a/test/build_systems_tests/advanced_project/main.c +++ b/test/build_systems_tests/advanced_project/main.c @@ -1,5 +1,6 @@ #include "src1.h" #include "src2.h" + #include #include diff --git a/test/build_systems_tests/cmake_project/main.c b/test/build_systems_tests/cmake_project/main.c index d15fb9d8a..49b9262c2 100644 --- a/test/build_systems_tests/cmake_project/main.c +++ b/test/build_systems_tests/cmake_project/main.c @@ -1,5 +1,6 @@ // A simple program that computes the square root of a number #include "mysources/one_source.h" + #include #include diff --git a/test/build_systems_tests/nomechanism_project/main.cpp b/test/build_systems_tests/nomechanism_project/main.cpp index becd3c95e..b58ec4d7b 100644 --- a/test/build_systems_tests/nomechanism_project/main.cpp +++ b/test/build_systems_tests/nomechanism_project/main.cpp @@ -1,5 +1,6 @@ #include "source_1.h" #include "source_2.h" + #include using namespace std; diff --git a/test/build_systems_tests/nomechanism_project/source_1.cpp b/test/build_systems_tests/nomechanism_project/source_1.cpp index abbf3c2cc..e97704c26 100644 --- a/test/build_systems_tests/nomechanism_project/source_1.cpp +++ b/test/build_systems_tests/nomechanism_project/source_1.cpp @@ -1,4 +1,5 @@ #include "source_1.h" + #include "source_2.h" const int src1_const = 42; diff --git a/test/clang_test_code/SimpleProject/main.cpp b/test/clang_test_code/SimpleProject/main.cpp index 065d550eb..e86dd792a 100644 --- a/test/clang_test_code/SimpleProject/main.cpp +++ b/test/clang_test_code/SimpleProject/main.cpp @@ -13,6 +13,7 @@ */ #include "myfunctions.h" + #include using namespace std; diff --git a/test/llvm_test_code/globals/globals_ctor_2_2.cpp b/test/llvm_test_code/globals/globals_ctor_2_2.cpp index ee1e9ee25..597706ae2 100644 --- a/test/llvm_test_code/globals/globals_ctor_2_2.cpp +++ b/test/llvm_test_code/globals/globals_ctor_2_2.cpp @@ -1,7 +1,7 @@ -#include - #include "globals_ctor_2_1.h" +#include + int createBar() { return 234765; } int bar = createBar(); diff --git a/test/llvm_test_code/openssl/key_derivation/key-derivation1.c b/test/llvm_test_code/openssl/key_derivation/key-derivation1.c index 32c37bc11..699fe9176 100644 --- a/test/llvm_test_code/openssl/key_derivation/key-derivation1.c +++ b/test/llvm_test_code/openssl/key_derivation/key-derivation1.c @@ -1,9 +1,8 @@ -#include -#include - #include #include #include +#include +#include void error(const char *fmt, ...); diff --git a/test/llvm_test_code/openssl/key_derivation/key-derivation2.c b/test/llvm_test_code/openssl/key_derivation/key-derivation2.c index 4157bb564..d8b3c9975 100644 --- a/test/llvm_test_code/openssl/key_derivation/key-derivation2.c +++ b/test/llvm_test_code/openssl/key_derivation/key-derivation2.c @@ -1,10 +1,9 @@ -#include -#include -#include - #include #include #include +#include +#include +#include void error(const char *fmt, ...); diff --git a/test/llvm_test_code/openssl/key_derivation/key-derivation3.c b/test/llvm_test_code/openssl/key_derivation/key-derivation3.c index c3f5ed1ab..808cea86f 100644 --- a/test/llvm_test_code/openssl/key_derivation/key-derivation3.c +++ b/test/llvm_test_code/openssl/key_derivation/key-derivation3.c @@ -1,10 +1,9 @@ -#include -#include -#include - #include #include #include +#include +#include +#include void error(const char *fmt, ...); diff --git a/test/llvm_test_code/openssl/key_derivation/key-derivation4.c b/test/llvm_test_code/openssl/key_derivation/key-derivation4.c index f493de1dc..98a67b9a0 100644 --- a/test/llvm_test_code/openssl/key_derivation/key-derivation4.c +++ b/test/llvm_test_code/openssl/key_derivation/key-derivation4.c @@ -1,10 +1,9 @@ -#include -#include -#include - #include #include #include +#include +#include +#include void error(const char *fmt, ...); diff --git a/test/llvm_test_code/openssl/key_derivation/key-derivation5.c b/test/llvm_test_code/openssl/key_derivation/key-derivation5.c index 2ddd53dcf..1169ff97b 100644 --- a/test/llvm_test_code/openssl/key_derivation/key-derivation5.c +++ b/test/llvm_test_code/openssl/key_derivation/key-derivation5.c @@ -1,10 +1,9 @@ -#include -#include -#include - #include #include #include +#include +#include +#include void error(const char *fmt, ...); diff --git a/test/llvm_test_code/openssl/key_derivation/key-derivation6.c b/test/llvm_test_code/openssl/key_derivation/key-derivation6.c index 75985f1a8..6de7b8136 100644 --- a/test/llvm_test_code/openssl/key_derivation/key-derivation6.c +++ b/test/llvm_test_code/openssl/key_derivation/key-derivation6.c @@ -1,10 +1,9 @@ -#include -#include -#include - #include #include #include +#include +#include +#include void error(const char *fmt, ...); diff --git a/test/llvm_test_code/openssl/key_derivation/key-derivation7.c b/test/llvm_test_code/openssl/key_derivation/key-derivation7.c index 0a3b822de..e89324b2c 100644 --- a/test/llvm_test_code/openssl/key_derivation/key-derivation7.c +++ b/test/llvm_test_code/openssl/key_derivation/key-derivation7.c @@ -1,10 +1,9 @@ -#include -#include -#include - #include #include #include +#include +#include +#include void error(const char *fmt, ...); diff --git a/test/llvm_test_code/openssl/key_derivation/key-derivation8.c b/test/llvm_test_code/openssl/key_derivation/key-derivation8.c index 3c844bcee..c9346523a 100644 --- a/test/llvm_test_code/openssl/key_derivation/key-derivation8.c +++ b/test/llvm_test_code/openssl/key_derivation/key-derivation8.c @@ -1,10 +1,9 @@ -#include -#include -#include - #include #include #include +#include +#include +#include void error(const char *fmt, ...); diff --git a/test/llvm_test_code/openssl/secure_heap/memory6.c b/test/llvm_test_code/openssl/secure_heap/memory6.c index 1859de3c6..891d134a9 100644 --- a/test/llvm_test_code/openssl/secure_heap/memory6.c +++ b/test/llvm_test_code/openssl/secure_heap/memory6.c @@ -1,9 +1,8 @@ +#include #include #include #include -#include - void error(const char *fmt, ...); int main() { diff --git a/test/llvm_test_code/openssl/secure_heap/memory7.c b/test/llvm_test_code/openssl/secure_heap/memory7.c index 51861f178..4bb15f8a0 100644 --- a/test/llvm_test_code/openssl/secure_heap/memory7.c +++ b/test/llvm_test_code/openssl/secure_heap/memory7.c @@ -1,9 +1,8 @@ +#include #include #include #include -#include - void error(const char *fmt, ...); int main() { diff --git a/test/llvm_test_code/openssl/secure_memory/memory1.c b/test/llvm_test_code/openssl/secure_memory/memory1.c index 926cc4bdb..7b5b18a48 100644 --- a/test/llvm_test_code/openssl/secure_memory/memory1.c +++ b/test/llvm_test_code/openssl/secure_memory/memory1.c @@ -1,8 +1,7 @@ +#include #include #include -#include - void error(const char *fmt, ...); int main() { diff --git a/test/llvm_test_code/openssl/secure_memory/memory2.c b/test/llvm_test_code/openssl/secure_memory/memory2.c index dee6cb582..f8e42f9ab 100644 --- a/test/llvm_test_code/openssl/secure_memory/memory2.c +++ b/test/llvm_test_code/openssl/secure_memory/memory2.c @@ -1,8 +1,7 @@ +#include #include #include -#include - void error(const char *fmt, ...); int main() { diff --git a/test/llvm_test_code/openssl/secure_memory/memory3.c b/test/llvm_test_code/openssl/secure_memory/memory3.c index 15189fbf0..70421c290 100644 --- a/test/llvm_test_code/openssl/secure_memory/memory3.c +++ b/test/llvm_test_code/openssl/secure_memory/memory3.c @@ -1,9 +1,8 @@ +#include #include #include #include -#include - void error(const char *fmt, ...); int main() { diff --git a/test/llvm_test_code/openssl/secure_memory/memory4.c b/test/llvm_test_code/openssl/secure_memory/memory4.c index 5bd50fa1f..5fa16bd77 100644 --- a/test/llvm_test_code/openssl/secure_memory/memory4.c +++ b/test/llvm_test_code/openssl/secure_memory/memory4.c @@ -1,9 +1,8 @@ +#include #include #include #include -#include - void error(const char *fmt, ...); int main() { diff --git a/test/llvm_test_code/openssl/secure_memory/memory5.c b/test/llvm_test_code/openssl/secure_memory/memory5.c index ce639ae55..1b1f9bb53 100644 --- a/test/llvm_test_code/openssl/secure_memory/memory5.c +++ b/test/llvm_test_code/openssl/secure_memory/memory5.c @@ -1,9 +1,8 @@ +#include #include #include #include -#include - void error(const char *fmt, ...); int main() { diff --git a/test/llvm_test_code/xtaint/xtaint08.cpp b/test/llvm_test_code/xtaint/xtaint08.cpp index 4246cccc9..70187ede5 100644 --- a/test/llvm_test_code/xtaint/xtaint08.cpp +++ b/test/llvm_test_code/xtaint/xtaint08.cpp @@ -1,5 +1,6 @@ #define PHASAR_ENABLE_TAINT_CONFIGURATION_API #include "../../../devapis/taint/phasar_taint_config_api.h" + #include struct Bar { From bbe775a95618227bf3824c18513516a5595a9c5c Mon Sep 17 00:00:00 2001 From: mxHuber Date: Thu, 6 Jun 2024 13:21:03 +0200 Subject: [PATCH 14/78] fixed all but one test in IDEInstInteractionAnalysisTest --- .../IDEInstInteractionAnalysisTest.cpp | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/unittests/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEInstInteractionAnalysisTest.cpp b/unittests/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEInstInteractionAnalysisTest.cpp index fab423848..5e0a4bfb7 100644 --- a/unittests/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEInstInteractionAnalysisTest.cpp +++ b/unittests/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEInstInteractionAnalysisTest.cpp @@ -240,6 +240,7 @@ TEST_F(IDEInstInteractionAnalysisTest, FieldSensStructConstruction_02) { TEST_F(IDEInstInteractionAnalysisTest, ArrayEquality_01) { initializeIR("array_01_cpp.ll"); + const auto *Main = IRDB->getFunction("main"); const auto *Inst = getNthInstruction(Main, 2); auto FlowFact = IDEIIAFlowFact::create(Inst); @@ -247,19 +248,20 @@ TEST_F(IDEInstInteractionAnalysisTest, ArrayEquality_01) { Inst = getNthInstruction(Main, 4); FlowFact = IDEIIAFlowFact::create(Inst); - Inst = getNthInstruction(Main, 14); + Inst = getNthInstruction(Main, 13); auto OtherFlowFact = IDEIIAFlowFact::create(Inst); ASSERT_NE(FlowFact, OtherFlowFact); - Inst = getNthInstruction(Main, 14); + Inst = getNthInstruction(Main, 13); + FlowFact = IDEIIAFlowFact::create(Inst); - Inst = getNthInstruction(Main, 19); + Inst = getNthInstruction(Main, 18); OtherFlowFact = IDEIIAFlowFact::create(Inst); ASSERT_EQ(FlowFact, OtherFlowFact); - Inst = getNthInstruction(Main, 17); + Inst = getNthInstruction(Main, 16); FlowFact = IDEIIAFlowFact::create(Inst); - Inst = getNthInstruction(Main, 22); + Inst = getNthInstruction(Main, 21); OtherFlowFact = IDEIIAFlowFact::create(Inst); ASSERT_EQ(FlowFact, OtherFlowFact); } @@ -844,13 +846,13 @@ TEST_F(IDEInstInteractionAnalysisTest, HandleHeapTest_01) { std::set GroundTruth; GroundTruth.emplace( std::tuple>( - "main", 19, "retval", {"3"})); + "main", 17, "retval", {"3"})); GroundTruth.emplace( std::tuple>( - "main", 19, "i", {"6", "7"})); + "main", 17, "i", {"5", "6"})); GroundTruth.emplace( std::tuple>( - "main", 19, "j", {"6", "7", "8", "10", "9"})); + "main", 17, "j", {"5", "6", "7", "8", "9"})); doAnalysisAndCompareResults("heap_01_cpp.ll", {"main"}, GroundTruth, false); } From c235afc5e539d9d270176ab5c0bec339fae55fc1 Mon Sep 17 00:00:00 2001 From: mxHuber Date: Thu, 6 Jun 2024 18:27:20 +0200 Subject: [PATCH 15/78] fixed all but two tests --- .../exceptions/exceptions_01_cpp_icfg.json | 712 +++++++++--------- .../ControlFlow/LLVMBasedCFGTest.cpp | 4 +- .../ControlFlow/LLVMBasedICFGExportTest.cpp | 2 +- .../ControlFlow/LLVMBasedICFG_OTFTest.cpp | 4 + .../IDEInstInteractionAnalysisTest.cpp | 3 + 5 files changed, 357 insertions(+), 368 deletions(-) diff --git a/test/json_test_code/exceptions/exceptions_01_cpp_icfg.json b/test/json_test_code/exceptions/exceptions_01_cpp_icfg.json index e93e96c4e..1b0c2accc 100644 --- a/test/json_test_code/exceptions/exceptions_01_cpp_icfg.json +++ b/test/json_test_code/exceptions/exceptions_01_cpp_icfg.json @@ -1,388 +1,118 @@ [ { "from": { - "IR": "%x = alloca i32, align 4 | ID: 1", - "column": 7, - "line": 5, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", - "sourceCodeFunctionName": "foo()", - "sourceCodeLine": "int x = 42;" - }, - "to": { - "IR": "store i32 42, i32* %x, align 4 | ID: 3", - "column": 7, - "line": 5, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", - "sourceCodeFunctionName": "foo()", - "sourceCodeLine": "int x = 42;" - } - }, - { - "from": { - "IR": "store i32 42, i32* %x, align 4 | ID: 3", - "column": 7, - "line": 5, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", - "sourceCodeFunctionName": "foo()", - "sourceCodeLine": "int x = 42;" - }, - "to": { - "IR": "%call = call i32 @rand() | ID: 4", - "column": 7, - "line": 6, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", - "sourceCodeFunctionName": "foo()", - "sourceCodeLine": "if (rand()) {" - } - }, - { - "from": { - "IR": "%call = call i32 @rand() | ID: 4", - "column": 7, - "line": 6, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", - "sourceCodeFunctionName": "foo()", - "sourceCodeLine": "if (rand()) {" - }, - "to": { - "IR": "%tobool = icmp ne i32 %call, 0 | ID: 5", - "column": 7, - "line": 6, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", - "sourceCodeFunctionName": "foo()", - "sourceCodeLine": "if (rand()) {" - } - }, - { - "from": { - "IR": "%tobool = icmp ne i32 %call, 0 | ID: 5", - "column": 7, - "line": 6, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", - "sourceCodeFunctionName": "foo()", - "sourceCodeLine": "if (rand()) {" - }, - "to": { - "IR": "br i1 %tobool, label %if.then, label %if.else | ID: 6", - "column": 7, - "line": 6, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", - "sourceCodeFunctionName": "foo()", - "sourceCodeLine": "if (rand()) {" - } - }, - { - "from": { - "IR": "br i1 %tobool, label %if.then, label %if.else | ID: 6", - "column": 7, - "line": 6, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", - "sourceCodeFunctionName": "foo()", - "sourceCodeLine": "if (rand()) {" - }, - "to": { - "IR": "%0 = load i32, i32* %x, align 4 | ID: 7", - "column": 7, - "line": 7, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", - "sourceCodeFunctionName": "foo()", - "sourceCodeLine": "x += 4;" - } - }, - { - "from": { - "IR": "br i1 %tobool, label %if.then, label %if.else | ID: 6", - "column": 7, - "line": 6, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", - "sourceCodeFunctionName": "foo()", - "sourceCodeLine": "if (rand()) {" - }, - "to": { - "IR": "%exception = call i8* @__cxa_allocate_exception(i64 4) | ID: 11", - "column": 5, - "line": 9, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", - "sourceCodeFunctionName": "foo()", - "sourceCodeLine": "throw 2353782;" - } - }, - { - "from": { - "IR": "%0 = load i32, i32* %x, align 4 | ID: 7", - "column": 7, - "line": 7, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", - "sourceCodeFunctionName": "foo()", - "sourceCodeLine": "x += 4;" - }, - "to": { - "IR": "%add = add nsw i32 %0, 4 | ID: 8", - "column": 7, - "line": 7, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", - "sourceCodeFunctionName": "foo()", - "sourceCodeLine": "x += 4;" - } - }, - { - "from": { - "IR": "%add = add nsw i32 %0, 4 | ID: 8", - "column": 7, - "line": 7, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", - "sourceCodeFunctionName": "foo()", - "sourceCodeLine": "x += 4;" - }, - "to": { - "IR": "store i32 %add, i32* %x, align 4 | ID: 9", - "column": 7, - "line": 7, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", - "sourceCodeFunctionName": "foo()", - "sourceCodeLine": "x += 4;" - } - }, - { - "from": { - "IR": "store i32 %add, i32* %x, align 4 | ID: 9", - "column": 7, - "line": 7, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", - "sourceCodeFunctionName": "foo()", - "sourceCodeLine": "x += 4;" - }, - "to": { - "IR": "br label %if.end | ID: 10", - "column": 3, - "line": 8, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", - "sourceCodeFunctionName": "foo()", - "sourceCodeLine": "} else {" - } - }, - { - "from": { - "IR": "br label %if.end | ID: 10", - "column": 3, - "line": 8, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", - "sourceCodeFunctionName": "foo()", - "sourceCodeLine": "} else {" - }, - "to": { - "IR": "%2 = load i32, i32* %x, align 4 | ID: 16", - "column": 10, - "line": 12, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", - "sourceCodeFunctionName": "foo()", - "sourceCodeLine": "return x;" - } - }, - { - "from": { - "IR": "%exception = call i8* @__cxa_allocate_exception(i64 4) | ID: 11", - "column": 5, - "line": 9, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", - "sourceCodeFunctionName": "foo()", - "sourceCodeLine": "throw 2353782;" - }, - "to": { - "IR": "%1 = bitcast i8* %exception to i32* | ID: 12", - "column": 5, - "line": 9, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", - "sourceCodeFunctionName": "foo()", - "sourceCodeLine": "throw 2353782;" - } - }, - { - "from": { - "IR": "%1 = bitcast i8* %exception to i32* | ID: 12", - "column": 5, - "line": 9, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", - "sourceCodeFunctionName": "foo()", - "sourceCodeLine": "throw 2353782;" - }, - "to": { - "IR": "store i32 2353782, i32* %1, align 16 | ID: 13", - "column": 5, - "line": 9, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", - "sourceCodeFunctionName": "foo()", - "sourceCodeLine": "throw 2353782;" - } - }, - { - "from": { - "IR": "store i32 2353782, i32* %1, align 16 | ID: 13", - "column": 5, - "line": 9, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", - "sourceCodeFunctionName": "foo()", - "sourceCodeLine": "throw 2353782;" - }, - "to": { - "IR": "call void @__cxa_throw(i8* %exception, i8* bitcast (i8** @_ZTIi to i8*), i8* null) | ID: 14", - "column": 5, - "line": 9, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", - "sourceCodeFunctionName": "foo()", - "sourceCodeLine": "throw 2353782;" - } - }, - { - "from": { - "IR": "call void @__cxa_throw(i8* %exception, i8* bitcast (i8** @_ZTIi to i8*), i8* null) | ID: 14", - "column": 5, - "line": 9, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", - "sourceCodeFunctionName": "foo()", - "sourceCodeLine": "throw 2353782;" - }, - "to": { - "IR": "unreachable | ID: 15", - "column": 5, - "line": 9, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", - "sourceCodeFunctionName": "foo()", - "sourceCodeLine": "throw 2353782;" - } - }, - { - "from": { - "IR": "%2 = load i32, i32* %x, align 4 | ID: 16", - "column": 10, - "line": 12, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", - "sourceCodeFunctionName": "foo()", - "sourceCodeLine": "return x;" - }, - "to": { - "IR": "ret i32 %2 | ID: 17", - "column": 3, - "line": 12, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", - "sourceCodeFunctionName": "foo()", - "sourceCodeLine": "return x;" - } - }, - { - "from": { - "IR": "%retval = alloca i32, align 4 | ID: 18", + "IR": "%retval = alloca i32, align 4 | ID: 17", "column": 0, "line": 0, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "" }, "to": { - "IR": "%a = alloca i32, align 4 | ID: 19", + "IR": "%a = alloca i32, align 4 | ID: 18", "column": 7, "line": 16, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "int a = 3;" } }, { "from": { - "IR": "%a = alloca i32, align 4 | ID: 19", + "IR": "%a = alloca i32, align 4 | ID: 18", "column": 7, "line": 16, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "int a = 3;" }, "to": { - "IR": "%exn.slot = alloca i8*, align 8 | ID: 20", + "IR": "%exn.slot = alloca ptr, align 8 | ID: 19", "column": 0, "line": 0, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "" } }, { "from": { - "IR": "%exn.slot = alloca i8*, align 8 | ID: 20", + "IR": "%exn.slot = alloca ptr, align 8 | ID: 19", "column": 0, "line": 0, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "" }, "to": { - "IR": "%ehselector.slot = alloca i32, align 4 | ID: 21", + "IR": "%ehselector.slot = alloca i32, align 4 | ID: 20", "column": 0, "line": 0, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "" } }, { "from": { - "IR": "%ehselector.slot = alloca i32, align 4 | ID: 21", + "IR": "%ehselector.slot = alloca i32, align 4 | ID: 20", "column": 0, "line": 0, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "" }, "to": { - "IR": "store i32 0, i32* %retval, align 4 | ID: 22", + "IR": "store i32 0, ptr %retval, align 4 | ID: 21", "column": 0, "line": 0, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "" } }, { "from": { - "IR": "store i32 0, i32* %retval, align 4 | ID: 22", + "IR": "store i32 0, ptr %retval, align 4 | ID: 21", "column": 0, "line": 0, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "" }, "to": { - "IR": "store i32 3, i32* %a, align 4 | ID: 24", + "IR": "store i32 3, ptr %a, align 4 | ID: 23", "column": 7, "line": 16, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "int a = 3;" } }, { "from": { - "IR": "store i32 3, i32* %a, align 4 | ID: 24", + "IR": "store i32 3, ptr %a, align 4 | ID: 23", "column": 7, "line": 16, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "int a = 3;" }, "to": { - "IR": "%call = invoke i32 @_Z3foov()\n to label %invoke.cont unwind label %lpad | ID: 25", + "IR": "%call = invoke noundef i32 @_Z3foov()\n to label %invoke.cont unwind label %lpad | ID: 24", "column": 9, "line": 18, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "a = foo();" } }, { "from": { - "IR": "%call = invoke i32 @_Z3foov()\n to label %invoke.cont unwind label %lpad | ID: 25", + "IR": "%call = invoke noundef i32 @_Z3foov()\n to label %invoke.cont unwind label %lpad | ID: 24", "column": 9, "line": 18, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "a = foo();" }, @@ -390,35 +120,35 @@ "IR": "%x = alloca i32, align 4 | ID: 1", "column": 7, "line": 5, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "foo()", "sourceCodeLine": "int x = 42;" } }, { "from": { - "IR": "ret i32 %2 | ID: 17", + "IR": "ret i32 %1 | ID: 16", "column": 3, "line": 12, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "foo()", "sourceCodeLine": "return x;" }, "to": { - "IR": "store i32 %call, i32* %a, align 4 | ID: 26", + "IR": "store i32 %call, ptr %a, align 4 | ID: 25", "column": 7, "line": 18, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "a = foo();" } }, { "from": { - "IR": "%call = invoke i32 @_Z3foov()\n to label %invoke.cont unwind label %lpad | ID: 25", + "IR": "%call = invoke noundef i32 @_Z3foov()\n to label %invoke.cont unwind label %lpad | ID: 24", "column": 9, "line": 18, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "a = foo();" }, @@ -426,279 +156,531 @@ "IR": "%x = alloca i32, align 4 | ID: 1", "column": 7, "line": 5, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "foo()", "sourceCodeLine": "int x = 42;" } }, { "from": { - "IR": "ret i32 %2 | ID: 17", + "IR": "ret i32 %1 | ID: 16", "column": 3, "line": 12, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "foo()", "sourceCodeLine": "return x;" }, "to": { - "IR": "%0 = landingpad { i8*, i32 }\n catch i8* null | ID: 28", + "IR": "%0 = landingpad { ptr, i32 }\n catch ptr null | ID: 27", "column": 1, "line": 23, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "}" } }, { "from": { - "IR": "store i32 %call, i32* %a, align 4 | ID: 26", + "IR": "store i32 %call, ptr %a, align 4 | ID: 25", "column": 7, "line": 18, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "a = foo();" }, "to": { - "IR": "br label %try.cont | ID: 27", + "IR": "br label %try.cont | ID: 26", "column": 3, "line": 19, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "} catch (...) {" } }, { "from": { - "IR": "br label %try.cont | ID: 27", + "IR": "br label %try.cont | ID: 26", "column": 3, "line": 19, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "} catch (...) {" }, "to": { - "IR": "%4 = load i32, i32* %a, align 4 | ID: 39", + "IR": "%4 = load i32, ptr %a, align 4 | ID: 38", "column": 10, "line": 22, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "return a;" } }, { "from": { - "IR": "%0 = landingpad { i8*, i32 }\n catch i8* null | ID: 28", + "IR": "%0 = landingpad { ptr, i32 }\n catch ptr null | ID: 27", "column": 1, "line": 23, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "}" }, "to": { - "IR": "%1 = extractvalue { i8*, i32 } %0, 0 | ID: 29", + "IR": "%1 = extractvalue { ptr, i32 } %0, 0 | ID: 28", "column": 1, "line": 23, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "}" } }, { "from": { - "IR": "%1 = extractvalue { i8*, i32 } %0, 0 | ID: 29", + "IR": "%1 = extractvalue { ptr, i32 } %0, 0 | ID: 28", "column": 1, "line": 23, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "}" }, "to": { - "IR": "store i8* %1, i8** %exn.slot, align 8 | ID: 30", + "IR": "store ptr %1, ptr %exn.slot, align 8 | ID: 29", "column": 1, "line": 23, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "}" } }, { "from": { - "IR": "store i8* %1, i8** %exn.slot, align 8 | ID: 30", + "IR": "store ptr %1, ptr %exn.slot, align 8 | ID: 29", "column": 1, "line": 23, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "}" }, "to": { - "IR": "%2 = extractvalue { i8*, i32 } %0, 1 | ID: 31", + "IR": "%2 = extractvalue { ptr, i32 } %0, 1 | ID: 30", "column": 1, "line": 23, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "}" } }, { "from": { - "IR": "%2 = extractvalue { i8*, i32 } %0, 1 | ID: 31", + "IR": "%2 = extractvalue { ptr, i32 } %0, 1 | ID: 30", "column": 1, "line": 23, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "}" }, "to": { - "IR": "store i32 %2, i32* %ehselector.slot, align 4 | ID: 32", + "IR": "store i32 %2, ptr %ehselector.slot, align 4 | ID: 31", "column": 1, "line": 23, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "}" } }, { "from": { - "IR": "store i32 %2, i32* %ehselector.slot, align 4 | ID: 32", + "IR": "store i32 %2, ptr %ehselector.slot, align 4 | ID: 31", "column": 1, "line": 23, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "}" }, "to": { - "IR": "br label %catch | ID: 33", + "IR": "br label %catch | ID: 32", "column": 1, "line": 23, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "}" } }, { "from": { - "IR": "br label %catch | ID: 33", + "IR": "br label %catch | ID: 32", "column": 1, "line": 23, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "}" }, "to": { - "IR": "%exn = load i8*, i8** %exn.slot, align 8 | ID: 34", + "IR": "%exn = load ptr, ptr %exn.slot, align 8 | ID: 33", "column": 3, "line": 19, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "} catch (...) {" } }, { "from": { - "IR": "%exn = load i8*, i8** %exn.slot, align 8 | ID: 34", + "IR": "%exn = load ptr, ptr %exn.slot, align 8 | ID: 33", "column": 3, "line": 19, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "} catch (...) {" }, "to": { - "IR": "%3 = call i8* @__cxa_begin_catch(i8* %exn) | ID: 35", + "IR": "%3 = call ptr @__cxa_begin_catch(ptr %exn) | ID: 34", "column": 3, "line": 19, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "} catch (...) {" } }, { "from": { - "IR": "%3 = call i8* @__cxa_begin_catch(i8* %exn) | ID: 35", + "IR": "%3 = call ptr @__cxa_begin_catch(ptr %exn) | ID: 34", "column": 3, "line": 19, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "} catch (...) {" }, "to": { - "IR": "store i32 -1, i32* %a, align 4 | ID: 36", + "IR": "store i32 -1, ptr %a, align 4 | ID: 35", "column": 7, "line": 20, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "a = -1;" } }, { "from": { - "IR": "store i32 -1, i32* %a, align 4 | ID: 36", + "IR": "store i32 -1, ptr %a, align 4 | ID: 35", "column": 7, "line": 20, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "a = -1;" }, "to": { - "IR": "call void @__cxa_end_catch() | ID: 37", + "IR": "call void @__cxa_end_catch() | ID: 36", "column": 3, "line": 21, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "}" } }, { "from": { - "IR": "call void @__cxa_end_catch() | ID: 37", + "IR": "call void @__cxa_end_catch() | ID: 36", "column": 3, "line": 21, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "}" }, "to": { - "IR": "br label %try.cont | ID: 38", + "IR": "br label %try.cont | ID: 37", "column": 3, "line": 21, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "}" } }, { "from": { - "IR": "br label %try.cont | ID: 38", + "IR": "br label %try.cont | ID: 37", "column": 3, "line": 21, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "}" }, "to": { - "IR": "%4 = load i32, i32* %a, align 4 | ID: 39", + "IR": "%4 = load i32, ptr %a, align 4 | ID: 38", "column": 10, "line": 22, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "return a;" } }, { "from": { - "IR": "%4 = load i32, i32* %a, align 4 | ID: 39", + "IR": "%4 = load i32, ptr %a, align 4 | ID: 38", "column": 10, "line": 22, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "return a;" }, "to": { - "IR": "ret i32 %4 | ID: 40", + "IR": "ret i32 %4 | ID: 39", "column": 3, "line": 22, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "return a;" } + }, + { + "from": { + "IR": "%x = alloca i32, align 4 | ID: 1", + "column": 7, + "line": 5, + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFunctionName": "foo()", + "sourceCodeLine": "int x = 42;" + }, + "to": { + "IR": "store i32 42, ptr %x, align 4 | ID: 3", + "column": 7, + "line": 5, + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFunctionName": "foo()", + "sourceCodeLine": "int x = 42;" + } + }, + { + "from": { + "IR": "store i32 42, ptr %x, align 4 | ID: 3", + "column": 7, + "line": 5, + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFunctionName": "foo()", + "sourceCodeLine": "int x = 42;" + }, + "to": { + "IR": "%call = call i32 @rand() | ID: 4", + "column": 7, + "line": 6, + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFunctionName": "foo()", + "sourceCodeLine": "if (rand()) {" + } + }, + { + "from": { + "IR": "%call = call i32 @rand() | ID: 4", + "column": 7, + "line": 6, + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFunctionName": "foo()", + "sourceCodeLine": "if (rand()) {" + }, + "to": { + "IR": "%tobool = icmp ne i32 %call, 0 | ID: 5", + "column": 7, + "line": 6, + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFunctionName": "foo()", + "sourceCodeLine": "if (rand()) {" + } + }, + { + "from": { + "IR": "%tobool = icmp ne i32 %call, 0 | ID: 5", + "column": 7, + "line": 6, + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFunctionName": "foo()", + "sourceCodeLine": "if (rand()) {" + }, + "to": { + "IR": "br i1 %tobool, label %if.then, label %if.else | ID: 6", + "column": 7, + "line": 6, + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFunctionName": "foo()", + "sourceCodeLine": "if (rand()) {" + } + }, + { + "from": { + "IR": "br i1 %tobool, label %if.then, label %if.else | ID: 6", + "column": 7, + "line": 6, + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFunctionName": "foo()", + "sourceCodeLine": "if (rand()) {" + }, + "to": { + "IR": "%0 = load i32, ptr %x, align 4 | ID: 7", + "column": 7, + "line": 7, + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFunctionName": "foo()", + "sourceCodeLine": "x += 4;" + } + }, + { + "from": { + "IR": "br i1 %tobool, label %if.then, label %if.else | ID: 6", + "column": 7, + "line": 6, + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFunctionName": "foo()", + "sourceCodeLine": "if (rand()) {" + }, + "to": { + "IR": "%exception = call ptr @__cxa_allocate_exception(i64 4) | ID: 11", + "column": 5, + "line": 9, + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFunctionName": "foo()", + "sourceCodeLine": "throw 2353782;" + } + }, + { + "from": { + "IR": "%0 = load i32, ptr %x, align 4 | ID: 7", + "column": 7, + "line": 7, + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFunctionName": "foo()", + "sourceCodeLine": "x += 4;" + }, + "to": { + "IR": "%add = add nsw i32 %0, 4 | ID: 8", + "column": 7, + "line": 7, + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFunctionName": "foo()", + "sourceCodeLine": "x += 4;" + } + }, + { + "from": { + "IR": "%add = add nsw i32 %0, 4 | ID: 8", + "column": 7, + "line": 7, + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFunctionName": "foo()", + "sourceCodeLine": "x += 4;" + }, + "to": { + "IR": "store i32 %add, ptr %x, align 4 | ID: 9", + "column": 7, + "line": 7, + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFunctionName": "foo()", + "sourceCodeLine": "x += 4;" + } + }, + { + "from": { + "IR": "store i32 %add, ptr %x, align 4 | ID: 9", + "column": 7, + "line": 7, + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFunctionName": "foo()", + "sourceCodeLine": "x += 4;" + }, + "to": { + "IR": "br label %if.end | ID: 10", + "column": 3, + "line": 8, + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFunctionName": "foo()", + "sourceCodeLine": "} else {" + } + }, + { + "from": { + "IR": "br label %if.end | ID: 10", + "column": 3, + "line": 8, + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFunctionName": "foo()", + "sourceCodeLine": "} else {" + }, + "to": { + "IR": "%1 = load i32, ptr %x, align 4 | ID: 15", + "column": 10, + "line": 12, + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFunctionName": "foo()", + "sourceCodeLine": "return x;" + } + }, + { + "from": { + "IR": "%exception = call ptr @__cxa_allocate_exception(i64 4) | ID: 11", + "column": 5, + "line": 9, + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFunctionName": "foo()", + "sourceCodeLine": "throw 2353782;" + }, + "to": { + "IR": "store i32 2353782, ptr %exception, align 16 | ID: 12", + "column": 5, + "line": 9, + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFunctionName": "foo()", + "sourceCodeLine": "throw 2353782;" + } + }, + { + "from": { + "IR": "store i32 2353782, ptr %exception, align 16 | ID: 12", + "column": 5, + "line": 9, + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFunctionName": "foo()", + "sourceCodeLine": "throw 2353782;" + }, + "to": { + "IR": "call void @__cxa_throw(ptr %exception, ptr @_ZTIi, ptr null) | ID: 13", + "column": 5, + "line": 9, + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFunctionName": "foo()", + "sourceCodeLine": "throw 2353782;" + } + }, + { + "from": { + "IR": "call void @__cxa_throw(ptr %exception, ptr @_ZTIi, ptr null) | ID: 13", + "column": 5, + "line": 9, + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFunctionName": "foo()", + "sourceCodeLine": "throw 2353782;" + }, + "to": { + "IR": "unreachable | ID: 14", + "column": 5, + "line": 9, + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFunctionName": "foo()", + "sourceCodeLine": "throw 2353782;" + } + }, + { + "from": { + "IR": "%1 = load i32, ptr %x, align 4 | ID: 15", + "column": 10, + "line": 12, + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFunctionName": "foo()", + "sourceCodeLine": "return x;" + }, + "to": { + "IR": "ret i32 %1 | ID: 16", + "column": 3, + "line": 12, + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFunctionName": "foo()", + "sourceCodeLine": "return x;" + } } -] +] \ No newline at end of file diff --git a/unittests/PhasarLLVM/ControlFlow/LLVMBasedCFGTest.cpp b/unittests/PhasarLLVM/ControlFlow/LLVMBasedCFGTest.cpp index 26c8f30d2..3753a403a 100644 --- a/unittests/PhasarLLVM/ControlFlow/LLVMBasedCFGTest.cpp +++ b/unittests/PhasarLLVM/ControlFlow/LLVMBasedCFGTest.cpp @@ -195,7 +195,7 @@ TEST(LLVMBasedCFGTest, HandleFieldLoadsArray) { const auto *F = IRDB.getFunctionDefinition("main"); const auto *Inst = getNthInstruction(F, 1); ASSERT_FALSE(Cfg.isFieldLoad(Inst)); - Inst = getNthInstruction(F, 6); + Inst = getNthInstruction(F, 5); ASSERT_TRUE(Cfg.isFieldLoad(Inst)); } @@ -205,7 +205,7 @@ TEST(LLVMBasedCFGTest, HandleFieldStoreArray) { const auto *F = IRDB.getFunctionDefinition("main"); const auto *Inst = getNthInstruction(F, 1); ASSERT_FALSE(Cfg.isFieldStore(Inst)); - Inst = getNthInstruction(F, 9); + Inst = getNthInstruction(F, 8); ASSERT_TRUE(Cfg.isFieldStore(Inst)); } diff --git a/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFGExportTest.cpp b/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFGExportTest.cpp index 7eb5463a7..d89cd9931 100644 --- a/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFGExportTest.cpp +++ b/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFGExportTest.cpp @@ -321,7 +321,7 @@ TEST_F(LLVMBasedICFGExportTest, ExportICFGSource02) { TEST_F(LLVMBasedICFGExportTest, ExportICFGSource03) { auto Results = exportICFG("exceptions/exceptions_01_cpp_dbg.ll", /*asSrcCode*/ true); - // llvm::errs() << Results.dump(4) << '\n'; + llvm::errs() << Results.dump(4) << '\n'; verifySourceCodeJSON(Results, readJson("exceptions/exceptions_01_cpp_icfg.json")); } diff --git a/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFG_OTFTest.cpp b/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFG_OTFTest.cpp index ba4df9fc7..954b7fcef 100644 --- a/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFG_OTFTest.cpp +++ b/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFG_OTFTest.cpp @@ -33,6 +33,10 @@ TEST(LLVMBasedICFG_OTFTest, VirtualCallSite_7) { ASSERT_TRUE(VFuncB); const auto *CallToAFunc = getNthInstruction(F, 19); + // TODO: find out why call void %5(%struct.A* noundef nonnull align 8 + // dereferenceable(8) %3), !psr.id !32 is gone and which function to call + // instead + llvm::outs() << "CallToAFunc: " << *CallToAFunc << '\n'; ASSERT_TRUE(ICFG.isVirtualFunctionCall(CallToAFunc)); const auto &AsCallees = ICFG.getCalleesOfCallAt(CallToAFunc); ASSERT_EQ(AsCallees.size(), 2U); diff --git a/unittests/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEInstInteractionAnalysisTest.cpp b/unittests/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEInstInteractionAnalysisTest.cpp index 5e0a4bfb7..02b9865a7 100644 --- a/unittests/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEInstInteractionAnalysisTest.cpp +++ b/unittests/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEInstInteractionAnalysisTest.cpp @@ -367,6 +367,7 @@ TEST_F(IDEInstInteractionAnalysisTest, StructEquality_01) { TEST_F(IDEInstInteractionAnalysisTest, StructEquality_02) { initializeIR("struct_02_cpp.ll"); + IRDB->dump(); const auto *Main = IRDB->getFunction("main"); const auto *Inst = getNthInstruction(Main, 2); auto FlowFact = IDEIIAFlowFact::create(Inst); @@ -397,8 +398,10 @@ TEST_F(IDEInstInteractionAnalysisTest, StructEquality_02) { ASSERT_EQ(FlowFact, OtherFlowFact); Inst = getNthInstruction(Main, 6); + llvm::outs() << "Instruction to create flow fact from: " << *Inst << '\n'; FlowFact = IDEIIAFlowFact::create(Inst); Inst = getNthInstruction(Main, 9); + llvm::outs() << "Instruction to create flow fact from 2: " << *Inst << '\n'; OtherFlowFact = IDEIIAFlowFact::create(Inst); ASSERT_NE(FlowFact, OtherFlowFact); } From 311cb68153bb03e9b1cf702e4c13e96f6328f796 Mon Sep 17 00:00:00 2001 From: Fabian Schiebel Date: Fri, 7 Jun 2024 09:46:24 +0200 Subject: [PATCH 16/78] Fix IIAFlowFact equality --- .../DataFlow/IfdsIde/Problems/IDEInstInteractionAnalysis.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEInstInteractionAnalysis.cpp b/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEInstInteractionAnalysis.cpp index c6efc8783..a8898c9e9 100644 --- a/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEInstInteractionAnalysis.cpp +++ b/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEInstInteractionAnalysis.cpp @@ -11,6 +11,7 @@ #include "phasar/PhasarLLVM/Utils/LLVMShorthands.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/IR/Instruction.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/Value.h" @@ -108,9 +109,7 @@ bool IDEIIAFlowFact::operator==(const IDEIIAFlowFact &Other) const { } auto EqualGEPDescriptor = [](const llvm::GetElementPtrInst *Lhs, const llvm::GetElementPtrInst *Rhs) { - const auto *LhsI = llvm::dyn_cast(Lhs); - const auto *RhsI = llvm::dyn_cast(Rhs); - return LhsI->isSameOperationAs(RhsI); + return llvm::equal(Lhs->indices(), Rhs->indices()); }; for (unsigned Idx = 0; Idx < FieldDesc.size(); ++Idx) { if (!EqualGEPDescriptor(FieldDesc[Idx], Other.FieldDesc[Idx])) { From 4c043d9cafa3480a2474750cf8fc1d0f0b2dea6f Mon Sep 17 00:00:00 2001 From: Fabian Schiebel Date: Mon, 10 Jun 2024 09:37:07 +0200 Subject: [PATCH 17/78] Re-add getVFTableGlobal --- .../PhasarLLVM/ControlFlow/LLVMVFTableProvider.h | 9 +++++++++ .../ControlFlow/LLVMVFTableProvider.cpp | 16 +++++++++++++++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/include/phasar/PhasarLLVM/ControlFlow/LLVMVFTableProvider.h b/include/phasar/PhasarLLVM/ControlFlow/LLVMVFTableProvider.h index 4206070fc..ba3610296 100644 --- a/include/phasar/PhasarLLVM/ControlFlow/LLVMVFTableProvider.h +++ b/include/phasar/PhasarLLVM/ControlFlow/LLVMVFTableProvider.h @@ -12,6 +12,8 @@ #include "phasar/PhasarLLVM/TypeHierarchy/LLVMVFTable.h" +#include "llvm/ADT/StringMap.h" + #include namespace llvm { @@ -32,8 +34,15 @@ class LLVMVFTableProvider { [[nodiscard]] const LLVMVFTable * getVFTableOrNull(const llvm::StructType *Type) const; + [[nodiscard]] const llvm::GlobalVariable * + getVFTableGlobal(const llvm::StructType *Type) const; + + [[nodiscard]] const llvm::GlobalVariable * + getVFTableGlobal(const std::string &ClearTypeName) const; + private: std::unordered_map TypeVFTMap; + llvm::StringMap ClearNameTVMap; }; } // namespace psr diff --git a/lib/PhasarLLVM/ControlFlow/LLVMVFTableProvider.cpp b/lib/PhasarLLVM/ControlFlow/LLVMVFTableProvider.cpp index b34384bd2..46fd591c4 100644 --- a/lib/PhasarLLVM/ControlFlow/LLVMVFTableProvider.cpp +++ b/lib/PhasarLLVM/ControlFlow/LLVMVFTableProvider.cpp @@ -36,7 +36,6 @@ static std::vector getVirtualFunctions( LLVMVFTableProvider::LLVMVFTableProvider(const llvm::Module &Mod) { auto StructTypes = Mod.getIdentifiedStructTypes(); - llvm::StringMap ClearNameTVMap; for (const auto &Glob : Mod.globals()) { if (LLVMTypeHierarchy::isVTable(Glob.getName())) { @@ -63,3 +62,18 @@ LLVMVFTableProvider::getVFTableOrNull(const llvm::StructType *Type) const { auto It = TypeVFTMap.find(Type); return It != TypeVFTMap.end() ? &It->second : nullptr; } + +const llvm::GlobalVariable * +LLVMVFTableProvider::getVFTableGlobal(const llvm::StructType *Type) const { + auto Name = LLVMTypeHierarchy::removeStructOrClassPrefix(*Type); + return getVFTableGlobal(Name); +} + +const llvm::GlobalVariable * +LLVMVFTableProvider::getVFTableGlobal(const std::string &ClearTypeName) const { + if (auto It = ClearNameTVMap.find(ClearTypeName); + It != ClearNameTVMap.end()) { + return It->second; + } + return nullptr; +} From 04a895d3001a2d135dd3d4dea451e94237625071 Mon Sep 17 00:00:00 2001 From: mxHuber Date: Wed, 12 Jun 2024 06:50:36 +0200 Subject: [PATCH 18/78] fixed some newly failed tests --- .../exceptions/exceptions_01_cpp_icfg.json | 710 +++++++++--------- .../ControlFlow/LLVMBasedCFGTest.cpp | 4 +- .../IDEInstInteractionAnalysisTest.cpp | 18 +- .../Problems/IFDSConstAnalysisTest.cpp | 4 +- .../Problems/IFDSTaintAnalysisTest.cpp | 22 +- .../Pointer/LLVMAliasSetSerializationTest.cpp | 6 +- .../TaintConfig/TaintConfigTest.cpp | 8 +- 7 files changed, 395 insertions(+), 377 deletions(-) diff --git a/test/json_test_code/exceptions/exceptions_01_cpp_icfg.json b/test/json_test_code/exceptions/exceptions_01_cpp_icfg.json index 1b0c2accc..1cf20ffc8 100644 --- a/test/json_test_code/exceptions/exceptions_01_cpp_icfg.json +++ b/test/json_test_code/exceptions/exceptions_01_cpp_icfg.json @@ -1,118 +1,388 @@ [ { "from": { - "IR": "%retval = alloca i32, align 4 | ID: 17", + "IR": "%x = alloca i32, align 4 | ID: 1", + "column": 7, + "line": 5, + "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFunctionName": "foo()", + "sourceCodeLine": "int x = 42;" + }, + "to": { + "IR": "store i32 42, i32* %x, align 4 | ID: 3", + "column": 7, + "line": 5, + "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFunctionName": "foo()", + "sourceCodeLine": "int x = 42;" + } + }, + { + "from": { + "IR": "store i32 42, i32* %x, align 4 | ID: 3", + "column": 7, + "line": 5, + "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFunctionName": "foo()", + "sourceCodeLine": "int x = 42;" + }, + "to": { + "IR": "%call = call i32 @rand() | ID: 4", + "column": 7, + "line": 6, + "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFunctionName": "foo()", + "sourceCodeLine": "if (rand()) {" + } + }, + { + "from": { + "IR": "%call = call i32 @rand() | ID: 4", + "column": 7, + "line": 6, + "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFunctionName": "foo()", + "sourceCodeLine": "if (rand()) {" + }, + "to": { + "IR": "%tobool = icmp ne i32 %call, 0 | ID: 5", + "column": 7, + "line": 6, + "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFunctionName": "foo()", + "sourceCodeLine": "if (rand()) {" + } + }, + { + "from": { + "IR": "%tobool = icmp ne i32 %call, 0 | ID: 5", + "column": 7, + "line": 6, + "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFunctionName": "foo()", + "sourceCodeLine": "if (rand()) {" + }, + "to": { + "IR": "br i1 %tobool, label %if.then, label %if.else | ID: 6", + "column": 7, + "line": 6, + "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFunctionName": "foo()", + "sourceCodeLine": "if (rand()) {" + } + }, + { + "from": { + "IR": "br i1 %tobool, label %if.then, label %if.else | ID: 6", + "column": 7, + "line": 6, + "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFunctionName": "foo()", + "sourceCodeLine": "if (rand()) {" + }, + "to": { + "IR": "%0 = load i32, i32* %x, align 4 | ID: 7", + "column": 7, + "line": 7, + "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFunctionName": "foo()", + "sourceCodeLine": "x += 4;" + } + }, + { + "from": { + "IR": "br i1 %tobool, label %if.then, label %if.else | ID: 6", + "column": 7, + "line": 6, + "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFunctionName": "foo()", + "sourceCodeLine": "if (rand()) {" + }, + "to": { + "IR": "%exception = call i8* @__cxa_allocate_exception(i64 4) | ID: 11", + "column": 5, + "line": 9, + "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFunctionName": "foo()", + "sourceCodeLine": "throw 2353782;" + } + }, + { + "from": { + "IR": "%0 = load i32, i32* %x, align 4 | ID: 7", + "column": 7, + "line": 7, + "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFunctionName": "foo()", + "sourceCodeLine": "x += 4;" + }, + "to": { + "IR": "%add = add nsw i32 %0, 4 | ID: 8", + "column": 7, + "line": 7, + "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFunctionName": "foo()", + "sourceCodeLine": "x += 4;" + } + }, + { + "from": { + "IR": "%add = add nsw i32 %0, 4 | ID: 8", + "column": 7, + "line": 7, + "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFunctionName": "foo()", + "sourceCodeLine": "x += 4;" + }, + "to": { + "IR": "store i32 %add, i32* %x, align 4 | ID: 9", + "column": 7, + "line": 7, + "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFunctionName": "foo()", + "sourceCodeLine": "x += 4;" + } + }, + { + "from": { + "IR": "store i32 %add, i32* %x, align 4 | ID: 9", + "column": 7, + "line": 7, + "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFunctionName": "foo()", + "sourceCodeLine": "x += 4;" + }, + "to": { + "IR": "br label %if.end | ID: 10", + "column": 3, + "line": 8, + "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFunctionName": "foo()", + "sourceCodeLine": "} else {" + } + }, + { + "from": { + "IR": "br label %if.end | ID: 10", + "column": 3, + "line": 8, + "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFunctionName": "foo()", + "sourceCodeLine": "} else {" + }, + "to": { + "IR": "%2 = load i32, i32* %x, align 4 | ID: 16", + "column": 10, + "line": 12, + "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFunctionName": "foo()", + "sourceCodeLine": "return x;" + } + }, + { + "from": { + "IR": "%exception = call i8* @__cxa_allocate_exception(i64 4) | ID: 11", + "column": 5, + "line": 9, + "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFunctionName": "foo()", + "sourceCodeLine": "throw 2353782;" + }, + "to": { + "IR": "%1 = bitcast i8* %exception to i32* | ID: 12", + "column": 5, + "line": 9, + "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFunctionName": "foo()", + "sourceCodeLine": "throw 2353782;" + } + }, + { + "from": { + "IR": "%1 = bitcast i8* %exception to i32* | ID: 12", + "column": 5, + "line": 9, + "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFunctionName": "foo()", + "sourceCodeLine": "throw 2353782;" + }, + "to": { + "IR": "store i32 2353782, i32* %1, align 16 | ID: 13", + "column": 5, + "line": 9, + "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFunctionName": "foo()", + "sourceCodeLine": "throw 2353782;" + } + }, + { + "from": { + "IR": "store i32 2353782, i32* %1, align 16 | ID: 13", + "column": 5, + "line": 9, + "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFunctionName": "foo()", + "sourceCodeLine": "throw 2353782;" + }, + "to": { + "IR": "call void @__cxa_throw(i8* %exception, i8* bitcast (i8** @_ZTIi to i8*), i8* null) | ID: 14", + "column": 5, + "line": 9, + "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFunctionName": "foo()", + "sourceCodeLine": "throw 2353782;" + } + }, + { + "from": { + "IR": "call void @__cxa_throw(i8* %exception, i8* bitcast (i8** @_ZTIi to i8*), i8* null) | ID: 14", + "column": 5, + "line": 9, + "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFunctionName": "foo()", + "sourceCodeLine": "throw 2353782;" + }, + "to": { + "IR": "unreachable | ID: 15", + "column": 5, + "line": 9, + "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFunctionName": "foo()", + "sourceCodeLine": "throw 2353782;" + } + }, + { + "from": { + "IR": "%2 = load i32, i32* %x, align 4 | ID: 16", + "column": 10, + "line": 12, + "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFunctionName": "foo()", + "sourceCodeLine": "return x;" + }, + "to": { + "IR": "ret i32 %2 | ID: 17", + "column": 3, + "line": 12, + "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFunctionName": "foo()", + "sourceCodeLine": "return x;" + } + }, + { + "from": { + "IR": "%retval = alloca i32, align 4 | ID: 18", "column": 0, "line": 0, - "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "" }, "to": { - "IR": "%a = alloca i32, align 4 | ID: 18", + "IR": "%a = alloca i32, align 4 | ID: 19", "column": 7, "line": 16, - "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "int a = 3;" } }, { "from": { - "IR": "%a = alloca i32, align 4 | ID: 18", + "IR": "%a = alloca i32, align 4 | ID: 19", "column": 7, "line": 16, - "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "int a = 3;" }, "to": { - "IR": "%exn.slot = alloca ptr, align 8 | ID: 19", + "IR": "%exn.slot = alloca i8*, align 8 | ID: 20", "column": 0, "line": 0, - "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "" } }, { "from": { - "IR": "%exn.slot = alloca ptr, align 8 | ID: 19", + "IR": "%exn.slot = alloca i8*, align 8 | ID: 20", "column": 0, "line": 0, - "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "" }, "to": { - "IR": "%ehselector.slot = alloca i32, align 4 | ID: 20", + "IR": "%ehselector.slot = alloca i32, align 4 | ID: 21", "column": 0, "line": 0, - "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "" } }, { "from": { - "IR": "%ehselector.slot = alloca i32, align 4 | ID: 20", + "IR": "%ehselector.slot = alloca i32, align 4 | ID: 21", "column": 0, "line": 0, - "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "" }, "to": { - "IR": "store i32 0, ptr %retval, align 4 | ID: 21", + "IR": "store i32 0, i32* %retval, align 4 | ID: 22", "column": 0, "line": 0, - "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "" } }, { "from": { - "IR": "store i32 0, ptr %retval, align 4 | ID: 21", + "IR": "store i32 0, i32* %retval, align 4 | ID: 22", "column": 0, "line": 0, - "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "" }, "to": { - "IR": "store i32 3, ptr %a, align 4 | ID: 23", + "IR": "store i32 3, i32* %a, align 4 | ID: 24", "column": 7, "line": 16, - "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "int a = 3;" } }, { "from": { - "IR": "store i32 3, ptr %a, align 4 | ID: 23", + "IR": "store i32 3, i32* %a, align 4 | ID: 24", "column": 7, "line": 16, - "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "int a = 3;" }, "to": { - "IR": "%call = invoke noundef i32 @_Z3foov()\n to label %invoke.cont unwind label %lpad | ID: 24", + "IR": "%call = invoke i32 @_Z3foov()\n to label %invoke.cont unwind label %lpad | ID: 25", "column": 9, "line": 18, - "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "a = foo();" } }, { "from": { - "IR": "%call = invoke noundef i32 @_Z3foov()\n to label %invoke.cont unwind label %lpad | ID: 24", + "IR": "%call = invoke i32 @_Z3foov()\n to label %invoke.cont unwind label %lpad | ID: 25", "column": 9, "line": 18, - "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "a = foo();" }, @@ -120,35 +390,35 @@ "IR": "%x = alloca i32, align 4 | ID: 1", "column": 7, "line": 5, - "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "foo()", "sourceCodeLine": "int x = 42;" } }, { "from": { - "IR": "ret i32 %1 | ID: 16", + "IR": "ret i32 %2 | ID: 17", "column": 3, "line": 12, - "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "foo()", "sourceCodeLine": "return x;" }, "to": { - "IR": "store i32 %call, ptr %a, align 4 | ID: 25", + "IR": "store i32 %call, i32* %a, align 4 | ID: 26", "column": 7, "line": 18, - "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "a = foo();" } }, { "from": { - "IR": "%call = invoke noundef i32 @_Z3foov()\n to label %invoke.cont unwind label %lpad | ID: 24", + "IR": "%call = invoke i32 @_Z3foov()\n to label %invoke.cont unwind label %lpad | ID: 25", "column": 9, "line": 18, - "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "a = foo();" }, @@ -156,531 +426,279 @@ "IR": "%x = alloca i32, align 4 | ID: 1", "column": 7, "line": 5, - "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "foo()", "sourceCodeLine": "int x = 42;" } }, { "from": { - "IR": "ret i32 %1 | ID: 16", + "IR": "ret i32 %2 | ID: 17", "column": 3, "line": 12, - "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "foo()", "sourceCodeLine": "return x;" }, "to": { - "IR": "%0 = landingpad { ptr, i32 }\n catch ptr null | ID: 27", + "IR": "%0 = landingpad { i8*, i32 }\n catch i8* null | ID: 28", "column": 1, "line": 23, - "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "}" } }, { "from": { - "IR": "store i32 %call, ptr %a, align 4 | ID: 25", + "IR": "store i32 %call, i32* %a, align 4 | ID: 26", "column": 7, "line": 18, - "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "a = foo();" }, "to": { - "IR": "br label %try.cont | ID: 26", + "IR": "br label %try.cont | ID: 27", "column": 3, "line": 19, - "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "} catch (...) {" } }, { "from": { - "IR": "br label %try.cont | ID: 26", + "IR": "br label %try.cont | ID: 27", "column": 3, "line": 19, - "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "} catch (...) {" }, "to": { - "IR": "%4 = load i32, ptr %a, align 4 | ID: 38", + "IR": "%4 = load i32, i32* %a, align 4 | ID: 39", "column": 10, "line": 22, - "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "return a;" } }, { "from": { - "IR": "%0 = landingpad { ptr, i32 }\n catch ptr null | ID: 27", + "IR": "%0 = landingpad { i8*, i32 }\n catch i8* null | ID: 28", "column": 1, "line": 23, - "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "}" }, "to": { - "IR": "%1 = extractvalue { ptr, i32 } %0, 0 | ID: 28", + "IR": "%1 = extractvalue { i8*, i32 } %0, 0 | ID: 29", "column": 1, "line": 23, - "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "}" } }, { "from": { - "IR": "%1 = extractvalue { ptr, i32 } %0, 0 | ID: 28", + "IR": "%1 = extractvalue { i8*, i32 } %0, 0 | ID: 29", "column": 1, "line": 23, - "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "}" }, "to": { - "IR": "store ptr %1, ptr %exn.slot, align 8 | ID: 29", + "IR": "store i8* %1, i8** %exn.slot, align 8 | ID: 30", "column": 1, "line": 23, - "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "}" } }, { "from": { - "IR": "store ptr %1, ptr %exn.slot, align 8 | ID: 29", + "IR": "store i8* %1, i8** %exn.slot, align 8 | ID: 30", "column": 1, "line": 23, - "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "}" }, "to": { - "IR": "%2 = extractvalue { ptr, i32 } %0, 1 | ID: 30", + "IR": "%2 = extractvalue { i8*, i32 } %0, 1 | ID: 31", "column": 1, "line": 23, - "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "}" } }, { "from": { - "IR": "%2 = extractvalue { ptr, i32 } %0, 1 | ID: 30", + "IR": "%2 = extractvalue { i8*, i32 } %0, 1 | ID: 31", "column": 1, "line": 23, - "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "}" }, "to": { - "IR": "store i32 %2, ptr %ehselector.slot, align 4 | ID: 31", + "IR": "store i32 %2, i32* %ehselector.slot, align 4 | ID: 32", "column": 1, "line": 23, - "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "}" } }, { "from": { - "IR": "store i32 %2, ptr %ehselector.slot, align 4 | ID: 31", + "IR": "store i32 %2, i32* %ehselector.slot, align 4 | ID: 32", "column": 1, "line": 23, - "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "}" }, "to": { - "IR": "br label %catch | ID: 32", + "IR": "br label %catch | ID: 33", "column": 1, "line": 23, - "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "}" } }, { "from": { - "IR": "br label %catch | ID: 32", + "IR": "br label %catch | ID: 33", "column": 1, "line": 23, - "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "}" }, "to": { - "IR": "%exn = load ptr, ptr %exn.slot, align 8 | ID: 33", + "IR": "%exn = load i8*, i8** %exn.slot, align 8 | ID: 34", "column": 3, "line": 19, - "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "} catch (...) {" } }, { "from": { - "IR": "%exn = load ptr, ptr %exn.slot, align 8 | ID: 33", + "IR": "%exn = load i8*, i8** %exn.slot, align 8 | ID: 34", "column": 3, "line": 19, - "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "} catch (...) {" }, "to": { - "IR": "%3 = call ptr @__cxa_begin_catch(ptr %exn) | ID: 34", + "IR": "%3 = call i8* @__cxa_begin_catch(i8* %exn) | ID: 35", "column": 3, "line": 19, - "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "} catch (...) {" } }, { "from": { - "IR": "%3 = call ptr @__cxa_begin_catch(ptr %exn) | ID: 34", + "IR": "%3 = call i8* @__cxa_begin_catch(i8* %exn) | ID: 35", "column": 3, "line": 19, - "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "} catch (...) {" }, "to": { - "IR": "store i32 -1, ptr %a, align 4 | ID: 35", + "IR": "store i32 -1, i32* %a, align 4 | ID: 36", "column": 7, "line": 20, - "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "a = -1;" } }, { "from": { - "IR": "store i32 -1, ptr %a, align 4 | ID: 35", + "IR": "store i32 -1, i32* %a, align 4 | ID: 36", "column": 7, "line": 20, - "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "a = -1;" }, "to": { - "IR": "call void @__cxa_end_catch() | ID: 36", + "IR": "call void @__cxa_end_catch() | ID: 37", "column": 3, "line": 21, - "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "}" } }, { "from": { - "IR": "call void @__cxa_end_catch() | ID: 36", + "IR": "call void @__cxa_end_catch() | ID: 37", "column": 3, "line": 21, - "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "}" }, "to": { - "IR": "br label %try.cont | ID: 37", + "IR": "br label %try.cont | ID: 38", "column": 3, "line": 21, - "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "}" } }, { "from": { - "IR": "br label %try.cont | ID: 37", + "IR": "br label %try.cont | ID: 38", "column": 3, "line": 21, - "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "}" }, "to": { - "IR": "%4 = load i32, ptr %a, align 4 | ID: 38", + "IR": "%4 = load i32, i32* %a, align 4 | ID: 39", "column": 10, "line": 22, - "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "return a;" } }, { "from": { - "IR": "%4 = load i32, ptr %a, align 4 | ID: 38", + "IR": "%4 = load i32, i32* %a, align 4 | ID: 39", "column": 10, "line": 22, - "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "return a;" }, "to": { - "IR": "ret i32 %4 | ID: 39", + "IR": "ret i32 %4 | ID: 40", "column": 3, "line": 22, - "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "return a;" } - }, - { - "from": { - "IR": "%x = alloca i32, align 4 | ID: 1", - "column": 7, - "line": 5, - "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", - "sourceCodeFunctionName": "foo()", - "sourceCodeLine": "int x = 42;" - }, - "to": { - "IR": "store i32 42, ptr %x, align 4 | ID: 3", - "column": 7, - "line": 5, - "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", - "sourceCodeFunctionName": "foo()", - "sourceCodeLine": "int x = 42;" - } - }, - { - "from": { - "IR": "store i32 42, ptr %x, align 4 | ID: 3", - "column": 7, - "line": 5, - "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", - "sourceCodeFunctionName": "foo()", - "sourceCodeLine": "int x = 42;" - }, - "to": { - "IR": "%call = call i32 @rand() | ID: 4", - "column": 7, - "line": 6, - "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", - "sourceCodeFunctionName": "foo()", - "sourceCodeLine": "if (rand()) {" - } - }, - { - "from": { - "IR": "%call = call i32 @rand() | ID: 4", - "column": 7, - "line": 6, - "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", - "sourceCodeFunctionName": "foo()", - "sourceCodeLine": "if (rand()) {" - }, - "to": { - "IR": "%tobool = icmp ne i32 %call, 0 | ID: 5", - "column": 7, - "line": 6, - "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", - "sourceCodeFunctionName": "foo()", - "sourceCodeLine": "if (rand()) {" - } - }, - { - "from": { - "IR": "%tobool = icmp ne i32 %call, 0 | ID: 5", - "column": 7, - "line": 6, - "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", - "sourceCodeFunctionName": "foo()", - "sourceCodeLine": "if (rand()) {" - }, - "to": { - "IR": "br i1 %tobool, label %if.then, label %if.else | ID: 6", - "column": 7, - "line": 6, - "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", - "sourceCodeFunctionName": "foo()", - "sourceCodeLine": "if (rand()) {" - } - }, - { - "from": { - "IR": "br i1 %tobool, label %if.then, label %if.else | ID: 6", - "column": 7, - "line": 6, - "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", - "sourceCodeFunctionName": "foo()", - "sourceCodeLine": "if (rand()) {" - }, - "to": { - "IR": "%0 = load i32, ptr %x, align 4 | ID: 7", - "column": 7, - "line": 7, - "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", - "sourceCodeFunctionName": "foo()", - "sourceCodeLine": "x += 4;" - } - }, - { - "from": { - "IR": "br i1 %tobool, label %if.then, label %if.else | ID: 6", - "column": 7, - "line": 6, - "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", - "sourceCodeFunctionName": "foo()", - "sourceCodeLine": "if (rand()) {" - }, - "to": { - "IR": "%exception = call ptr @__cxa_allocate_exception(i64 4) | ID: 11", - "column": 5, - "line": 9, - "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", - "sourceCodeFunctionName": "foo()", - "sourceCodeLine": "throw 2353782;" - } - }, - { - "from": { - "IR": "%0 = load i32, ptr %x, align 4 | ID: 7", - "column": 7, - "line": 7, - "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", - "sourceCodeFunctionName": "foo()", - "sourceCodeLine": "x += 4;" - }, - "to": { - "IR": "%add = add nsw i32 %0, 4 | ID: 8", - "column": 7, - "line": 7, - "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", - "sourceCodeFunctionName": "foo()", - "sourceCodeLine": "x += 4;" - } - }, - { - "from": { - "IR": "%add = add nsw i32 %0, 4 | ID: 8", - "column": 7, - "line": 7, - "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", - "sourceCodeFunctionName": "foo()", - "sourceCodeLine": "x += 4;" - }, - "to": { - "IR": "store i32 %add, ptr %x, align 4 | ID: 9", - "column": 7, - "line": 7, - "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", - "sourceCodeFunctionName": "foo()", - "sourceCodeLine": "x += 4;" - } - }, - { - "from": { - "IR": "store i32 %add, ptr %x, align 4 | ID: 9", - "column": 7, - "line": 7, - "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", - "sourceCodeFunctionName": "foo()", - "sourceCodeLine": "x += 4;" - }, - "to": { - "IR": "br label %if.end | ID: 10", - "column": 3, - "line": 8, - "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", - "sourceCodeFunctionName": "foo()", - "sourceCodeLine": "} else {" - } - }, - { - "from": { - "IR": "br label %if.end | ID: 10", - "column": 3, - "line": 8, - "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", - "sourceCodeFunctionName": "foo()", - "sourceCodeLine": "} else {" - }, - "to": { - "IR": "%1 = load i32, ptr %x, align 4 | ID: 15", - "column": 10, - "line": 12, - "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", - "sourceCodeFunctionName": "foo()", - "sourceCodeLine": "return x;" - } - }, - { - "from": { - "IR": "%exception = call ptr @__cxa_allocate_exception(i64 4) | ID: 11", - "column": 5, - "line": 9, - "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", - "sourceCodeFunctionName": "foo()", - "sourceCodeLine": "throw 2353782;" - }, - "to": { - "IR": "store i32 2353782, ptr %exception, align 16 | ID: 12", - "column": 5, - "line": 9, - "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", - "sourceCodeFunctionName": "foo()", - "sourceCodeLine": "throw 2353782;" - } - }, - { - "from": { - "IR": "store i32 2353782, ptr %exception, align 16 | ID: 12", - "column": 5, - "line": 9, - "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", - "sourceCodeFunctionName": "foo()", - "sourceCodeLine": "throw 2353782;" - }, - "to": { - "IR": "call void @__cxa_throw(ptr %exception, ptr @_ZTIi, ptr null) | ID: 13", - "column": 5, - "line": 9, - "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", - "sourceCodeFunctionName": "foo()", - "sourceCodeLine": "throw 2353782;" - } - }, - { - "from": { - "IR": "call void @__cxa_throw(ptr %exception, ptr @_ZTIi, ptr null) | ID: 13", - "column": 5, - "line": 9, - "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", - "sourceCodeFunctionName": "foo()", - "sourceCodeLine": "throw 2353782;" - }, - "to": { - "IR": "unreachable | ID: 14", - "column": 5, - "line": 9, - "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", - "sourceCodeFunctionName": "foo()", - "sourceCodeLine": "throw 2353782;" - } - }, - { - "from": { - "IR": "%1 = load i32, ptr %x, align 4 | ID: 15", - "column": 10, - "line": 12, - "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", - "sourceCodeFunctionName": "foo()", - "sourceCodeLine": "return x;" - }, - "to": { - "IR": "ret i32 %1 | ID: 16", - "column": 3, - "line": 12, - "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", - "sourceCodeFunctionName": "foo()", - "sourceCodeLine": "return x;" - } } ] \ No newline at end of file diff --git a/unittests/PhasarLLVM/ControlFlow/LLVMBasedCFGTest.cpp b/unittests/PhasarLLVM/ControlFlow/LLVMBasedCFGTest.cpp index 3753a403a..26c8f30d2 100644 --- a/unittests/PhasarLLVM/ControlFlow/LLVMBasedCFGTest.cpp +++ b/unittests/PhasarLLVM/ControlFlow/LLVMBasedCFGTest.cpp @@ -195,7 +195,7 @@ TEST(LLVMBasedCFGTest, HandleFieldLoadsArray) { const auto *F = IRDB.getFunctionDefinition("main"); const auto *Inst = getNthInstruction(F, 1); ASSERT_FALSE(Cfg.isFieldLoad(Inst)); - Inst = getNthInstruction(F, 5); + Inst = getNthInstruction(F, 6); ASSERT_TRUE(Cfg.isFieldLoad(Inst)); } @@ -205,7 +205,7 @@ TEST(LLVMBasedCFGTest, HandleFieldStoreArray) { const auto *F = IRDB.getFunctionDefinition("main"); const auto *Inst = getNthInstruction(F, 1); ASSERT_FALSE(Cfg.isFieldStore(Inst)); - Inst = getNthInstruction(F, 8); + Inst = getNthInstruction(F, 9); ASSERT_TRUE(Cfg.isFieldStore(Inst)); } diff --git a/unittests/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEInstInteractionAnalysisTest.cpp b/unittests/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEInstInteractionAnalysisTest.cpp index 02b9865a7..c05d4745d 100644 --- a/unittests/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEInstInteractionAnalysisTest.cpp +++ b/unittests/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEInstInteractionAnalysisTest.cpp @@ -143,11 +143,11 @@ TEST_F(IDEInstInteractionAnalysisTest, FieldSensArrayConstruction_01) { llvm::outs() << "Instruction to create flow fact from: " << *Inst << '\n'; auto FlowFact = IDEIIAFlowFact::create(Inst); llvm::outs() << FlowFact << '\n'; - Inst = getNthInstruction(Main, 13); + Inst = getNthInstruction(Main, 14); llvm::outs() << "Instruction to create flow fact from: " << *Inst << '\n'; FlowFact = IDEIIAFlowFact::create(Inst); llvm::outs() << FlowFact << '\n'; - Inst = getNthInstruction(Main, 16); + Inst = getNthInstruction(Main, 17); llvm::outs() << "Instruction to create flow fact from: " << *Inst << '\n'; FlowFact = IDEIIAFlowFact::create(Inst); llvm::outs() << FlowFact << '\n'; @@ -248,20 +248,20 @@ TEST_F(IDEInstInteractionAnalysisTest, ArrayEquality_01) { Inst = getNthInstruction(Main, 4); FlowFact = IDEIIAFlowFact::create(Inst); - Inst = getNthInstruction(Main, 13); + Inst = getNthInstruction(Main, 14); auto OtherFlowFact = IDEIIAFlowFact::create(Inst); ASSERT_NE(FlowFact, OtherFlowFact); - Inst = getNthInstruction(Main, 13); + Inst = getNthInstruction(Main, 14); FlowFact = IDEIIAFlowFact::create(Inst); - Inst = getNthInstruction(Main, 18); + Inst = getNthInstruction(Main, 19); OtherFlowFact = IDEIIAFlowFact::create(Inst); ASSERT_EQ(FlowFact, OtherFlowFact); - Inst = getNthInstruction(Main, 16); + Inst = getNthInstruction(Main, 17); FlowFact = IDEIIAFlowFact::create(Inst); - Inst = getNthInstruction(Main, 21); + Inst = getNthInstruction(Main, 22); OtherFlowFact = IDEIIAFlowFact::create(Inst); ASSERT_EQ(FlowFact, OtherFlowFact); } @@ -852,10 +852,10 @@ TEST_F(IDEInstInteractionAnalysisTest, HandleHeapTest_01) { "main", 17, "retval", {"3"})); GroundTruth.emplace( std::tuple>( - "main", 17, "i", {"5", "6"})); + "main", 17, "i", {"6", "7"})); GroundTruth.emplace( std::tuple>( - "main", 17, "j", {"5", "6", "7", "8", "9"})); + "main", 17, "j", {"6", "7", "8", "9", "10"})); doAnalysisAndCompareResults("heap_01_cpp.ll", {"main"}, GroundTruth, false); } diff --git a/unittests/PhasarLLVM/DataFlow/IfdsIde/Problems/IFDSConstAnalysisTest.cpp b/unittests/PhasarLLVM/DataFlow/IfdsIde/Problems/IFDSConstAnalysisTest.cpp index 25cf40461..77f858c30 100644 --- a/unittests/PhasarLLVM/DataFlow/IfdsIde/Problems/IFDSConstAnalysisTest.cpp +++ b/unittests/PhasarLLVM/DataFlow/IfdsIde/Problems/IFDSConstAnalysisTest.cpp @@ -175,7 +175,7 @@ TEST_F(IFDSConstAnalysisTest, HandlePointerTest_04) { initialize({PathToLlFiles + "pointer/pointer_04_cpp_m2r_dbg.ll"}); IFDSSolver Llvmconstsolver(*Constproblem, &HA->getICFG()); Llvmconstsolver.solve(); - compareResults({3}, Llvmconstsolver); + compareResults({4}, Llvmconstsolver); } /* ============== GLOBAL TESTS ============== */ @@ -352,7 +352,7 @@ TEST_F(IFDSConstAnalysisTest, HandleArrayTest_08) { initialize({PathToLlFiles + "array/array_08_cpp_m2r_dbg.ll"}); IFDSSolver Llvmconstsolver(*Constproblem, &HA->getICFG()); Llvmconstsolver.solve(); - compareResults({0}, Llvmconstsolver); + compareResults({}, Llvmconstsolver); } TEST_F(IFDSConstAnalysisTest, HandleArrayTest_09) { diff --git a/unittests/PhasarLLVM/DataFlow/IfdsIde/Problems/IFDSTaintAnalysisTest.cpp b/unittests/PhasarLLVM/DataFlow/IfdsIde/Problems/IFDSTaintAnalysisTest.cpp index 69ea7f0d2..0812fafcf 100644 --- a/unittests/PhasarLLVM/DataFlow/IfdsIde/Problems/IFDSTaintAnalysisTest.cpp +++ b/unittests/PhasarLLVM/DataFlow/IfdsIde/Problems/IFDSTaintAnalysisTest.cpp @@ -193,7 +193,7 @@ TEST_F(IFDSTaintAnalysisTest, TaintTest_ExceptionHandling_01) { IFDSSolver TaintSolver(*TaintProblem, &HA->getICFG()); TaintSolver.solve(); map> GroundTruth; - GroundTruth[14] = set{"13"}; + GroundTruth[15] = set{"14"}; compareResults(GroundTruth); } @@ -203,7 +203,7 @@ TEST_F(IFDSTaintAnalysisTest, TaintTest_ExceptionHandling_01_m2r) { IFDSSolver TaintSolver(*TaintProblem, &HA->getICFG()); TaintSolver.solve(); map> GroundTruth; - GroundTruth[5] = set{"0"}; + GroundTruth[6] = set{"0"}; compareResults(GroundTruth); } @@ -213,7 +213,7 @@ TEST_F(IFDSTaintAnalysisTest, TaintTest_ExceptionHandling_02) { IFDSSolver TaintSolver(*TaintProblem, &HA->getICFG()); TaintSolver.solve(); map> GroundTruth; - GroundTruth[16] = set{"15"}; + GroundTruth[17] = set{"16"}; compareResults(GroundTruth); } @@ -224,7 +224,7 @@ TEST_F(IFDSTaintAnalysisTest, TaintTest_ExceptionHandling_03) { TaintSolver.solve(); map> GroundTruth; GroundTruth[11] = set{"10"}; - GroundTruth[20] = set{"19"}; + GroundTruth[21] = set{"20"}; compareResults(GroundTruth); } @@ -234,7 +234,7 @@ TEST_F(IFDSTaintAnalysisTest, TaintTest_ExceptionHandling_04) { IFDSSolver TaintSolver(*TaintProblem, &HA->getICFG()); TaintSolver.solve(); map> GroundTruth; - GroundTruth[32] = set{"31"}; + GroundTruth[33] = set{"32"}; compareResults(GroundTruth); } @@ -245,7 +245,7 @@ TEST_F(IFDSTaintAnalysisTest, TaintTest_ExceptionHandling_05) { TaintSolver.solve(); map> GroundTruth; - GroundTruth[32] = set{"31"}; + GroundTruth[33] = set{"32"}; compareResults(GroundTruth); } @@ -255,7 +255,7 @@ TEST_F(IFDSTaintAnalysisTest, TaintTest_ExceptionHandling_06) { IFDSSolver TaintSolver(*TaintProblem, &HA->getICFG()); TaintSolver.solve(); map> GroundTruth; - GroundTruth[14] = set{"13"}; + GroundTruth[15] = set{"14"}; compareResults(GroundTruth); } @@ -265,7 +265,7 @@ TEST_F(IFDSTaintAnalysisTest, TaintTest_ExceptionHandling_07) { IFDSSolver TaintSolver(*TaintProblem, &HA->getICFG()); TaintSolver.solve(); map> GroundTruth; - GroundTruth[30] = set{"29"}; + GroundTruth[31] = set{"30"}; compareResults(GroundTruth); } @@ -275,7 +275,7 @@ TEST_F(IFDSTaintAnalysisTest, TaintTest_ExceptionHandling_08) { IFDSSolver TaintSolver(*TaintProblem, &HA->getICFG()); TaintSolver.solve(); map> GroundTruth; - GroundTruth[32] = set{"31"}; + GroundTruth[33] = set{"32"}; compareResults(GroundTruth); } @@ -285,7 +285,7 @@ TEST_F(IFDSTaintAnalysisTest, TaintTest_ExceptionHandling_09) { IFDSSolver TaintSolver(*TaintProblem, &HA->getICFG()); TaintSolver.solve(); map> GroundTruth; - GroundTruth[62] = set{"61"}; + GroundTruth[64] = set{"63"}; compareResults(GroundTruth); } @@ -295,7 +295,7 @@ TEST_F(IFDSTaintAnalysisTest, TaintTest_ExceptionHandling_10) { IFDSSolver TaintSolver(*TaintProblem, &HA->getICFG()); TaintSolver.solve(); map> GroundTruth; - GroundTruth[60] = set{"59"}; + GroundTruth[62] = set{"61"}; compareResults(GroundTruth); } diff --git a/unittests/PhasarLLVM/Pointer/LLVMAliasSetSerializationTest.cpp b/unittests/PhasarLLVM/Pointer/LLVMAliasSetSerializationTest.cpp index f0ee361b0..533212beb 100644 --- a/unittests/PhasarLLVM/Pointer/LLVMAliasSetSerializationTest.cpp +++ b/unittests/PhasarLLVM/Pointer/LLVMAliasSetSerializationTest.cpp @@ -103,11 +103,11 @@ TEST(LLVMAliasSetSerializationTest, Ser_Inter01) { TEST(LLVMAliasSetSerializationTest, Ser_Global01) { analyze("pointers/global_01_cpp.ll", - {{{"0", "14", "16", "2", "8", "_Z3fooPi.0"}, + {{{"0", "15", "17", "2", "9", "_Z3fooPi.0"}, {"1"}, - {"11"}, {"12"}, - {"6"}}, + {"13"}, + {"7"}}, {"_GLOBAL__sub_I_global_01.cpp", "_Z3fooPi", "__cxx_global_var_init", "main"}}); } diff --git a/unittests/PhasarLLVM/TaintConfig/TaintConfigTest.cpp b/unittests/PhasarLLVM/TaintConfig/TaintConfigTest.cpp index c7af226d5..3c6a3199f 100644 --- a/unittests/PhasarLLVM/TaintConfig/TaintConfigTest.cpp +++ b/unittests/PhasarLLVM/TaintConfig/TaintConfigTest.cpp @@ -367,10 +367,10 @@ TEST_F(TaintConfigTest, FunMember_02_Json) { psr::LLVMTaintConfig TConfig(IR, JsonConfig); llvm::outs() << TConfig << '\n'; - const llvm::Value *I1 = IR.getInstruction(16); - const llvm::Value *I2 = IR.getInstruction(52); - const llvm::Value *I3 = IR.getInstruction(61); - const llvm::Value *I4 = IR.getInstruction(69); + const llvm::Value *I1 = IR.getInstruction(18); + const llvm::Value *I2 = IR.getInstruction(54); + const llvm::Value *I3 = IR.getInstruction(63); + const llvm::Value *I4 = IR.getInstruction(71); ASSERT_TRUE(TConfig.isSource(I1)); ASSERT_TRUE(TConfig.isSource(I2)); ASSERT_TRUE(TConfig.isSource(I3)); From e31c5ae72f65378b6a4ed1222a187f82fc4aa97c Mon Sep 17 00:00:00 2001 From: Fabian Schiebel Date: Wed, 12 Jun 2024 10:03:10 +0200 Subject: [PATCH 19/78] trade soundness for precision in LLVMAliasSet --- lib/PhasarLLVM/Pointer/LLVMAliasSet.cpp | 40 ++++++++++++++++++------- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/lib/PhasarLLVM/Pointer/LLVMAliasSet.cpp b/lib/PhasarLLVM/Pointer/LLVMAliasSet.cpp index 83e796b6b..ebf8af538 100644 --- a/lib/PhasarLLVM/Pointer/LLVMAliasSet.cpp +++ b/lib/PhasarLLVM/Pointer/LLVMAliasSet.cpp @@ -23,6 +23,7 @@ #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Analysis/AliasAnalysis.h" +#include "llvm/Analysis/MemoryLocation.h" #include "llvm/IR/Argument.h" #include "llvm/IR/Constants.h" #include "llvm/IR/Function.h" @@ -36,6 +37,7 @@ #include "llvm/Support/Casting.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/FormatVariadic.h" +#include "llvm/Support/TypeSize.h" #include "nlohmann/json.hpp" @@ -315,24 +317,42 @@ bool LLVMAliasSet::intraIsReachableAllocationSiteTy( return false; } +static llvm::Type *getPointeeTypeOrNull(const llvm::Value *Ptr) { + assert(Ptr->getType()->isPointerTy()); + + if (!Ptr->getType()->isOpaquePointerTy()) { + return Ptr->getType()->getNonOpaquePointerElementType(); + } + + if (const auto *Arg = llvm::dyn_cast(Ptr)) { + if (auto *Ty = Arg->getParamByValType()) { + return Ty; + } + if (auto *Ty = Arg->getParamStructRetType()) { + return Ty; + } + } + if (const auto *Alloca = llvm::dyn_cast(Ptr)) { + return Alloca->getAllocatedType(); + } + return nullptr; +} + static bool mayAlias(llvm::AAResults &AA, const llvm::DataLayout &DL, const llvm::Value *V, const llvm::Value *Rep) { assert(V->getType()->isPointerTy()); assert(Rep->getType()->isPointerTy()); - auto *ElTy = !V->getType()->isOpaquePointerTy() - ? V->getType()->getNonOpaquePointerElementType() - : nullptr; - auto *RepElTy = !Rep->getType()->isOpaquePointerTy() - ? Rep->getType()->getNonOpaquePointerElementType() - : nullptr; + auto *ElTy = getPointeeTypeOrNull(V); + auto *RepElTy = getPointeeTypeOrNull(Rep); - auto VSize = ElTy && ElTy->isSized() ? DL.getTypeStoreSize(ElTy) - : llvm::MemoryLocation::UnknownSize; + auto VSize = ElTy && ElTy->isSized() + ? llvm::LocationSize::precise(DL.getTypeStoreSize(ElTy)) + : llvm::LocationSize::precise(1); auto RepSize = RepElTy && RepElTy->isSized() - ? DL.getTypeStoreSize(RepElTy) - : llvm::MemoryLocation::UnknownSize; + ? llvm::LocationSize::precise(DL.getTypeStoreSize(RepElTy)) + : llvm::LocationSize::precise(1); if (AA.alias(V, VSize, Rep, RepSize) != llvm::AliasResult::NoAlias) { return true; From e8c7f6516803199208ba644d191afb0a349b50d2 Mon Sep 17 00:00:00 2001 From: mxHuber Date: Wed, 12 Jun 2024 10:33:08 +0200 Subject: [PATCH 20/78] ci.yml update --- .github/workflows/ci.yml | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 79c2de56c..5967f993c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,7 +12,7 @@ jobs: strategy: fail-fast: true matrix: - compiler: [ [clang++-14, clang-14] ] + compiler: [ [clang++-15, clang-15] ] build: [ Debug, Release, DebugLibdeps ] include: - build: Debug @@ -42,18 +42,18 @@ jobs: - name: Install Strategy Dependencies shell: bash run: | - sudo apt-key adv --fetch-keys https://apt.llvm.org/llvm-snapshot.gpg.key - sudo add-apt-repository -y 'deb http://apt.llvm.org/focal/ llvm-toolchain-focal-14 main' - sudo apt-get update + sudo apt-key adv --fetch-keys https://apt.llvm.org/llvm-snapshot.gpg.key && \ + sudo add-apt-repository -y 'deb http://apt.llvm.org/focal/ llvm-toolchain-focal-15 main' && \ + sudo apt-get update && \ sudo apt-get -y install --no-install-recommends \ - ${{ matrix.compiler[1] }} \ - llvm-14-dev \ - libllvm14 \ - libclang-common-14-dev \ - libclang-14-dev \ - libclang-cpp14-dev \ - clang-tidy-14 \ - libclang-rt-14-dev + clang-15 \ + llvm-15-dev \ + libllvm15 \ + libclang-common-15-dev \ + libclang-15-dev \ + libclang-cpp15-dev \ + clang-tidy-15 \ + libclang-rt-15-dev - uses: swift-actions/setup-swift@v2 with: From c3081edb6fee8a2dda2d249f767923e0ee230042 Mon Sep 17 00:00:00 2001 From: mxHuber Date: Wed, 12 Jun 2024 10:44:26 +0200 Subject: [PATCH 21/78] Revert "fixed some newly failed tests" --- .../exceptions/exceptions_01_cpp_icfg.json | 710 +++++++++--------- .../ControlFlow/LLVMBasedCFGTest.cpp | 4 +- .../IDEInstInteractionAnalysisTest.cpp | 18 +- .../Problems/IFDSConstAnalysisTest.cpp | 4 +- .../Problems/IFDSTaintAnalysisTest.cpp | 22 +- .../Pointer/LLVMAliasSetSerializationTest.cpp | 6 +- .../TaintConfig/TaintConfigTest.cpp | 8 +- 7 files changed, 377 insertions(+), 395 deletions(-) diff --git a/test/json_test_code/exceptions/exceptions_01_cpp_icfg.json b/test/json_test_code/exceptions/exceptions_01_cpp_icfg.json index 1cf20ffc8..1b0c2accc 100644 --- a/test/json_test_code/exceptions/exceptions_01_cpp_icfg.json +++ b/test/json_test_code/exceptions/exceptions_01_cpp_icfg.json @@ -1,388 +1,118 @@ [ { "from": { - "IR": "%x = alloca i32, align 4 | ID: 1", - "column": 7, - "line": 5, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", - "sourceCodeFunctionName": "foo()", - "sourceCodeLine": "int x = 42;" - }, - "to": { - "IR": "store i32 42, i32* %x, align 4 | ID: 3", - "column": 7, - "line": 5, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", - "sourceCodeFunctionName": "foo()", - "sourceCodeLine": "int x = 42;" - } - }, - { - "from": { - "IR": "store i32 42, i32* %x, align 4 | ID: 3", - "column": 7, - "line": 5, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", - "sourceCodeFunctionName": "foo()", - "sourceCodeLine": "int x = 42;" - }, - "to": { - "IR": "%call = call i32 @rand() | ID: 4", - "column": 7, - "line": 6, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", - "sourceCodeFunctionName": "foo()", - "sourceCodeLine": "if (rand()) {" - } - }, - { - "from": { - "IR": "%call = call i32 @rand() | ID: 4", - "column": 7, - "line": 6, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", - "sourceCodeFunctionName": "foo()", - "sourceCodeLine": "if (rand()) {" - }, - "to": { - "IR": "%tobool = icmp ne i32 %call, 0 | ID: 5", - "column": 7, - "line": 6, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", - "sourceCodeFunctionName": "foo()", - "sourceCodeLine": "if (rand()) {" - } - }, - { - "from": { - "IR": "%tobool = icmp ne i32 %call, 0 | ID: 5", - "column": 7, - "line": 6, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", - "sourceCodeFunctionName": "foo()", - "sourceCodeLine": "if (rand()) {" - }, - "to": { - "IR": "br i1 %tobool, label %if.then, label %if.else | ID: 6", - "column": 7, - "line": 6, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", - "sourceCodeFunctionName": "foo()", - "sourceCodeLine": "if (rand()) {" - } - }, - { - "from": { - "IR": "br i1 %tobool, label %if.then, label %if.else | ID: 6", - "column": 7, - "line": 6, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", - "sourceCodeFunctionName": "foo()", - "sourceCodeLine": "if (rand()) {" - }, - "to": { - "IR": "%0 = load i32, i32* %x, align 4 | ID: 7", - "column": 7, - "line": 7, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", - "sourceCodeFunctionName": "foo()", - "sourceCodeLine": "x += 4;" - } - }, - { - "from": { - "IR": "br i1 %tobool, label %if.then, label %if.else | ID: 6", - "column": 7, - "line": 6, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", - "sourceCodeFunctionName": "foo()", - "sourceCodeLine": "if (rand()) {" - }, - "to": { - "IR": "%exception = call i8* @__cxa_allocate_exception(i64 4) | ID: 11", - "column": 5, - "line": 9, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", - "sourceCodeFunctionName": "foo()", - "sourceCodeLine": "throw 2353782;" - } - }, - { - "from": { - "IR": "%0 = load i32, i32* %x, align 4 | ID: 7", - "column": 7, - "line": 7, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", - "sourceCodeFunctionName": "foo()", - "sourceCodeLine": "x += 4;" - }, - "to": { - "IR": "%add = add nsw i32 %0, 4 | ID: 8", - "column": 7, - "line": 7, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", - "sourceCodeFunctionName": "foo()", - "sourceCodeLine": "x += 4;" - } - }, - { - "from": { - "IR": "%add = add nsw i32 %0, 4 | ID: 8", - "column": 7, - "line": 7, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", - "sourceCodeFunctionName": "foo()", - "sourceCodeLine": "x += 4;" - }, - "to": { - "IR": "store i32 %add, i32* %x, align 4 | ID: 9", - "column": 7, - "line": 7, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", - "sourceCodeFunctionName": "foo()", - "sourceCodeLine": "x += 4;" - } - }, - { - "from": { - "IR": "store i32 %add, i32* %x, align 4 | ID: 9", - "column": 7, - "line": 7, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", - "sourceCodeFunctionName": "foo()", - "sourceCodeLine": "x += 4;" - }, - "to": { - "IR": "br label %if.end | ID: 10", - "column": 3, - "line": 8, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", - "sourceCodeFunctionName": "foo()", - "sourceCodeLine": "} else {" - } - }, - { - "from": { - "IR": "br label %if.end | ID: 10", - "column": 3, - "line": 8, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", - "sourceCodeFunctionName": "foo()", - "sourceCodeLine": "} else {" - }, - "to": { - "IR": "%2 = load i32, i32* %x, align 4 | ID: 16", - "column": 10, - "line": 12, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", - "sourceCodeFunctionName": "foo()", - "sourceCodeLine": "return x;" - } - }, - { - "from": { - "IR": "%exception = call i8* @__cxa_allocate_exception(i64 4) | ID: 11", - "column": 5, - "line": 9, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", - "sourceCodeFunctionName": "foo()", - "sourceCodeLine": "throw 2353782;" - }, - "to": { - "IR": "%1 = bitcast i8* %exception to i32* | ID: 12", - "column": 5, - "line": 9, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", - "sourceCodeFunctionName": "foo()", - "sourceCodeLine": "throw 2353782;" - } - }, - { - "from": { - "IR": "%1 = bitcast i8* %exception to i32* | ID: 12", - "column": 5, - "line": 9, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", - "sourceCodeFunctionName": "foo()", - "sourceCodeLine": "throw 2353782;" - }, - "to": { - "IR": "store i32 2353782, i32* %1, align 16 | ID: 13", - "column": 5, - "line": 9, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", - "sourceCodeFunctionName": "foo()", - "sourceCodeLine": "throw 2353782;" - } - }, - { - "from": { - "IR": "store i32 2353782, i32* %1, align 16 | ID: 13", - "column": 5, - "line": 9, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", - "sourceCodeFunctionName": "foo()", - "sourceCodeLine": "throw 2353782;" - }, - "to": { - "IR": "call void @__cxa_throw(i8* %exception, i8* bitcast (i8** @_ZTIi to i8*), i8* null) | ID: 14", - "column": 5, - "line": 9, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", - "sourceCodeFunctionName": "foo()", - "sourceCodeLine": "throw 2353782;" - } - }, - { - "from": { - "IR": "call void @__cxa_throw(i8* %exception, i8* bitcast (i8** @_ZTIi to i8*), i8* null) | ID: 14", - "column": 5, - "line": 9, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", - "sourceCodeFunctionName": "foo()", - "sourceCodeLine": "throw 2353782;" - }, - "to": { - "IR": "unreachable | ID: 15", - "column": 5, - "line": 9, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", - "sourceCodeFunctionName": "foo()", - "sourceCodeLine": "throw 2353782;" - } - }, - { - "from": { - "IR": "%2 = load i32, i32* %x, align 4 | ID: 16", - "column": 10, - "line": 12, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", - "sourceCodeFunctionName": "foo()", - "sourceCodeLine": "return x;" - }, - "to": { - "IR": "ret i32 %2 | ID: 17", - "column": 3, - "line": 12, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", - "sourceCodeFunctionName": "foo()", - "sourceCodeLine": "return x;" - } - }, - { - "from": { - "IR": "%retval = alloca i32, align 4 | ID: 18", + "IR": "%retval = alloca i32, align 4 | ID: 17", "column": 0, "line": 0, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "" }, "to": { - "IR": "%a = alloca i32, align 4 | ID: 19", + "IR": "%a = alloca i32, align 4 | ID: 18", "column": 7, "line": 16, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "int a = 3;" } }, { "from": { - "IR": "%a = alloca i32, align 4 | ID: 19", + "IR": "%a = alloca i32, align 4 | ID: 18", "column": 7, "line": 16, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "int a = 3;" }, "to": { - "IR": "%exn.slot = alloca i8*, align 8 | ID: 20", + "IR": "%exn.slot = alloca ptr, align 8 | ID: 19", "column": 0, "line": 0, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "" } }, { "from": { - "IR": "%exn.slot = alloca i8*, align 8 | ID: 20", + "IR": "%exn.slot = alloca ptr, align 8 | ID: 19", "column": 0, "line": 0, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "" }, "to": { - "IR": "%ehselector.slot = alloca i32, align 4 | ID: 21", + "IR": "%ehselector.slot = alloca i32, align 4 | ID: 20", "column": 0, "line": 0, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "" } }, { "from": { - "IR": "%ehselector.slot = alloca i32, align 4 | ID: 21", + "IR": "%ehselector.slot = alloca i32, align 4 | ID: 20", "column": 0, "line": 0, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "" }, "to": { - "IR": "store i32 0, i32* %retval, align 4 | ID: 22", + "IR": "store i32 0, ptr %retval, align 4 | ID: 21", "column": 0, "line": 0, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "" } }, { "from": { - "IR": "store i32 0, i32* %retval, align 4 | ID: 22", + "IR": "store i32 0, ptr %retval, align 4 | ID: 21", "column": 0, "line": 0, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "" }, "to": { - "IR": "store i32 3, i32* %a, align 4 | ID: 24", + "IR": "store i32 3, ptr %a, align 4 | ID: 23", "column": 7, "line": 16, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "int a = 3;" } }, { "from": { - "IR": "store i32 3, i32* %a, align 4 | ID: 24", + "IR": "store i32 3, ptr %a, align 4 | ID: 23", "column": 7, "line": 16, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "int a = 3;" }, "to": { - "IR": "%call = invoke i32 @_Z3foov()\n to label %invoke.cont unwind label %lpad | ID: 25", + "IR": "%call = invoke noundef i32 @_Z3foov()\n to label %invoke.cont unwind label %lpad | ID: 24", "column": 9, "line": 18, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "a = foo();" } }, { "from": { - "IR": "%call = invoke i32 @_Z3foov()\n to label %invoke.cont unwind label %lpad | ID: 25", + "IR": "%call = invoke noundef i32 @_Z3foov()\n to label %invoke.cont unwind label %lpad | ID: 24", "column": 9, "line": 18, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "a = foo();" }, @@ -390,35 +120,35 @@ "IR": "%x = alloca i32, align 4 | ID: 1", "column": 7, "line": 5, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "foo()", "sourceCodeLine": "int x = 42;" } }, { "from": { - "IR": "ret i32 %2 | ID: 17", + "IR": "ret i32 %1 | ID: 16", "column": 3, "line": 12, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "foo()", "sourceCodeLine": "return x;" }, "to": { - "IR": "store i32 %call, i32* %a, align 4 | ID: 26", + "IR": "store i32 %call, ptr %a, align 4 | ID: 25", "column": 7, "line": 18, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "a = foo();" } }, { "from": { - "IR": "%call = invoke i32 @_Z3foov()\n to label %invoke.cont unwind label %lpad | ID: 25", + "IR": "%call = invoke noundef i32 @_Z3foov()\n to label %invoke.cont unwind label %lpad | ID: 24", "column": 9, "line": 18, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "a = foo();" }, @@ -426,279 +156,531 @@ "IR": "%x = alloca i32, align 4 | ID: 1", "column": 7, "line": 5, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "foo()", "sourceCodeLine": "int x = 42;" } }, { "from": { - "IR": "ret i32 %2 | ID: 17", + "IR": "ret i32 %1 | ID: 16", "column": 3, "line": 12, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "foo()", "sourceCodeLine": "return x;" }, "to": { - "IR": "%0 = landingpad { i8*, i32 }\n catch i8* null | ID: 28", + "IR": "%0 = landingpad { ptr, i32 }\n catch ptr null | ID: 27", "column": 1, "line": 23, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "}" } }, { "from": { - "IR": "store i32 %call, i32* %a, align 4 | ID: 26", + "IR": "store i32 %call, ptr %a, align 4 | ID: 25", "column": 7, "line": 18, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "a = foo();" }, "to": { - "IR": "br label %try.cont | ID: 27", + "IR": "br label %try.cont | ID: 26", "column": 3, "line": 19, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "} catch (...) {" } }, { "from": { - "IR": "br label %try.cont | ID: 27", + "IR": "br label %try.cont | ID: 26", "column": 3, "line": 19, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "} catch (...) {" }, "to": { - "IR": "%4 = load i32, i32* %a, align 4 | ID: 39", + "IR": "%4 = load i32, ptr %a, align 4 | ID: 38", "column": 10, "line": 22, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "return a;" } }, { "from": { - "IR": "%0 = landingpad { i8*, i32 }\n catch i8* null | ID: 28", + "IR": "%0 = landingpad { ptr, i32 }\n catch ptr null | ID: 27", "column": 1, "line": 23, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "}" }, "to": { - "IR": "%1 = extractvalue { i8*, i32 } %0, 0 | ID: 29", + "IR": "%1 = extractvalue { ptr, i32 } %0, 0 | ID: 28", "column": 1, "line": 23, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "}" } }, { "from": { - "IR": "%1 = extractvalue { i8*, i32 } %0, 0 | ID: 29", + "IR": "%1 = extractvalue { ptr, i32 } %0, 0 | ID: 28", "column": 1, "line": 23, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "}" }, "to": { - "IR": "store i8* %1, i8** %exn.slot, align 8 | ID: 30", + "IR": "store ptr %1, ptr %exn.slot, align 8 | ID: 29", "column": 1, "line": 23, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "}" } }, { "from": { - "IR": "store i8* %1, i8** %exn.slot, align 8 | ID: 30", + "IR": "store ptr %1, ptr %exn.slot, align 8 | ID: 29", "column": 1, "line": 23, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "}" }, "to": { - "IR": "%2 = extractvalue { i8*, i32 } %0, 1 | ID: 31", + "IR": "%2 = extractvalue { ptr, i32 } %0, 1 | ID: 30", "column": 1, "line": 23, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "}" } }, { "from": { - "IR": "%2 = extractvalue { i8*, i32 } %0, 1 | ID: 31", + "IR": "%2 = extractvalue { ptr, i32 } %0, 1 | ID: 30", "column": 1, "line": 23, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "}" }, "to": { - "IR": "store i32 %2, i32* %ehselector.slot, align 4 | ID: 32", + "IR": "store i32 %2, ptr %ehselector.slot, align 4 | ID: 31", "column": 1, "line": 23, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "}" } }, { "from": { - "IR": "store i32 %2, i32* %ehselector.slot, align 4 | ID: 32", + "IR": "store i32 %2, ptr %ehselector.slot, align 4 | ID: 31", "column": 1, "line": 23, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "}" }, "to": { - "IR": "br label %catch | ID: 33", + "IR": "br label %catch | ID: 32", "column": 1, "line": 23, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "}" } }, { "from": { - "IR": "br label %catch | ID: 33", + "IR": "br label %catch | ID: 32", "column": 1, "line": 23, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "}" }, "to": { - "IR": "%exn = load i8*, i8** %exn.slot, align 8 | ID: 34", + "IR": "%exn = load ptr, ptr %exn.slot, align 8 | ID: 33", "column": 3, "line": 19, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "} catch (...) {" } }, { "from": { - "IR": "%exn = load i8*, i8** %exn.slot, align 8 | ID: 34", + "IR": "%exn = load ptr, ptr %exn.slot, align 8 | ID: 33", "column": 3, "line": 19, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "} catch (...) {" }, "to": { - "IR": "%3 = call i8* @__cxa_begin_catch(i8* %exn) | ID: 35", + "IR": "%3 = call ptr @__cxa_begin_catch(ptr %exn) | ID: 34", "column": 3, "line": 19, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "} catch (...) {" } }, { "from": { - "IR": "%3 = call i8* @__cxa_begin_catch(i8* %exn) | ID: 35", + "IR": "%3 = call ptr @__cxa_begin_catch(ptr %exn) | ID: 34", "column": 3, "line": 19, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "} catch (...) {" }, "to": { - "IR": "store i32 -1, i32* %a, align 4 | ID: 36", + "IR": "store i32 -1, ptr %a, align 4 | ID: 35", "column": 7, "line": 20, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "a = -1;" } }, { "from": { - "IR": "store i32 -1, i32* %a, align 4 | ID: 36", + "IR": "store i32 -1, ptr %a, align 4 | ID: 35", "column": 7, "line": 20, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "a = -1;" }, "to": { - "IR": "call void @__cxa_end_catch() | ID: 37", + "IR": "call void @__cxa_end_catch() | ID: 36", "column": 3, "line": 21, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "}" } }, { "from": { - "IR": "call void @__cxa_end_catch() | ID: 37", + "IR": "call void @__cxa_end_catch() | ID: 36", "column": 3, "line": 21, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "}" }, "to": { - "IR": "br label %try.cont | ID: 38", + "IR": "br label %try.cont | ID: 37", "column": 3, "line": 21, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "}" } }, { "from": { - "IR": "br label %try.cont | ID: 38", + "IR": "br label %try.cont | ID: 37", "column": 3, "line": 21, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "}" }, "to": { - "IR": "%4 = load i32, i32* %a, align 4 | ID: 39", + "IR": "%4 = load i32, ptr %a, align 4 | ID: 38", "column": 10, "line": 22, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "return a;" } }, { "from": { - "IR": "%4 = load i32, i32* %a, align 4 | ID: 39", + "IR": "%4 = load i32, ptr %a, align 4 | ID: 38", "column": 10, "line": 22, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "return a;" }, "to": { - "IR": "ret i32 %4 | ID: 40", + "IR": "ret i32 %4 | ID: 39", "column": 3, "line": 22, - "sourceCodeFileName": "/home/ubuntu/phasar/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", "sourceCodeFunctionName": "main", "sourceCodeLine": "return a;" } + }, + { + "from": { + "IR": "%x = alloca i32, align 4 | ID: 1", + "column": 7, + "line": 5, + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFunctionName": "foo()", + "sourceCodeLine": "int x = 42;" + }, + "to": { + "IR": "store i32 42, ptr %x, align 4 | ID: 3", + "column": 7, + "line": 5, + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFunctionName": "foo()", + "sourceCodeLine": "int x = 42;" + } + }, + { + "from": { + "IR": "store i32 42, ptr %x, align 4 | ID: 3", + "column": 7, + "line": 5, + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFunctionName": "foo()", + "sourceCodeLine": "int x = 42;" + }, + "to": { + "IR": "%call = call i32 @rand() | ID: 4", + "column": 7, + "line": 6, + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFunctionName": "foo()", + "sourceCodeLine": "if (rand()) {" + } + }, + { + "from": { + "IR": "%call = call i32 @rand() | ID: 4", + "column": 7, + "line": 6, + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFunctionName": "foo()", + "sourceCodeLine": "if (rand()) {" + }, + "to": { + "IR": "%tobool = icmp ne i32 %call, 0 | ID: 5", + "column": 7, + "line": 6, + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFunctionName": "foo()", + "sourceCodeLine": "if (rand()) {" + } + }, + { + "from": { + "IR": "%tobool = icmp ne i32 %call, 0 | ID: 5", + "column": 7, + "line": 6, + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFunctionName": "foo()", + "sourceCodeLine": "if (rand()) {" + }, + "to": { + "IR": "br i1 %tobool, label %if.then, label %if.else | ID: 6", + "column": 7, + "line": 6, + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFunctionName": "foo()", + "sourceCodeLine": "if (rand()) {" + } + }, + { + "from": { + "IR": "br i1 %tobool, label %if.then, label %if.else | ID: 6", + "column": 7, + "line": 6, + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFunctionName": "foo()", + "sourceCodeLine": "if (rand()) {" + }, + "to": { + "IR": "%0 = load i32, ptr %x, align 4 | ID: 7", + "column": 7, + "line": 7, + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFunctionName": "foo()", + "sourceCodeLine": "x += 4;" + } + }, + { + "from": { + "IR": "br i1 %tobool, label %if.then, label %if.else | ID: 6", + "column": 7, + "line": 6, + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFunctionName": "foo()", + "sourceCodeLine": "if (rand()) {" + }, + "to": { + "IR": "%exception = call ptr @__cxa_allocate_exception(i64 4) | ID: 11", + "column": 5, + "line": 9, + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFunctionName": "foo()", + "sourceCodeLine": "throw 2353782;" + } + }, + { + "from": { + "IR": "%0 = load i32, ptr %x, align 4 | ID: 7", + "column": 7, + "line": 7, + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFunctionName": "foo()", + "sourceCodeLine": "x += 4;" + }, + "to": { + "IR": "%add = add nsw i32 %0, 4 | ID: 8", + "column": 7, + "line": 7, + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFunctionName": "foo()", + "sourceCodeLine": "x += 4;" + } + }, + { + "from": { + "IR": "%add = add nsw i32 %0, 4 | ID: 8", + "column": 7, + "line": 7, + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFunctionName": "foo()", + "sourceCodeLine": "x += 4;" + }, + "to": { + "IR": "store i32 %add, ptr %x, align 4 | ID: 9", + "column": 7, + "line": 7, + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFunctionName": "foo()", + "sourceCodeLine": "x += 4;" + } + }, + { + "from": { + "IR": "store i32 %add, ptr %x, align 4 | ID: 9", + "column": 7, + "line": 7, + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFunctionName": "foo()", + "sourceCodeLine": "x += 4;" + }, + "to": { + "IR": "br label %if.end | ID: 10", + "column": 3, + "line": 8, + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFunctionName": "foo()", + "sourceCodeLine": "} else {" + } + }, + { + "from": { + "IR": "br label %if.end | ID: 10", + "column": 3, + "line": 8, + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFunctionName": "foo()", + "sourceCodeLine": "} else {" + }, + "to": { + "IR": "%1 = load i32, ptr %x, align 4 | ID: 15", + "column": 10, + "line": 12, + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFunctionName": "foo()", + "sourceCodeLine": "return x;" + } + }, + { + "from": { + "IR": "%exception = call ptr @__cxa_allocate_exception(i64 4) | ID: 11", + "column": 5, + "line": 9, + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFunctionName": "foo()", + "sourceCodeLine": "throw 2353782;" + }, + "to": { + "IR": "store i32 2353782, ptr %exception, align 16 | ID: 12", + "column": 5, + "line": 9, + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFunctionName": "foo()", + "sourceCodeLine": "throw 2353782;" + } + }, + { + "from": { + "IR": "store i32 2353782, ptr %exception, align 16 | ID: 12", + "column": 5, + "line": 9, + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFunctionName": "foo()", + "sourceCodeLine": "throw 2353782;" + }, + "to": { + "IR": "call void @__cxa_throw(ptr %exception, ptr @_ZTIi, ptr null) | ID: 13", + "column": 5, + "line": 9, + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFunctionName": "foo()", + "sourceCodeLine": "throw 2353782;" + } + }, + { + "from": { + "IR": "call void @__cxa_throw(ptr %exception, ptr @_ZTIi, ptr null) | ID: 13", + "column": 5, + "line": 9, + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFunctionName": "foo()", + "sourceCodeLine": "throw 2353782;" + }, + "to": { + "IR": "unreachable | ID: 14", + "column": 5, + "line": 9, + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFunctionName": "foo()", + "sourceCodeLine": "throw 2353782;" + } + }, + { + "from": { + "IR": "%1 = load i32, ptr %x, align 4 | ID: 15", + "column": 10, + "line": 12, + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFunctionName": "foo()", + "sourceCodeLine": "return x;" + }, + "to": { + "IR": "ret i32 %1 | ID: 16", + "column": 3, + "line": 12, + "sourceCodeFileName": "/home/max/Desktop/dev/Arbeit/phasar-clones/phasar-f-clang-15/test/llvm_test_code/exceptions/exceptions_01.cpp", + "sourceCodeFunctionName": "foo()", + "sourceCodeLine": "return x;" + } } ] \ No newline at end of file diff --git a/unittests/PhasarLLVM/ControlFlow/LLVMBasedCFGTest.cpp b/unittests/PhasarLLVM/ControlFlow/LLVMBasedCFGTest.cpp index 26c8f30d2..3753a403a 100644 --- a/unittests/PhasarLLVM/ControlFlow/LLVMBasedCFGTest.cpp +++ b/unittests/PhasarLLVM/ControlFlow/LLVMBasedCFGTest.cpp @@ -195,7 +195,7 @@ TEST(LLVMBasedCFGTest, HandleFieldLoadsArray) { const auto *F = IRDB.getFunctionDefinition("main"); const auto *Inst = getNthInstruction(F, 1); ASSERT_FALSE(Cfg.isFieldLoad(Inst)); - Inst = getNthInstruction(F, 6); + Inst = getNthInstruction(F, 5); ASSERT_TRUE(Cfg.isFieldLoad(Inst)); } @@ -205,7 +205,7 @@ TEST(LLVMBasedCFGTest, HandleFieldStoreArray) { const auto *F = IRDB.getFunctionDefinition("main"); const auto *Inst = getNthInstruction(F, 1); ASSERT_FALSE(Cfg.isFieldStore(Inst)); - Inst = getNthInstruction(F, 9); + Inst = getNthInstruction(F, 8); ASSERT_TRUE(Cfg.isFieldStore(Inst)); } diff --git a/unittests/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEInstInteractionAnalysisTest.cpp b/unittests/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEInstInteractionAnalysisTest.cpp index c05d4745d..02b9865a7 100644 --- a/unittests/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEInstInteractionAnalysisTest.cpp +++ b/unittests/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEInstInteractionAnalysisTest.cpp @@ -143,11 +143,11 @@ TEST_F(IDEInstInteractionAnalysisTest, FieldSensArrayConstruction_01) { llvm::outs() << "Instruction to create flow fact from: " << *Inst << '\n'; auto FlowFact = IDEIIAFlowFact::create(Inst); llvm::outs() << FlowFact << '\n'; - Inst = getNthInstruction(Main, 14); + Inst = getNthInstruction(Main, 13); llvm::outs() << "Instruction to create flow fact from: " << *Inst << '\n'; FlowFact = IDEIIAFlowFact::create(Inst); llvm::outs() << FlowFact << '\n'; - Inst = getNthInstruction(Main, 17); + Inst = getNthInstruction(Main, 16); llvm::outs() << "Instruction to create flow fact from: " << *Inst << '\n'; FlowFact = IDEIIAFlowFact::create(Inst); llvm::outs() << FlowFact << '\n'; @@ -248,20 +248,20 @@ TEST_F(IDEInstInteractionAnalysisTest, ArrayEquality_01) { Inst = getNthInstruction(Main, 4); FlowFact = IDEIIAFlowFact::create(Inst); - Inst = getNthInstruction(Main, 14); + Inst = getNthInstruction(Main, 13); auto OtherFlowFact = IDEIIAFlowFact::create(Inst); ASSERT_NE(FlowFact, OtherFlowFact); - Inst = getNthInstruction(Main, 14); + Inst = getNthInstruction(Main, 13); FlowFact = IDEIIAFlowFact::create(Inst); - Inst = getNthInstruction(Main, 19); + Inst = getNthInstruction(Main, 18); OtherFlowFact = IDEIIAFlowFact::create(Inst); ASSERT_EQ(FlowFact, OtherFlowFact); - Inst = getNthInstruction(Main, 17); + Inst = getNthInstruction(Main, 16); FlowFact = IDEIIAFlowFact::create(Inst); - Inst = getNthInstruction(Main, 22); + Inst = getNthInstruction(Main, 21); OtherFlowFact = IDEIIAFlowFact::create(Inst); ASSERT_EQ(FlowFact, OtherFlowFact); } @@ -852,10 +852,10 @@ TEST_F(IDEInstInteractionAnalysisTest, HandleHeapTest_01) { "main", 17, "retval", {"3"})); GroundTruth.emplace( std::tuple>( - "main", 17, "i", {"6", "7"})); + "main", 17, "i", {"5", "6"})); GroundTruth.emplace( std::tuple>( - "main", 17, "j", {"6", "7", "8", "9", "10"})); + "main", 17, "j", {"5", "6", "7", "8", "9"})); doAnalysisAndCompareResults("heap_01_cpp.ll", {"main"}, GroundTruth, false); } diff --git a/unittests/PhasarLLVM/DataFlow/IfdsIde/Problems/IFDSConstAnalysisTest.cpp b/unittests/PhasarLLVM/DataFlow/IfdsIde/Problems/IFDSConstAnalysisTest.cpp index 77f858c30..25cf40461 100644 --- a/unittests/PhasarLLVM/DataFlow/IfdsIde/Problems/IFDSConstAnalysisTest.cpp +++ b/unittests/PhasarLLVM/DataFlow/IfdsIde/Problems/IFDSConstAnalysisTest.cpp @@ -175,7 +175,7 @@ TEST_F(IFDSConstAnalysisTest, HandlePointerTest_04) { initialize({PathToLlFiles + "pointer/pointer_04_cpp_m2r_dbg.ll"}); IFDSSolver Llvmconstsolver(*Constproblem, &HA->getICFG()); Llvmconstsolver.solve(); - compareResults({4}, Llvmconstsolver); + compareResults({3}, Llvmconstsolver); } /* ============== GLOBAL TESTS ============== */ @@ -352,7 +352,7 @@ TEST_F(IFDSConstAnalysisTest, HandleArrayTest_08) { initialize({PathToLlFiles + "array/array_08_cpp_m2r_dbg.ll"}); IFDSSolver Llvmconstsolver(*Constproblem, &HA->getICFG()); Llvmconstsolver.solve(); - compareResults({}, Llvmconstsolver); + compareResults({0}, Llvmconstsolver); } TEST_F(IFDSConstAnalysisTest, HandleArrayTest_09) { diff --git a/unittests/PhasarLLVM/DataFlow/IfdsIde/Problems/IFDSTaintAnalysisTest.cpp b/unittests/PhasarLLVM/DataFlow/IfdsIde/Problems/IFDSTaintAnalysisTest.cpp index 0812fafcf..69ea7f0d2 100644 --- a/unittests/PhasarLLVM/DataFlow/IfdsIde/Problems/IFDSTaintAnalysisTest.cpp +++ b/unittests/PhasarLLVM/DataFlow/IfdsIde/Problems/IFDSTaintAnalysisTest.cpp @@ -193,7 +193,7 @@ TEST_F(IFDSTaintAnalysisTest, TaintTest_ExceptionHandling_01) { IFDSSolver TaintSolver(*TaintProblem, &HA->getICFG()); TaintSolver.solve(); map> GroundTruth; - GroundTruth[15] = set{"14"}; + GroundTruth[14] = set{"13"}; compareResults(GroundTruth); } @@ -203,7 +203,7 @@ TEST_F(IFDSTaintAnalysisTest, TaintTest_ExceptionHandling_01_m2r) { IFDSSolver TaintSolver(*TaintProblem, &HA->getICFG()); TaintSolver.solve(); map> GroundTruth; - GroundTruth[6] = set{"0"}; + GroundTruth[5] = set{"0"}; compareResults(GroundTruth); } @@ -213,7 +213,7 @@ TEST_F(IFDSTaintAnalysisTest, TaintTest_ExceptionHandling_02) { IFDSSolver TaintSolver(*TaintProblem, &HA->getICFG()); TaintSolver.solve(); map> GroundTruth; - GroundTruth[17] = set{"16"}; + GroundTruth[16] = set{"15"}; compareResults(GroundTruth); } @@ -224,7 +224,7 @@ TEST_F(IFDSTaintAnalysisTest, TaintTest_ExceptionHandling_03) { TaintSolver.solve(); map> GroundTruth; GroundTruth[11] = set{"10"}; - GroundTruth[21] = set{"20"}; + GroundTruth[20] = set{"19"}; compareResults(GroundTruth); } @@ -234,7 +234,7 @@ TEST_F(IFDSTaintAnalysisTest, TaintTest_ExceptionHandling_04) { IFDSSolver TaintSolver(*TaintProblem, &HA->getICFG()); TaintSolver.solve(); map> GroundTruth; - GroundTruth[33] = set{"32"}; + GroundTruth[32] = set{"31"}; compareResults(GroundTruth); } @@ -245,7 +245,7 @@ TEST_F(IFDSTaintAnalysisTest, TaintTest_ExceptionHandling_05) { TaintSolver.solve(); map> GroundTruth; - GroundTruth[33] = set{"32"}; + GroundTruth[32] = set{"31"}; compareResults(GroundTruth); } @@ -255,7 +255,7 @@ TEST_F(IFDSTaintAnalysisTest, TaintTest_ExceptionHandling_06) { IFDSSolver TaintSolver(*TaintProblem, &HA->getICFG()); TaintSolver.solve(); map> GroundTruth; - GroundTruth[15] = set{"14"}; + GroundTruth[14] = set{"13"}; compareResults(GroundTruth); } @@ -265,7 +265,7 @@ TEST_F(IFDSTaintAnalysisTest, TaintTest_ExceptionHandling_07) { IFDSSolver TaintSolver(*TaintProblem, &HA->getICFG()); TaintSolver.solve(); map> GroundTruth; - GroundTruth[31] = set{"30"}; + GroundTruth[30] = set{"29"}; compareResults(GroundTruth); } @@ -275,7 +275,7 @@ TEST_F(IFDSTaintAnalysisTest, TaintTest_ExceptionHandling_08) { IFDSSolver TaintSolver(*TaintProblem, &HA->getICFG()); TaintSolver.solve(); map> GroundTruth; - GroundTruth[33] = set{"32"}; + GroundTruth[32] = set{"31"}; compareResults(GroundTruth); } @@ -285,7 +285,7 @@ TEST_F(IFDSTaintAnalysisTest, TaintTest_ExceptionHandling_09) { IFDSSolver TaintSolver(*TaintProblem, &HA->getICFG()); TaintSolver.solve(); map> GroundTruth; - GroundTruth[64] = set{"63"}; + GroundTruth[62] = set{"61"}; compareResults(GroundTruth); } @@ -295,7 +295,7 @@ TEST_F(IFDSTaintAnalysisTest, TaintTest_ExceptionHandling_10) { IFDSSolver TaintSolver(*TaintProblem, &HA->getICFG()); TaintSolver.solve(); map> GroundTruth; - GroundTruth[62] = set{"61"}; + GroundTruth[60] = set{"59"}; compareResults(GroundTruth); } diff --git a/unittests/PhasarLLVM/Pointer/LLVMAliasSetSerializationTest.cpp b/unittests/PhasarLLVM/Pointer/LLVMAliasSetSerializationTest.cpp index 533212beb..f0ee361b0 100644 --- a/unittests/PhasarLLVM/Pointer/LLVMAliasSetSerializationTest.cpp +++ b/unittests/PhasarLLVM/Pointer/LLVMAliasSetSerializationTest.cpp @@ -103,11 +103,11 @@ TEST(LLVMAliasSetSerializationTest, Ser_Inter01) { TEST(LLVMAliasSetSerializationTest, Ser_Global01) { analyze("pointers/global_01_cpp.ll", - {{{"0", "15", "17", "2", "9", "_Z3fooPi.0"}, + {{{"0", "14", "16", "2", "8", "_Z3fooPi.0"}, {"1"}, + {"11"}, {"12"}, - {"13"}, - {"7"}}, + {"6"}}, {"_GLOBAL__sub_I_global_01.cpp", "_Z3fooPi", "__cxx_global_var_init", "main"}}); } diff --git a/unittests/PhasarLLVM/TaintConfig/TaintConfigTest.cpp b/unittests/PhasarLLVM/TaintConfig/TaintConfigTest.cpp index 3c6a3199f..c7af226d5 100644 --- a/unittests/PhasarLLVM/TaintConfig/TaintConfigTest.cpp +++ b/unittests/PhasarLLVM/TaintConfig/TaintConfigTest.cpp @@ -367,10 +367,10 @@ TEST_F(TaintConfigTest, FunMember_02_Json) { psr::LLVMTaintConfig TConfig(IR, JsonConfig); llvm::outs() << TConfig << '\n'; - const llvm::Value *I1 = IR.getInstruction(18); - const llvm::Value *I2 = IR.getInstruction(54); - const llvm::Value *I3 = IR.getInstruction(63); - const llvm::Value *I4 = IR.getInstruction(71); + const llvm::Value *I1 = IR.getInstruction(16); + const llvm::Value *I2 = IR.getInstruction(52); + const llvm::Value *I3 = IR.getInstruction(61); + const llvm::Value *I4 = IR.getInstruction(69); ASSERT_TRUE(TConfig.isSource(I1)); ASSERT_TRUE(TConfig.isSource(I2)); ASSERT_TRUE(TConfig.isSource(I3)); From 6ced6145bc4ce5949b36251832f99a09a4db87dd Mon Sep 17 00:00:00 2001 From: mxHuber Date: Wed, 12 Jun 2024 10:48:11 +0200 Subject: [PATCH 22/78] pre-commit hook --- test/json_test_code/exceptions/exceptions_01_cpp_icfg.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/json_test_code/exceptions/exceptions_01_cpp_icfg.json b/test/json_test_code/exceptions/exceptions_01_cpp_icfg.json index 1b0c2accc..e1e54fda4 100644 --- a/test/json_test_code/exceptions/exceptions_01_cpp_icfg.json +++ b/test/json_test_code/exceptions/exceptions_01_cpp_icfg.json @@ -683,4 +683,4 @@ "sourceCodeLine": "return x;" } } -] \ No newline at end of file +] From 12a9d06a9a9cf18e2af2934cef87a959b0a8db84 Mon Sep 17 00:00:00 2001 From: mxHuber Date: Wed, 12 Jun 2024 12:02:57 +0200 Subject: [PATCH 23/78] Two Tests + xtaint09 test fix for pipeline --- unittests/PhasarLLVM/ControlFlow/LLVMBasedICFG_OTFTest.cpp | 5 +---- .../IfdsIde/Problems/IDEExtendedTaintAnalysisTest.cpp | 2 +- .../DataFlow/IfdsIde/Problems/IFDSConstAnalysisTest.cpp | 2 +- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFG_OTFTest.cpp b/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFG_OTFTest.cpp index 954b7fcef..d745c5937 100644 --- a/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFG_OTFTest.cpp +++ b/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFG_OTFTest.cpp @@ -32,10 +32,7 @@ TEST(LLVMBasedICFG_OTFTest, VirtualCallSite_7) { ASSERT_TRUE(VFuncA); ASSERT_TRUE(VFuncB); - const auto *CallToAFunc = getNthInstruction(F, 19); - // TODO: find out why call void %5(%struct.A* noundef nonnull align 8 - // dereferenceable(8) %3), !psr.id !32 is gone and which function to call - // instead + const auto *CallToAFunc = getNthInstruction(F, 27); llvm::outs() << "CallToAFunc: " << *CallToAFunc << '\n'; ASSERT_TRUE(ICFG.isVirtualFunctionCall(CallToAFunc)); const auto &AsCallees = ICFG.getCalleesOfCallAt(CallToAFunc); diff --git a/unittests/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEExtendedTaintAnalysisTest.cpp b/unittests/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEExtendedTaintAnalysisTest.cpp index b6b9cb075..5c3395b6d 100644 --- a/unittests/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEExtendedTaintAnalysisTest.cpp +++ b/unittests/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEExtendedTaintAnalysisTest.cpp @@ -208,7 +208,7 @@ TEST_F(IDETaintAnalysisTest, XTaint09_1) { TEST_F(IDETaintAnalysisTest, XTaint09) { map> Gt; - Gt[34] = {"33"}; + Gt[33] = {"32"}; doAnalysis({PathToLLFiles + "xtaint09_cpp.ll"}, Gt, std::monostate{}); } diff --git a/unittests/PhasarLLVM/DataFlow/IfdsIde/Problems/IFDSConstAnalysisTest.cpp b/unittests/PhasarLLVM/DataFlow/IfdsIde/Problems/IFDSConstAnalysisTest.cpp index 25cf40461..b36430c3c 100644 --- a/unittests/PhasarLLVM/DataFlow/IfdsIde/Problems/IFDSConstAnalysisTest.cpp +++ b/unittests/PhasarLLVM/DataFlow/IfdsIde/Problems/IFDSConstAnalysisTest.cpp @@ -352,7 +352,7 @@ TEST_F(IFDSConstAnalysisTest, HandleArrayTest_08) { initialize({PathToLlFiles + "array/array_08_cpp_m2r_dbg.ll"}); IFDSSolver Llvmconstsolver(*Constproblem, &HA->getICFG()); Llvmconstsolver.solve(); - compareResults({0}, Llvmconstsolver); + compareResults({}, Llvmconstsolver); } TEST_F(IFDSConstAnalysisTest, HandleArrayTest_09) { From 9f5902a7ec0e3403e1600c3e1c1a5ac26ad2e302 Mon Sep 17 00:00:00 2001 From: mxHuber Date: Thu, 13 Jun 2024 12:57:16 +0200 Subject: [PATCH 24/78] Basic Opaque Pointer Impl, bugged --- .../ControlFlow/Resolver/Resolver.h | 8 ++++-- include/phasar/Utils/OpaquePtrTypeMap.h | 16 ++++++++++++ lib/PhasarLLVM/ControlFlow/LLVMBasedICFG.cpp | 9 ++++--- .../ControlFlow/Resolver/CHAResolver.cpp | 2 +- .../ControlFlow/Resolver/DTAResolver.cpp | 2 +- .../ControlFlow/Resolver/RTAResolver.cpp | 2 +- .../ControlFlow/Resolver/Resolver.cpp | 25 +++++++++++++------ lib/Utils/OpaquePtrTypeMap.cpp | 25 +++++++++++++++++++ .../ControlFlow/LLVMBasedICFG_OTFTest.cpp | 3 +-- 9 files changed, 74 insertions(+), 18 deletions(-) create mode 100644 include/phasar/Utils/OpaquePtrTypeMap.h create mode 100644 lib/Utils/OpaquePtrTypeMap.cpp diff --git a/include/phasar/PhasarLLVM/ControlFlow/Resolver/Resolver.h b/include/phasar/PhasarLLVM/ControlFlow/Resolver/Resolver.h index e8f997f17..b143270f0 100644 --- a/include/phasar/PhasarLLVM/ControlFlow/Resolver/Resolver.h +++ b/include/phasar/PhasarLLVM/ControlFlow/Resolver/Resolver.h @@ -18,6 +18,7 @@ #define PHASAR_PHASARLLVM_CONTROLFLOW_RESOLVER_RESOLVER_H_ #include "phasar/PhasarLLVM/Pointer/LLVMAliasInfo.h" +#include "phasar/Utils/OpaquePtrTypeMap.h" #include "llvm/ADT/DenseSet.h" @@ -42,9 +43,10 @@ enum class CallGraphAnalysisType; getVFTIndex(const llvm::CallBase *CallSite); [[nodiscard]] const llvm::StructType * -getReceiverType(const llvm::CallBase *CallSite); +getReceiverType(const llvm::CallBase *CallSite, const LLVMProjectIRDB *IRDB); -[[nodiscard]] std::string getReceiverTypeName(const llvm::CallBase *CallSite); +[[nodiscard]] std::string getReceiverTypeName(const llvm::CallBase *CallSite, + const LLVMProjectIRDB *IRDB); [[nodiscard]] bool isConsistentCall(const llvm::CallBase *CallSite, const llvm::Function *DestFun); @@ -63,6 +65,8 @@ class Resolver { public: using FunctionSetTy = llvm::SmallDenseSet; + OpaquePtrTypeInfoMap OpaquePtrTypeInfo; + Resolver(const LLVMProjectIRDB *IRDB, const LLVMVFTableProvider *VTP); virtual ~Resolver() = default; diff --git a/include/phasar/Utils/OpaquePtrTypeMap.h b/include/phasar/Utils/OpaquePtrTypeMap.h new file mode 100644 index 000000000..0779c7299 --- /dev/null +++ b/include/phasar/Utils/OpaquePtrTypeMap.h @@ -0,0 +1,16 @@ +#include "phasar/PhasarLLVM/DB/LLVMProjectIRDB.h" + +#include "llvm/IR/Type.h" + +#include + +namespace psr { + +class OpaquePtrTypeInfoMap { +public: + // maps ValueID of pointer to ValueID of variable + std::map TypeInfo; + OpaquePtrTypeInfoMap(const psr::LLVMProjectIRDB *Code); +}; + +} // namespace psr diff --git a/lib/PhasarLLVM/ControlFlow/LLVMBasedICFG.cpp b/lib/PhasarLLVM/ControlFlow/LLVMBasedICFG.cpp index f8e56c182..7c4a5abcf 100644 --- a/lib/PhasarLLVM/ControlFlow/LLVMBasedICFG.cpp +++ b/lib/PhasarLLVM/ControlFlow/LLVMBasedICFG.cpp @@ -234,14 +234,15 @@ bool LLVMBasedICFG::Builder::processFunction(const llvm::Function *F) { } static bool internalIsVirtualFunctionCall(const llvm::Instruction *Inst, - const LLVMVFTableProvider &VTP) { + const LLVMVFTableProvider &VTP, + const LLVMProjectIRDB *IRDB) { assert(Inst != nullptr); const auto *CallSite = llvm::dyn_cast(Inst); if (!CallSite) { return false; } // check potential receiver type - const auto *RecType = getReceiverType(CallSite); + const auto *RecType = getReceiverType(CallSite, IRDB); if (!RecType) { return false; } @@ -273,7 +274,7 @@ bool LLVMBasedICFG::Builder::constructDynamicCall(const llvm::Instruction *CS) { // call the resolve routine assert(VTP != nullptr); - auto PossibleTargets = internalIsVirtualFunctionCall(CallSite, *VTP) + auto PossibleTargets = internalIsVirtualFunctionCall(CallSite, *VTP, IRDB) ? Res->resolveVirtualCall(CallSite) : Res->resolveFunctionPointer(CallSite); @@ -412,7 +413,7 @@ bool LLVMBasedICFG::isPhasarGenerated(const llvm::Function &F) noexcept { } [[nodiscard]] bool LLVMBasedICFG::isVirtualFunctionCallImpl(n_t Inst) const { - return internalIsVirtualFunctionCall(Inst, VTP); + return internalIsVirtualFunctionCall(Inst, VTP, IRDB); } [[nodiscard]] auto LLVMBasedICFG::allNonCallStartNodesImpl() const diff --git a/lib/PhasarLLVM/ControlFlow/Resolver/CHAResolver.cpp b/lib/PhasarLLVM/ControlFlow/Resolver/CHAResolver.cpp index 6b2c144a5..9ee78fe92 100644 --- a/lib/PhasarLLVM/ControlFlow/Resolver/CHAResolver.cpp +++ b/lib/PhasarLLVM/ControlFlow/Resolver/CHAResolver.cpp @@ -63,7 +63,7 @@ auto CHAResolver::resolveVirtualCall(const llvm::CallBase *CallSite) PHASAR_LOG_LEVEL(DEBUG, "Virtual function table entry is: " << VtableIndex); - const auto *ReceiverTy = getReceiverType(CallSite); + const auto *ReceiverTy = getReceiverType(CallSite, IRDB); // also insert all possible subtypes vtable entries auto FallbackTys = TH->getSubTypes(ReceiverTy); diff --git a/lib/PhasarLLVM/ControlFlow/Resolver/DTAResolver.cpp b/lib/PhasarLLVM/ControlFlow/Resolver/DTAResolver.cpp index eed109422..5f44717b1 100644 --- a/lib/PhasarLLVM/ControlFlow/Resolver/DTAResolver.cpp +++ b/lib/PhasarLLVM/ControlFlow/Resolver/DTAResolver.cpp @@ -185,7 +185,7 @@ auto DTAResolver::resolveVirtualCall(const llvm::CallBase *CallSite) PHASAR_LOG_LEVEL(DEBUG, "Virtual function table entry is: " << VtableIndex); - const auto *ReceiverType = getReceiverType(CallSite); + const auto *ReceiverType = getReceiverType(CallSite, IRDB); auto PossibleTypes = TypeGraph.getTypes(ReceiverType); diff --git a/lib/PhasarLLVM/ControlFlow/Resolver/RTAResolver.cpp b/lib/PhasarLLVM/ControlFlow/Resolver/RTAResolver.cpp index 27ec5c5a1..79c2bfcf2 100644 --- a/lib/PhasarLLVM/ControlFlow/Resolver/RTAResolver.cpp +++ b/lib/PhasarLLVM/ControlFlow/Resolver/RTAResolver.cpp @@ -64,7 +64,7 @@ auto RTAResolver::resolveVirtualCall(const llvm::CallBase *CallSite) PHASAR_LOG_LEVEL(DEBUG, "Virtual function table entry is: " << VtableIndex); - const auto *ReceiverType = getReceiverType(CallSite); + const auto *ReceiverType = getReceiverType(CallSite, IRDB); // also insert all possible subtypes vtable entries auto ReachableTypes = TH->getSubTypes(ReceiverType); diff --git a/lib/PhasarLLVM/ControlFlow/Resolver/Resolver.cpp b/lib/PhasarLLVM/ControlFlow/Resolver/Resolver.cpp index 745a4e866..70cb731b5 100644 --- a/lib/PhasarLLVM/ControlFlow/Resolver/Resolver.cpp +++ b/lib/PhasarLLVM/ControlFlow/Resolver/Resolver.cpp @@ -57,7 +57,8 @@ std::optional psr::getVFTIndex(const llvm::CallBase *CallSite) { return std::nullopt; } -const llvm::StructType *psr::getReceiverType(const llvm::CallBase *CallSite) { +const llvm::StructType *psr::getReceiverType(const llvm::CallBase *CallSite, + const LLVMProjectIRDB *IRDB) { if (CallSite->arg_empty() || (CallSite->hasStructRetAttr() && CallSite->arg_size() < 2)) { return nullptr; @@ -71,8 +72,16 @@ const llvm::StructType *psr::getReceiverType(const llvm::CallBase *CallSite) { } if (Receiver->getType()->isOpaquePointerTy()) { - llvm::errs() << "WARNING: The IR under analysis uses opaque pointers, " - "which are not supported by phasar yet!\n"; + + OpaquePtrTypeInfoMap OpaquePtrTypeInfo(IRDB); + + if (const auto *ReceiverTy = llvm::dyn_cast( + IRDB->getValueFromId( + OpaquePtrTypeInfo.TypeInfo[Receiver->getValueID()]) + ->getType())) { + return ReceiverTy; + } + return nullptr; } @@ -86,8 +95,9 @@ const llvm::StructType *psr::getReceiverType(const llvm::CallBase *CallSite) { return nullptr; } -std::string psr::getReceiverTypeName(const llvm::CallBase *CallSite) { - const auto *RT = getReceiverType(CallSite); +std::string psr::getReceiverTypeName(const llvm::CallBase *CallSite, + const LLVMProjectIRDB *IRDB) { + const auto *RT = getReceiverType(CallSite, IRDB); if (RT) { return RT->getName().str(); } @@ -110,12 +120,13 @@ bool psr::isConsistentCall(const llvm::CallBase *CallSite, namespace psr { -Resolver::Resolver(const LLVMProjectIRDB *IRDB) : IRDB(IRDB), VTP(nullptr) { +Resolver::Resolver(const LLVMProjectIRDB *IRDB) + : IRDB(IRDB), VTP(nullptr), OpaquePtrTypeInfo(IRDB) { assert(IRDB != nullptr); } Resolver::Resolver(const LLVMProjectIRDB *IRDB, const LLVMVFTableProvider *VTP) - : IRDB(IRDB), VTP(VTP) {} + : IRDB(IRDB), VTP(VTP), OpaquePtrTypeInfo(IRDB) {} const llvm::Function * Resolver::getNonPureVirtualVFTEntry(const llvm::StructType *T, unsigned Idx, diff --git a/lib/Utils/OpaquePtrTypeMap.cpp b/lib/Utils/OpaquePtrTypeMap.cpp new file mode 100644 index 000000000..9c3dbd74d --- /dev/null +++ b/lib/Utils/OpaquePtrTypeMap.cpp @@ -0,0 +1,25 @@ +#include "phasar/Utils/OpaquePtrTypeMap.h" + +#include "llvm/IR/Instructions.h" + +namespace psr { + +OpaquePtrTypeInfoMap::OpaquePtrTypeInfoMap(const psr::LLVMProjectIRDB *Code) { + for (const auto &Instr : Code->getAllInstructions()) { + if (Instr->getType()->isOpaquePointerTy()) { + TypeInfo.try_emplace(Instr->getValueID()); + } + } + + for (const auto &Instr : Code->getAllInstructions()) { + if (const auto &Store = llvm::dyn_cast(Instr)) { + const auto &Operand = Store->getPointerOperand(); + + if (Operand->getType()->isPointerTy()) { + TypeInfo[Store->getValueID()] = Store->getValueOperand()->getValueID(); + } + } + } +}; + +} // namespace psr \ No newline at end of file diff --git a/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFG_OTFTest.cpp b/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFG_OTFTest.cpp index d745c5937..ba4df9fc7 100644 --- a/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFG_OTFTest.cpp +++ b/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFG_OTFTest.cpp @@ -32,8 +32,7 @@ TEST(LLVMBasedICFG_OTFTest, VirtualCallSite_7) { ASSERT_TRUE(VFuncA); ASSERT_TRUE(VFuncB); - const auto *CallToAFunc = getNthInstruction(F, 27); - llvm::outs() << "CallToAFunc: " << *CallToAFunc << '\n'; + const auto *CallToAFunc = getNthInstruction(F, 19); ASSERT_TRUE(ICFG.isVirtualFunctionCall(CallToAFunc)); const auto &AsCallees = ICFG.getCalleesOfCallAt(CallToAFunc); ASSERT_EQ(AsCallees.size(), 2U); From 812e6cbe142cc46a428ff391a4b4422b53d48336 Mon Sep 17 00:00:00 2001 From: mxHuber Date: Thu, 13 Jun 2024 21:26:25 +0200 Subject: [PATCH 25/78] switching to DebugInfoFinder --- include/phasar/Utils/OpaquePtrTypeMap.h | 5 ++- .../ControlFlow/Resolver/Resolver.cpp | 40 +++++++++++++++---- lib/Utils/OpaquePtrTypeMap.cpp | 4 +- .../llvm_test_code/call_graphs/CMakeLists.txt | 2 +- .../ControlFlow/LLVMBasedICFG_OTFTest.cpp | 2 +- 5 files changed, 39 insertions(+), 14 deletions(-) diff --git a/include/phasar/Utils/OpaquePtrTypeMap.h b/include/phasar/Utils/OpaquePtrTypeMap.h index 0779c7299..67565e1cb 100644 --- a/include/phasar/Utils/OpaquePtrTypeMap.h +++ b/include/phasar/Utils/OpaquePtrTypeMap.h @@ -1,5 +1,6 @@ #include "phasar/PhasarLLVM/DB/LLVMProjectIRDB.h" +#include "llvm/ADT/StringRef.h" #include "llvm/IR/Type.h" #include @@ -8,8 +9,8 @@ namespace psr { class OpaquePtrTypeInfoMap { public: - // maps ValueID of pointer to ValueID of variable - std::map TypeInfo; + // maps name of pointer to name of variable + std::map TypeInfo; OpaquePtrTypeInfoMap(const psr::LLVMProjectIRDB *Code); }; diff --git a/lib/PhasarLLVM/ControlFlow/Resolver/Resolver.cpp b/lib/PhasarLLVM/ControlFlow/Resolver/Resolver.cpp index 70cb731b5..3dfe81165 100644 --- a/lib/PhasarLLVM/ControlFlow/Resolver/Resolver.cpp +++ b/lib/PhasarLLVM/ControlFlow/Resolver/Resolver.cpp @@ -29,8 +29,10 @@ #include "phasar/Utils/Logger.h" #include "llvm/IR/Constants.h" +#include "llvm/IR/DebugInfo.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/InstrTypes.h" +#include "llvm/IR/Instruction.h" #include "llvm/IR/Instructions.h" #include "llvm/Support/Casting.h" #include "llvm/Support/ErrorHandling.h" @@ -71,16 +73,38 @@ const llvm::StructType *psr::getReceiverType(const llvm::CallBase *CallSite, return nullptr; } - if (Receiver->getType()->isOpaquePointerTy()) { + llvm::DebugInfoFinder DIF; + const auto *M = IRDB->getModule(); + // IRDB->dump(); - OpaquePtrTypeInfoMap OpaquePtrTypeInfo(IRDB); + DIF.processModule(*M); - if (const auto *ReceiverTy = llvm::dyn_cast( - IRDB->getValueFromId( - OpaquePtrTypeInfo.TypeInfo[Receiver->getValueID()]) - ->getType())) { - return ReceiverTy; - } + for (const auto &SubP : DIF.subprograms()) { + llvm::outs() << "SubP: " << SubP << "\n"; + llvm::outs() << "Name: " << SubP->getName() << "\n"; + llvm::outs() << "VirtualIndex: " << SubP->getVirtualIndex() << "\n"; + llvm::outs() << "Metadata ID: " << SubP->getMetadataID() << "\n"; + } + + if (Receiver->getType()->isOpaquePointerTy()) { + /* + OpaquePtrTypeInfoMap OpaquePtrTypeInfo(IRDB); + + if (const auto &ReceiverInstr = + llvm::dyn_cast(Receiver)) { + llvm::outs() << "ReceiverInstr opcode name: " + << ReceiverInstr->getOpcodeName() << "\n"; + for (const auto *Instr : IRDB->getAllInstructions()) { + llvm::outs() << "Instr opcode name: " << Instr->getOpcodeName() << + "\n"; if (Instr->getOpcodeName() == ReceiverInstr->getOpcodeName()) { + if (const auto *ReceiverTy = + llvm::dyn_cast(Instr->getType())) { + llvm::outs() << "\nReceiverTy\n" << ReceiverTy << "\n"; + return ReceiverTy; + } + } + } + } */ return nullptr; } diff --git a/lib/Utils/OpaquePtrTypeMap.cpp b/lib/Utils/OpaquePtrTypeMap.cpp index 9c3dbd74d..5b48b1990 100644 --- a/lib/Utils/OpaquePtrTypeMap.cpp +++ b/lib/Utils/OpaquePtrTypeMap.cpp @@ -7,7 +7,7 @@ namespace psr { OpaquePtrTypeInfoMap::OpaquePtrTypeInfoMap(const psr::LLVMProjectIRDB *Code) { for (const auto &Instr : Code->getAllInstructions()) { if (Instr->getType()->isOpaquePointerTy()) { - TypeInfo.try_emplace(Instr->getValueID()); + TypeInfo.try_emplace(Instr->getOpcodeName()); } } @@ -16,7 +16,7 @@ OpaquePtrTypeInfoMap::OpaquePtrTypeInfoMap(const psr::LLVMProjectIRDB *Code) { const auto &Operand = Store->getPointerOperand(); if (Operand->getType()->isPointerTy()) { - TypeInfo[Store->getValueID()] = Store->getValueOperand()->getValueID(); + TypeInfo[Store->getOpcodeName()] = Store->getValueOperand()->getName(); } } } diff --git a/test/llvm_test_code/call_graphs/CMakeLists.txt b/test/llvm_test_code/call_graphs/CMakeLists.txt index 9b1b58ebe..ca97cd932 100644 --- a/test/llvm_test_code/call_graphs/CMakeLists.txt +++ b/test/llvm_test_code/call_graphs/CMakeLists.txt @@ -34,5 +34,5 @@ set(NoMem2regSources ) foreach(TEST_SRC ${NoMem2regSources}) - generate_ll_file(FILE ${TEST_SRC}) + generate_ll_file(FILE ${TEST_SRC} DEBUG) endforeach(TEST_SRC) diff --git a/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFG_OTFTest.cpp b/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFG_OTFTest.cpp index ba4df9fc7..ebe5345d4 100644 --- a/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFG_OTFTest.cpp +++ b/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFG_OTFTest.cpp @@ -19,7 +19,7 @@ using namespace psr; TEST(LLVMBasedICFG_OTFTest, VirtualCallSite_7) { LLVMProjectIRDB IRDB(unittest::PathToLLTestFiles + - "call_graphs/virtual_call_7_cpp.ll"); + "call_graphs/virtual_call_7_cpp_dbg.ll"); LLVMTypeHierarchy TH(IRDB); LLVMAliasSet PT(&IRDB, false); LLVMBasedICFG ICFG(&IRDB, CallGraphAnalysisType::OTF, {"main"}, &TH, &PT); From 8f89d1d15f5ee4676dac1dec7370200cd4994bcc Mon Sep 17 00:00:00 2001 From: Fabian Schiebel Date: Sun, 16 Jun 2024 19:50:52 +0200 Subject: [PATCH 26/78] re-add the quick-fix for LLVMTypeHierarchy --- .../TypeHierarchy/LLVMTypeHierarchy.cpp | 22 ++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/lib/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.cpp b/lib/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.cpp index ca8506e11..66fcba08a 100644 --- a/lib/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.cpp +++ b/lib/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.cpp @@ -88,10 +88,12 @@ LLVMTypeHierarchy::removeStructOrClassPrefix(const llvm::StructType &T) { std::string LLVMTypeHierarchy::removeStructOrClassPrefix(llvm::StringRef TypeName) { if (TypeName.startswith(StructPrefix)) { - return TypeName.drop_front(StructPrefix.size()).str(); + TypeName = TypeName.drop_front(StructPrefix.size()); + } else if (TypeName.startswith(ClassPrefix)) { + TypeName = TypeName.drop_front(ClassPrefix.size()); } - if (TypeName.startswith(ClassPrefix)) { - return TypeName.drop_front(ClassPrefix.size()).str(); + if (TypeName.endswith(".base")) { + TypeName = TypeName.drop_back(llvm::StringRef(".base").size()); } return TypeName.str(); } @@ -265,8 +267,9 @@ LLVMTypeHierarchy::getSubTypes(const llvm::StructType *Type) const { return {}; } -const llvm::StructType * -LLVMTypeHierarchy::getType(llvm::StringRef TypeName) const { +template +static const llvm::StructType *getTypeImpl(const GraphT &TypeGraph, + llvm::StringRef TypeName) { for (auto V : boost::make_iterator_range(boost::vertices(TypeGraph))) { if (TypeGraph[V].Type->getName() == TypeName) { return TypeGraph[V].Type; @@ -275,6 +278,15 @@ LLVMTypeHierarchy::getType(llvm::StringRef TypeName) const { return nullptr; } +const llvm::StructType * +LLVMTypeHierarchy::getType(llvm::StringRef TypeName) const { + if (const auto *Ty = getTypeImpl(TypeGraph, TypeName)) { + return Ty; + } + + return getTypeImpl(TypeGraph, (TypeName + ".base").str()); +} + std::vector LLVMTypeHierarchy::getAllTypes() const { std::vector Types; Types.reserve(boost::num_vertices(TypeGraph)); From 2bfffa8a52b5254e717814e5e937dd19ce36815b Mon Sep 17 00:00:00 2001 From: mxHuber Date: Mon, 17 Jun 2024 23:33:37 +0200 Subject: [PATCH 27/78] OpaquePtr type mapping, missing subroutines --- .../ControlFlow/Resolver/Resolver.h | 5 +- include/phasar/Utils/IRDBOpaquePtrTypes.h | 29 ++++ include/phasar/Utils/OpaquePtrTypeMap.h | 17 --- .../ControlFlow/Resolver/Resolver.cpp | 37 +---- lib/Utils/IRDBOpaquePtrTypes.cpp | 126 ++++++++++++++++++ lib/Utils/OpaquePtrTypeMap.cpp | 25 ---- .../llvm_test_code/call_graphs/CMakeLists.txt | 4 + 7 files changed, 164 insertions(+), 79 deletions(-) create mode 100644 include/phasar/Utils/IRDBOpaquePtrTypes.h delete mode 100644 include/phasar/Utils/OpaquePtrTypeMap.h create mode 100644 lib/Utils/IRDBOpaquePtrTypes.cpp delete mode 100644 lib/Utils/OpaquePtrTypeMap.cpp diff --git a/include/phasar/PhasarLLVM/ControlFlow/Resolver/Resolver.h b/include/phasar/PhasarLLVM/ControlFlow/Resolver/Resolver.h index b143270f0..5cbf894b2 100644 --- a/include/phasar/PhasarLLVM/ControlFlow/Resolver/Resolver.h +++ b/include/phasar/PhasarLLVM/ControlFlow/Resolver/Resolver.h @@ -18,7 +18,7 @@ #define PHASAR_PHASARLLVM_CONTROLFLOW_RESOLVER_RESOLVER_H_ #include "phasar/PhasarLLVM/Pointer/LLVMAliasInfo.h" -#include "phasar/Utils/OpaquePtrTypeMap.h" +#include "phasar/Utils/IRDBOpaquePtrTypes.h" #include "llvm/ADT/DenseSet.h" @@ -55,6 +55,7 @@ class Resolver { protected: const LLVMProjectIRDB *IRDB; const LLVMVFTableProvider *VTP; + IRDBOpaquePtrTypes OpaquePtrTypes; Resolver(const LLVMProjectIRDB *IRDB); @@ -65,8 +66,6 @@ class Resolver { public: using FunctionSetTy = llvm::SmallDenseSet; - OpaquePtrTypeInfoMap OpaquePtrTypeInfo; - Resolver(const LLVMProjectIRDB *IRDB, const LLVMVFTableProvider *VTP); virtual ~Resolver() = default; diff --git a/include/phasar/Utils/IRDBOpaquePtrTypes.h b/include/phasar/Utils/IRDBOpaquePtrTypes.h new file mode 100644 index 000000000..afd7e1ebc --- /dev/null +++ b/include/phasar/Utils/IRDBOpaquePtrTypes.h @@ -0,0 +1,29 @@ + +#include "phasar/PhasarLLVM/DB/LLVMProjectIRDB.h" + +#include "llvm/IR/DebugInfoMetadata.h" +#include "llvm/IR/Type.h" +#include "llvm/IR/Value.h" + +#include + +namespace psr { + +class IRDBOpaquePtrTypes { +public: + IRDBOpaquePtrTypes(const LLVMProjectIRDB *IRDB); + const llvm::Type *getTypeOfPtr(const llvm::Value *Value); + +private: + std::map ValueToDIType; + std::map DITypeToValue; + std::map> + SubprogamVars; + std::map ValueToType; + + const llvm::DIType *getBaseType(const llvm::DIDerivedType *DerivedTy); + const llvm::Type *getPtrType(const llvm::Value *Value); +}; + +} // namespace psr \ No newline at end of file diff --git a/include/phasar/Utils/OpaquePtrTypeMap.h b/include/phasar/Utils/OpaquePtrTypeMap.h deleted file mode 100644 index 67565e1cb..000000000 --- a/include/phasar/Utils/OpaquePtrTypeMap.h +++ /dev/null @@ -1,17 +0,0 @@ -#include "phasar/PhasarLLVM/DB/LLVMProjectIRDB.h" - -#include "llvm/ADT/StringRef.h" -#include "llvm/IR/Type.h" - -#include - -namespace psr { - -class OpaquePtrTypeInfoMap { -public: - // maps name of pointer to name of variable - std::map TypeInfo; - OpaquePtrTypeInfoMap(const psr::LLVMProjectIRDB *Code); -}; - -} // namespace psr diff --git a/lib/PhasarLLVM/ControlFlow/Resolver/Resolver.cpp b/lib/PhasarLLVM/ControlFlow/Resolver/Resolver.cpp index 3dfe81165..bff1fb881 100644 --- a/lib/PhasarLLVM/ControlFlow/Resolver/Resolver.cpp +++ b/lib/PhasarLLVM/ControlFlow/Resolver/Resolver.cpp @@ -30,6 +30,7 @@ #include "llvm/IR/Constants.h" #include "llvm/IR/DebugInfo.h" +#include "llvm/IR/DebugInfoMetadata.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/InstrTypes.h" #include "llvm/IR/Instruction.h" @@ -73,39 +74,7 @@ const llvm::StructType *psr::getReceiverType(const llvm::CallBase *CallSite, return nullptr; } - llvm::DebugInfoFinder DIF; - const auto *M = IRDB->getModule(); - // IRDB->dump(); - - DIF.processModule(*M); - - for (const auto &SubP : DIF.subprograms()) { - llvm::outs() << "SubP: " << SubP << "\n"; - llvm::outs() << "Name: " << SubP->getName() << "\n"; - llvm::outs() << "VirtualIndex: " << SubP->getVirtualIndex() << "\n"; - llvm::outs() << "Metadata ID: " << SubP->getMetadataID() << "\n"; - } - if (Receiver->getType()->isOpaquePointerTy()) { - /* - OpaquePtrTypeInfoMap OpaquePtrTypeInfo(IRDB); - - if (const auto &ReceiverInstr = - llvm::dyn_cast(Receiver)) { - llvm::outs() << "ReceiverInstr opcode name: " - << ReceiverInstr->getOpcodeName() << "\n"; - for (const auto *Instr : IRDB->getAllInstructions()) { - llvm::outs() << "Instr opcode name: " << Instr->getOpcodeName() << - "\n"; if (Instr->getOpcodeName() == ReceiverInstr->getOpcodeName()) { - if (const auto *ReceiverTy = - llvm::dyn_cast(Instr->getType())) { - llvm::outs() << "\nReceiverTy\n" << ReceiverTy << "\n"; - return ReceiverTy; - } - } - } - } */ - return nullptr; } @@ -145,12 +114,12 @@ bool psr::isConsistentCall(const llvm::CallBase *CallSite, namespace psr { Resolver::Resolver(const LLVMProjectIRDB *IRDB) - : IRDB(IRDB), VTP(nullptr), OpaquePtrTypeInfo(IRDB) { + : IRDB(IRDB), VTP(nullptr), OpaquePtrTypes(IRDB) { assert(IRDB != nullptr); } Resolver::Resolver(const LLVMProjectIRDB *IRDB, const LLVMVFTableProvider *VTP) - : IRDB(IRDB), VTP(VTP), OpaquePtrTypeInfo(IRDB) {} + : IRDB(IRDB), VTP(VTP), OpaquePtrTypes(IRDB) {} const llvm::Function * Resolver::getNonPureVirtualVFTEntry(const llvm::StructType *T, unsigned Idx, diff --git a/lib/Utils/IRDBOpaquePtrTypes.cpp b/lib/Utils/IRDBOpaquePtrTypes.cpp new file mode 100644 index 000000000..36c94b77d --- /dev/null +++ b/lib/Utils/IRDBOpaquePtrTypes.cpp @@ -0,0 +1,126 @@ +#include "phasar/Utils/IRDBOpaquePtrTypes.h" + +#include "llvm/IR/DebugInfo.h" +#include "llvm/IR/DebugInfoMetadata.h" +#include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/IntrinsicInst.h" +#include "llvm/Support/Casting.h" +#include "llvm/Support/ErrorHandling.h" + +namespace psr { + +IRDBOpaquePtrTypes::IRDBOpaquePtrTypes(const LLVMProjectIRDB *IRDB) { + llvm::DebugInfoFinder DIF; + const auto *M = IRDB->getModule(); + DIF.processModule(*M); + + for (const auto *Instr : IRDB->getAllInstructions()) { + if (Instr->getType()->isOpaquePointerTy()) { + llvm::outs() << "is opaque pointer\n"; + } + } + + // Map values to DITypes + for (const auto *Instr : IRDB->getAllInstructions()) { + // Check if the current instruction has debug information + if (const auto *DbgDeclare = llvm::dyn_cast(Instr)) { + if (auto *Var = llvm::dyn_cast( + DbgDeclare->getVariable())) { + for (const auto *DIFType : DIF.types()) { + if (Var->getType() == DIFType) { + ValueToDIType.try_emplace(DbgDeclare->getAddress(), DIFType); + } + } + } + } + } + + // Map local variables to their according subprograms + for (const auto *DITy : DIF.types()) { + if (const auto *Var = llvm::dyn_cast(DITy)) { + llvm::outs() << "cast to localVar successful\n"; + if (SubprogamVars.find(Var->getScope()->getSubprogram()) == + SubprogamVars.end()) { + std::vector InitVector; + SubprogamVars.try_emplace(Var->getScope()->getSubprogram(), + std::move(InitVector)); + } + SubprogamVars[Var->getScope()->getSubprogram()].push_back(Var); + } + } + + // Map pointers to the type they are pointing to + for (const auto *Instr : IRDB->getAllInstructions()) { + if (const auto *Value = llvm::dyn_cast(Instr)) { + if (Value->getType()->isOpaquePointerTy()) { + ValueToType.try_emplace(Value, getPtrType(Value)); + } + } + } + + llvm::outs() << "ValueToDIType map:\n"; + for (const auto &[Key, Val] : ValueToDIType) { + llvm::outs() << "Key: " << *Key << " Value: " << *Val << "\n"; + } + + llvm::outs() << "DITypeToValue map:\n"; + for (const auto &[Key, Val] : DITypeToValue) { + llvm::outs() << "Key: " << *Key << " Value: " << *Val << "\n"; + } + + llvm::outs() << "\nSubprogamVars map:\n"; + for (const auto &[Key, Val] : SubprogamVars) { + llvm::outs() << "Key: " << Key << " Values\n{"; + for (const auto &Elem : Val) { + llvm::outs() << Elem << ", "; + } + llvm::outs() << "}\n"; + } + llvm::outs() << "\nValueToType map:\n"; + for (const auto &[Key, Val] : ValueToType) { + llvm::outs() << "Key: " << Key << " Value: " << Val << "\n"; + } +} + +const llvm::Type *IRDBOpaquePtrTypes::getTypeOfPtr(const llvm::Value *Value) { + return ValueToType[Value]; +} + +const llvm::DIType * +IRDBOpaquePtrTypes::getBaseType(const llvm::DIDerivedType *DerivedTy) { + if (const auto *BaseTy = + llvm::dyn_cast(DerivedTy->getBaseType())) { + return BaseTy; + }; + + if (const auto *CompTy = + llvm::dyn_cast(DerivedTy->getBaseType())) { + return CompTy; + } + + // case: getBaseType() is a derived type itself + if (const auto *BaseIsDerivedTy = + llvm::dyn_cast(DerivedTy->getBaseType())) { + return getBaseType(BaseIsDerivedTy); + } + + // case: getBaseType() returns a DISubroutineType, in which we need to + // find the type inside the corresponding subprogram + /* + if (const auto *BaseIsInSubprogram = + llvm::dyn_cast(DerivedTy)) { + return; + }*/ + llvm::report_fatal_error("No base type found"); +} + +const llvm::Type *IRDBOpaquePtrTypes::getPtrType(const llvm::Value *Value) { + const auto *CorrespondingDIType = ValueToDIType[Value]; + if (const auto *DerivedTyTy = + llvm::dyn_cast(CorrespondingDIType)) { + return DITypeToValue[getBaseType(DerivedTyTy)]->getType(); + } + llvm::report_fatal_error("Value is not a derived type"); +} + +} // namespace psr diff --git a/lib/Utils/OpaquePtrTypeMap.cpp b/lib/Utils/OpaquePtrTypeMap.cpp deleted file mode 100644 index 5b48b1990..000000000 --- a/lib/Utils/OpaquePtrTypeMap.cpp +++ /dev/null @@ -1,25 +0,0 @@ -#include "phasar/Utils/OpaquePtrTypeMap.h" - -#include "llvm/IR/Instructions.h" - -namespace psr { - -OpaquePtrTypeInfoMap::OpaquePtrTypeInfoMap(const psr::LLVMProjectIRDB *Code) { - for (const auto &Instr : Code->getAllInstructions()) { - if (Instr->getType()->isOpaquePointerTy()) { - TypeInfo.try_emplace(Instr->getOpcodeName()); - } - } - - for (const auto &Instr : Code->getAllInstructions()) { - if (const auto &Store = llvm::dyn_cast(Instr)) { - const auto &Operand = Store->getPointerOperand(); - - if (Operand->getType()->isPointerTy()) { - TypeInfo[Store->getOpcodeName()] = Store->getValueOperand()->getName(); - } - } - } -}; - -} // namespace psr \ No newline at end of file diff --git a/test/llvm_test_code/call_graphs/CMakeLists.txt b/test/llvm_test_code/call_graphs/CMakeLists.txt index ca97cd932..9a4557b17 100644 --- a/test/llvm_test_code/call_graphs/CMakeLists.txt +++ b/test/llvm_test_code/call_graphs/CMakeLists.txt @@ -33,6 +33,10 @@ set(NoMem2regSources global_ctor_dtor_4.cpp ) +foreach(TEST_SRC ${NoMem2regSources}) + generate_ll_file(FILE ${TEST_SRC}) +endforeach(TEST_SRC) + foreach(TEST_SRC ${NoMem2regSources}) generate_ll_file(FILE ${TEST_SRC} DEBUG) endforeach(TEST_SRC) From 2a91b6ddac99665490df6f06789b2013201c37ec Mon Sep 17 00:00:00 2001 From: mxHuber Date: Tue, 18 Jun 2024 20:40:50 +0200 Subject: [PATCH 28/78] Introducing a pass to save ptr types --- .../PhasarLLVM/Passes/OpaquePtrTyPass.h | 37 ++++++++++ lib/PhasarLLVM/Passes/OpaquePtrTyPass.cpp | 68 +++++++++++++++++++ 2 files changed, 105 insertions(+) create mode 100644 include/phasar/PhasarLLVM/Passes/OpaquePtrTyPass.h create mode 100644 lib/PhasarLLVM/Passes/OpaquePtrTyPass.cpp diff --git a/include/phasar/PhasarLLVM/Passes/OpaquePtrTyPass.h b/include/phasar/PhasarLLVM/Passes/OpaquePtrTyPass.h new file mode 100644 index 000000000..baa7cb6bc --- /dev/null +++ b/include/phasar/PhasarLLVM/Passes/OpaquePtrTyPass.h @@ -0,0 +1,37 @@ +/****************************************************************************** + * Copyright (c) 2018 Philipp Schubert. + * All rights reserved. This program and the accompanying materials are made + * available under the terms of LICENSE.txt. + * + * Contributors: + * Philipp Schubert and others + *****************************************************************************/ + +#ifndef PHASAR_PHASARPASS_OPAQUEPTRTYPASS_H_ +#define PHASAR_PHASARPASS_OPAQUEPTRTYPASS_H_ + +#include "llvm/Pass.h" + +namespace llvm { +class Module; +} // namespace llvm + +namespace psr { + +class OpaquePtrTyPass : public llvm::ModulePass { +public: + static inline char ID = 12; // NOLINT FIXME: make const when LLVM supports it + + explicit OpaquePtrTyPass(); + OpaquePtrTyPass(const OpaquePtrTyPass &) = delete; + OpaquePtrTyPass &operator=(const OpaquePtrTyPass &) = delete; + ~OpaquePtrTyPass() override = default; + + [[nodiscard]] llvm::StringRef getPassName() const override; + + bool runOnModule(llvm::Module &M) override; +}; + +} // namespace psr + +#endif diff --git a/lib/PhasarLLVM/Passes/OpaquePtrTyPass.cpp b/lib/PhasarLLVM/Passes/OpaquePtrTyPass.cpp new file mode 100644 index 000000000..8ff16763f --- /dev/null +++ b/lib/PhasarLLVM/Passes/OpaquePtrTyPass.cpp @@ -0,0 +1,68 @@ +/****************************************************************************** + * Copyright (c) 2024 Philipp Schubert. + * All rights reserved. This program and the accompanying materials are made + * available under the terms of LICENSE.txt. + * + * Contributors: + * Maximilian Leo Huber and others + *****************************************************************************/ + +#include "phasar/PhasarLLVM/Passes/OpaquePtrTyPass.h" + +#include "phasar/Utils/Logger.h" +#include "phasar/Utils/NlohmannLogging.h" + +#include "llvm/ADT/StringRef.h" +#include "llvm/IR/Module.h" +#include "llvm/Support/FileSystem.h" + +#include + +namespace psr { + +OpaquePtrTyPass::OpaquePtrTyPass() : llvm::ModulePass(ID) {} + +llvm::StringRef OpaquePtrTyPass::getPassName() const { + return "OpaquePtrTyPass"; +} + +bool OpaquePtrTyPass::runOnModule(llvm::Module &M) { + llvm::outs() << "OpaquePtrTyPass::runOnModule()\n"; + + std::map PtrTypes; + + // get pointer types + for (const auto &Func : M.getFunctionList()) { + if (Func.isDeclaration()) { + continue; + } + + PtrTypes[Func.getName().str()] = + Func.getFunctionType()->getStructName().str(); + } + + // save pointer types to json file + nlohmann::json Json(PtrTypes); + std::string PathToJson = "./OpaquePtrTyPassJsons/"; + std::string FileName = PathToJson + "PointerTypes.json"; + + llvm::sys::fs::create_directories(PathToJson); + std::error_code EC; + llvm::raw_fd_ostream FileStream(llvm::StringRef(FileName), EC); + + if (EC) { + PHASAR_LOG_LEVEL(ERROR, EC.message()); + return false; + } + + FileStream << Json; + + llvm::outs() << "Json with pointer types saved to: " << PathToJson << "\n"; + + return true; +} +static llvm::RegisterPass + Phasar("opaque-pointer-type-pass", "PhASAR Opaque Pointer Type Pass", false, + false); + +} // namespace psr From d5819877fd3bdfc65cba44e170ad658704da92b1 Mon Sep 17 00:00:00 2001 From: mxHuber Date: Wed, 19 Jun 2024 10:50:58 +0200 Subject: [PATCH 29/78] Revert "Introducing a pass to save ptr types" This reverts commit 2a91b6ddac99665490df6f06789b2013201c37ec. --- .../PhasarLLVM/Passes/OpaquePtrTyPass.h | 37 ---------- lib/PhasarLLVM/Passes/OpaquePtrTyPass.cpp | 68 ------------------- 2 files changed, 105 deletions(-) delete mode 100644 include/phasar/PhasarLLVM/Passes/OpaquePtrTyPass.h delete mode 100644 lib/PhasarLLVM/Passes/OpaquePtrTyPass.cpp diff --git a/include/phasar/PhasarLLVM/Passes/OpaquePtrTyPass.h b/include/phasar/PhasarLLVM/Passes/OpaquePtrTyPass.h deleted file mode 100644 index baa7cb6bc..000000000 --- a/include/phasar/PhasarLLVM/Passes/OpaquePtrTyPass.h +++ /dev/null @@ -1,37 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2018 Philipp Schubert. - * All rights reserved. This program and the accompanying materials are made - * available under the terms of LICENSE.txt. - * - * Contributors: - * Philipp Schubert and others - *****************************************************************************/ - -#ifndef PHASAR_PHASARPASS_OPAQUEPTRTYPASS_H_ -#define PHASAR_PHASARPASS_OPAQUEPTRTYPASS_H_ - -#include "llvm/Pass.h" - -namespace llvm { -class Module; -} // namespace llvm - -namespace psr { - -class OpaquePtrTyPass : public llvm::ModulePass { -public: - static inline char ID = 12; // NOLINT FIXME: make const when LLVM supports it - - explicit OpaquePtrTyPass(); - OpaquePtrTyPass(const OpaquePtrTyPass &) = delete; - OpaquePtrTyPass &operator=(const OpaquePtrTyPass &) = delete; - ~OpaquePtrTyPass() override = default; - - [[nodiscard]] llvm::StringRef getPassName() const override; - - bool runOnModule(llvm::Module &M) override; -}; - -} // namespace psr - -#endif diff --git a/lib/PhasarLLVM/Passes/OpaquePtrTyPass.cpp b/lib/PhasarLLVM/Passes/OpaquePtrTyPass.cpp deleted file mode 100644 index 8ff16763f..000000000 --- a/lib/PhasarLLVM/Passes/OpaquePtrTyPass.cpp +++ /dev/null @@ -1,68 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2024 Philipp Schubert. - * All rights reserved. This program and the accompanying materials are made - * available under the terms of LICENSE.txt. - * - * Contributors: - * Maximilian Leo Huber and others - *****************************************************************************/ - -#include "phasar/PhasarLLVM/Passes/OpaquePtrTyPass.h" - -#include "phasar/Utils/Logger.h" -#include "phasar/Utils/NlohmannLogging.h" - -#include "llvm/ADT/StringRef.h" -#include "llvm/IR/Module.h" -#include "llvm/Support/FileSystem.h" - -#include - -namespace psr { - -OpaquePtrTyPass::OpaquePtrTyPass() : llvm::ModulePass(ID) {} - -llvm::StringRef OpaquePtrTyPass::getPassName() const { - return "OpaquePtrTyPass"; -} - -bool OpaquePtrTyPass::runOnModule(llvm::Module &M) { - llvm::outs() << "OpaquePtrTyPass::runOnModule()\n"; - - std::map PtrTypes; - - // get pointer types - for (const auto &Func : M.getFunctionList()) { - if (Func.isDeclaration()) { - continue; - } - - PtrTypes[Func.getName().str()] = - Func.getFunctionType()->getStructName().str(); - } - - // save pointer types to json file - nlohmann::json Json(PtrTypes); - std::string PathToJson = "./OpaquePtrTyPassJsons/"; - std::string FileName = PathToJson + "PointerTypes.json"; - - llvm::sys::fs::create_directories(PathToJson); - std::error_code EC; - llvm::raw_fd_ostream FileStream(llvm::StringRef(FileName), EC); - - if (EC) { - PHASAR_LOG_LEVEL(ERROR, EC.message()); - return false; - } - - FileStream << Json; - - llvm::outs() << "Json with pointer types saved to: " << PathToJson << "\n"; - - return true; -} -static llvm::RegisterPass - Phasar("opaque-pointer-type-pass", "PhASAR Opaque Pointer Type Pass", false, - false); - -} // namespace psr From 9eb99290a61f8761490693d78ad2e16c7e1ef3a6 Mon Sep 17 00:00:00 2001 From: mxHuber Date: Wed, 19 Jun 2024 22:28:49 +0200 Subject: [PATCH 30/78] moving phasar to DIBasedTypeHierarchy --- .../PhasarLLVM/ControlFlow/LLVMBasedICFG.h | 8 +- .../ControlFlow/LLVMVFTableProvider.h | 4 + .../ControlFlow/Resolver/CHAResolver.h | 7 +- .../ControlFlow/Resolver/DTAResolver.h | 3 +- .../ControlFlow/Resolver/RTAResolver.h | 2 +- .../ControlFlow/Resolver/Resolver.h | 20 +-- .../Mono/Problems/InterMonoSolverTest.h | 7 +- .../Mono/Problems/IntraMonoSolverTest.h | 7 +- include/phasar/PhasarLLVM/HelperAnalyses.h | 6 +- .../TypeHierarchy/DIBasedTypeHierarchy.h | 4 + include/phasar/PhasarLLVM/Utils/LLVMIRToSrc.h | 4 + include/phasar/Utils/IRDBOpaquePtrTypes.h | 29 ---- lib/Controller/AnalysisController.cpp | 2 +- lib/PhasarLLVM/ControlFlow/LLVMBasedICFG.cpp | 12 +- .../ControlFlow/LLVMVFTableProvider.cpp | 13 ++ .../ControlFlow/Resolver/CHAResolver.cpp | 6 +- .../ControlFlow/Resolver/DTAResolver.cpp | 24 ++-- .../ControlFlow/Resolver/RTAResolver.cpp | 21 ++- .../ControlFlow/Resolver/Resolver.cpp | 66 ++++++--- .../Mono/Problems/InterMonoSolverTest.cpp | 4 +- lib/PhasarLLVM/HelperAnalyses.cpp | 6 +- .../TypeHierarchy/DIBasedTypeHierarchy.cpp | 5 + lib/PhasarLLVM/Utils/LLVMIRToSrc.cpp | 3 +- lib/PhasarPass/PhasarPass.cpp | 4 +- lib/Utils/IRDBOpaquePtrTypes.cpp | 126 ------------------ .../ControlFlow/LLVMBasedICFGExportTest.cpp | 6 +- .../LLVMBasedICFGGlobCtorDtorTest.cpp | 20 +-- .../ControlFlow/LLVMBasedICFGTest.cpp | 33 +++-- .../ControlFlow/LLVMBasedICFG_DTATest.cpp | 4 +- .../ControlFlow/LLVMBasedICFG_OTFTest.cpp | 8 +- .../ControlFlow/LLVMBasedICFG_RTATest.cpp | 8 +- .../PathSensitivity/PathTracingTest.cpp | 8 +- .../PhasarLLVM/Pointer/LLVMAliasSetTest.cpp | 6 +- 33 files changed, 204 insertions(+), 282 deletions(-) delete mode 100644 include/phasar/Utils/IRDBOpaquePtrTypes.h delete mode 100644 lib/Utils/IRDBOpaquePtrTypes.cpp diff --git a/include/phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h b/include/phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h index 7cd8e7182..dd363f5c8 100644 --- a/include/phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h +++ b/include/phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h @@ -23,6 +23,7 @@ #include "phasar/PhasarLLVM/ControlFlow/LLVMBasedCFG.h" #include "phasar/PhasarLLVM/ControlFlow/LLVMVFTableProvider.h" #include "phasar/PhasarLLVM/Pointer/LLVMAliasInfo.h" +#include "phasar/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.h" #include "phasar/PhasarLLVM/Utils/LLVMBasedContainerConfig.h" #include "phasar/Utils/Soundness.h" @@ -38,7 +39,7 @@ #include namespace psr { -class LLVMTypeHierarchy; +class DIBasedTypeHierarchy; class LLVMProjectIRDB; class Resolver; @@ -82,7 +83,7 @@ class LLVMBasedICFG : public LLVMBasedCFG, public ICFGBase { /// IRDB. True by default explicit LLVMBasedICFG(LLVMProjectIRDB *IRDB, CallGraphAnalysisType CGType, llvm::ArrayRef EntryPoints = {}, - LLVMTypeHierarchy *TH = nullptr, + DIBasedTypeHierarchy *TH = nullptr, LLVMAliasInfoRef PT = nullptr, Soundness S = Soundness::Soundy, bool IncludeGlobals = true); @@ -102,7 +103,7 @@ class LLVMBasedICFG : public LLVMBasedCFG, public ICFGBase { explicit LLVMBasedICFG(LLVMProjectIRDB *IRDB, const nlohmann::json &SerializedCG); - // Deleter of LLVMTypeHierarchy may be unknown here... + // Deleter of DIBasedTypeHierarchy may be unknown here... ~LLVMBasedICFG(); LLVMBasedICFG(const LLVMBasedICFG &) = delete; @@ -173,6 +174,7 @@ class LLVMBasedICFG : public LLVMBasedCFG, public ICFGBase { CallGraph CG; LLVMProjectIRDB *IRDB = nullptr; LLVMVFTableProvider VTP; + std::map DITypeToValueType; }; extern template class ICFGBase; diff --git a/include/phasar/PhasarLLVM/ControlFlow/LLVMVFTableProvider.h b/include/phasar/PhasarLLVM/ControlFlow/LLVMVFTableProvider.h index 4206070fc..126251da8 100644 --- a/include/phasar/PhasarLLVM/ControlFlow/LLVMVFTableProvider.h +++ b/include/phasar/PhasarLLVM/ControlFlow/LLVMVFTableProvider.h @@ -12,6 +12,8 @@ #include "phasar/PhasarLLVM/TypeHierarchy/LLVMVFTable.h" +#include "llvm/IR/DebugInfoMetadata.h" + #include namespace llvm { @@ -29,11 +31,13 @@ class LLVMVFTableProvider { explicit LLVMVFTableProvider(const LLVMProjectIRDB &IRDB); [[nodiscard]] bool hasVFTable(const llvm::StructType *Type) const; + [[nodiscard]] bool hasVFTable(const llvm::DIType *Type) const; [[nodiscard]] const LLVMVFTable * getVFTableOrNull(const llvm::StructType *Type) const; private: std::unordered_map TypeVFTMap; + std::map DITypeToStructType; }; } // namespace psr diff --git a/include/phasar/PhasarLLVM/ControlFlow/Resolver/CHAResolver.h b/include/phasar/PhasarLLVM/ControlFlow/Resolver/CHAResolver.h index 299a600ea..0b72ef94f 100644 --- a/include/phasar/PhasarLLVM/ControlFlow/Resolver/CHAResolver.h +++ b/include/phasar/PhasarLLVM/ControlFlow/Resolver/CHAResolver.h @@ -18,6 +18,7 @@ #define PHASAR_PHASARLLVM_CONTROLFLOW_RESOLVER_CHARESOLVER_H_ #include "phasar/PhasarLLVM/ControlFlow/Resolver/Resolver.h" +#include "phasar/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.h" #include "phasar/Utils/MaybeUniquePtr.h" namespace llvm { @@ -26,11 +27,11 @@ class Function; } // namespace llvm namespace psr { -class LLVMTypeHierarchy; +class DIBasedTypeHierarchy; class CHAResolver : public Resolver { public: CHAResolver(const LLVMProjectIRDB *IRDB, const LLVMVFTableProvider *VTP, - const LLVMTypeHierarchy *TH); + const DIBasedTypeHierarchy *TH); ~CHAResolver() override = default; @@ -39,7 +40,7 @@ class CHAResolver : public Resolver { [[nodiscard]] std::string str() const override; protected: - MaybeUniquePtr TH; + MaybeUniquePtr TH; }; } // namespace psr diff --git a/include/phasar/PhasarLLVM/ControlFlow/Resolver/DTAResolver.h b/include/phasar/PhasarLLVM/ControlFlow/Resolver/DTAResolver.h index 7b4484f6e..3e8e1ed95 100644 --- a/include/phasar/PhasarLLVM/ControlFlow/Resolver/DTAResolver.h +++ b/include/phasar/PhasarLLVM/ControlFlow/Resolver/DTAResolver.h @@ -19,6 +19,7 @@ #include "phasar/PhasarLLVM/ControlFlow/Resolver/CHAResolver.h" #include "phasar/PhasarLLVM/Pointer/TypeGraphs/CachedTypeGraph.h" +#include "phasar/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.h" // To switch the TypeGraph // #include "phasar/PhasarLLVM/Pointer/TypeGraphs/LazyTypeGraph.h" @@ -56,7 +57,7 @@ class DTAResolver : public CHAResolver { public: DTAResolver(const LLVMProjectIRDB *IRDB, const LLVMVFTableProvider *VTP, - const LLVMTypeHierarchy *TH); + const DIBasedTypeHierarchy *TH); ~DTAResolver() override = default; diff --git a/include/phasar/PhasarLLVM/ControlFlow/Resolver/RTAResolver.h b/include/phasar/PhasarLLVM/ControlFlow/Resolver/RTAResolver.h index 6010443f0..a17ceedc3 100644 --- a/include/phasar/PhasarLLVM/ControlFlow/Resolver/RTAResolver.h +++ b/include/phasar/PhasarLLVM/ControlFlow/Resolver/RTAResolver.h @@ -32,7 +32,7 @@ namespace psr { class RTAResolver : public CHAResolver { public: RTAResolver(const LLVMProjectIRDB *IRDB, const LLVMVFTableProvider *VTP, - const LLVMTypeHierarchy *TH); + const DIBasedTypeHierarchy *TH); ~RTAResolver() override = default; diff --git a/include/phasar/PhasarLLVM/ControlFlow/Resolver/Resolver.h b/include/phasar/PhasarLLVM/ControlFlow/Resolver/Resolver.h index 5cbf894b2..d2e311daa 100644 --- a/include/phasar/PhasarLLVM/ControlFlow/Resolver/Resolver.h +++ b/include/phasar/PhasarLLVM/ControlFlow/Resolver/Resolver.h @@ -18,7 +18,7 @@ #define PHASAR_PHASARLLVM_CONTROLFLOW_RESOLVER_RESOLVER_H_ #include "phasar/PhasarLLVM/Pointer/LLVMAliasInfo.h" -#include "phasar/Utils/IRDBOpaquePtrTypes.h" +#include "phasar/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.h" #include "llvm/ADT/DenseSet.h" @@ -30,23 +30,22 @@ namespace llvm { class Instruction; class CallBase; class Function; -class StructType; +class DIType; } // namespace llvm namespace psr { class LLVMProjectIRDB; class LLVMVFTableProvider; -class LLVMTypeHierarchy; +class DIBasedTypeHierarchy; enum class CallGraphAnalysisType; [[nodiscard]] std::optional getVFTIndex(const llvm::CallBase *CallSite); -[[nodiscard]] const llvm::StructType * -getReceiverType(const llvm::CallBase *CallSite, const LLVMProjectIRDB *IRDB); +[[nodiscard]] const llvm::DIType * +getReceiverType(const llvm::CallBase *CallSite); -[[nodiscard]] std::string getReceiverTypeName(const llvm::CallBase *CallSite, - const LLVMProjectIRDB *IRDB); +[[nodiscard]] std::string getReceiverTypeName(const llvm::CallBase *CallSite); [[nodiscard]] bool isConsistentCall(const llvm::CallBase *CallSite, const llvm::Function *DestFun); @@ -55,12 +54,13 @@ class Resolver { protected: const LLVMProjectIRDB *IRDB; const LLVMVFTableProvider *VTP; - IRDBOpaquePtrTypes OpaquePtrTypes; + std::map DITypeToStructType; Resolver(const LLVMProjectIRDB *IRDB); + void initializeTypeMap(); const llvm::Function * - getNonPureVirtualVFTEntry(const llvm::StructType *T, unsigned Idx, + getNonPureVirtualVFTEntry(const llvm::DIType *T, unsigned Idx, const llvm::CallBase *CallSite); public: @@ -88,7 +88,7 @@ class Resolver { static std::unique_ptr create(CallGraphAnalysisType Ty, const LLVMProjectIRDB *IRDB, const LLVMVFTableProvider *VTP, - const LLVMTypeHierarchy *TH, + const DIBasedTypeHierarchy *TH, LLVMAliasInfoRef PT = nullptr); }; } // namespace psr diff --git a/include/phasar/PhasarLLVM/DataFlow/Mono/Problems/InterMonoSolverTest.h b/include/phasar/PhasarLLVM/DataFlow/Mono/Problems/InterMonoSolverTest.h index 8674ff564..a280365a5 100644 --- a/include/phasar/PhasarLLVM/DataFlow/Mono/Problems/InterMonoSolverTest.h +++ b/include/phasar/PhasarLLVM/DataFlow/Mono/Problems/InterMonoSolverTest.h @@ -36,7 +36,7 @@ class StructType; namespace psr { -class LLVMTypeHierarchy; +class DIBasedTypeHierarchy; struct InterMonoSolverTestDomain : LLVMAnalysisDomainDefault { using mono_container_t = BitVectorSet; @@ -52,8 +52,9 @@ class InterMonoSolverTest : public InterMonoProblem { using i_t = InterMonoSolverTestDomain::i_t; using mono_container_t = InterMonoSolverTestDomain::mono_container_t; - InterMonoSolverTest(const LLVMProjectIRDB *IRDB, const LLVMTypeHierarchy *TH, - const LLVMBasedICFG *ICF, LLVMAliasInfoRef PT, + InterMonoSolverTest(const LLVMProjectIRDB *IRDB, + const DIBasedTypeHierarchy *TH, const LLVMBasedICFG *ICF, + LLVMAliasInfoRef PT, std::vector EntryPoints = {}); ~InterMonoSolverTest() override = default; diff --git a/include/phasar/PhasarLLVM/DataFlow/Mono/Problems/IntraMonoSolverTest.h b/include/phasar/PhasarLLVM/DataFlow/Mono/Problems/IntraMonoSolverTest.h index 13c5ac42f..75e31f25e 100644 --- a/include/phasar/PhasarLLVM/DataFlow/Mono/Problems/IntraMonoSolverTest.h +++ b/include/phasar/PhasarLLVM/DataFlow/Mono/Problems/IntraMonoSolverTest.h @@ -37,7 +37,7 @@ namespace psr { class LLVMBasedCFG; class LLVMBasedICFG; -class LLVMTypeHierarchy; +class DIBasedTypeHierarchy; struct IntraMonoSolverTestAnalysisDomain : public LLVMAnalysisDomainDefault { using mono_container_t = BitVectorSet; @@ -54,8 +54,9 @@ class IntraMonoSolverTest using i_t = IntraMonoSolverTestAnalysisDomain::i_t; using mono_container_t = IntraMonoSolverTestAnalysisDomain::mono_container_t; - IntraMonoSolverTest(const LLVMProjectIRDB *IRDB, const LLVMTypeHierarchy *TH, - const LLVMBasedCFG *CF, LLVMAliasInfoRef PT, + IntraMonoSolverTest(const LLVMProjectIRDB *IRDB, + const DIBasedTypeHierarchy *TH, const LLVMBasedCFG *CF, + LLVMAliasInfoRef PT, std::vector EntryPoints = {}); ~IntraMonoSolverTest() override = default; diff --git a/include/phasar/PhasarLLVM/HelperAnalyses.h b/include/phasar/PhasarLLVM/HelperAnalyses.h index f8cb8029b..2c6f06000 100644 --- a/include/phasar/PhasarLLVM/HelperAnalyses.h +++ b/include/phasar/PhasarLLVM/HelperAnalyses.h @@ -26,7 +26,7 @@ class Module; namespace psr { class LLVMProjectIRDB; -class LLVMTypeHierarchy; +class DIBasedTypeHierarchy; class LLVMBasedICFG; class LLVMBasedCFG; class LLVMAliasSet; @@ -60,14 +60,14 @@ class HelperAnalyses { // NOLINT(cppcoreguidelines-special-member-functions) [[nodiscard]] LLVMProjectIRDB &getProjectIRDB(); [[nodiscard]] LLVMAliasSet &getAliasInfo(); - [[nodiscard]] LLVMTypeHierarchy &getTypeHierarchy(); + [[nodiscard]] DIBasedTypeHierarchy &getTypeHierarchy(); [[nodiscard]] LLVMBasedICFG &getICFG(); [[nodiscard]] LLVMBasedCFG &getCFG(); private: std::unique_ptr IRDB; std::unique_ptr PT; - std::unique_ptr TH; + std::unique_ptr TH; std::unique_ptr ICF; std::unique_ptr CFG; diff --git a/include/phasar/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.h b/include/phasar/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.h index dc7df6ea4..34b194350 100644 --- a/include/phasar/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.h +++ b/include/phasar/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.h @@ -31,6 +31,9 @@ class DIBasedTypeHierarchy using ClassType = const llvm::DIType *; using f_t = const llvm::Function *; + static inline constexpr llvm::StringLiteral PureVirtualCallName = + "__cxa_pure_virtual"; + explicit DIBasedTypeHierarchy(const LLVMProjectIRDB &IRDB); ~DIBasedTypeHierarchy() override = default; @@ -83,6 +86,7 @@ class DIBasedTypeHierarchy void printAsDot(llvm::raw_ostream &OS = llvm::outs()) const; [[nodiscard]] nlohmann::json getAsJson() const override; + void printAsJson(llvm::raw_ostream &OS = llvm::outs()) const; private: [[nodiscard]] llvm::iterator_range diff --git a/include/phasar/PhasarLLVM/Utils/LLVMIRToSrc.h b/include/phasar/PhasarLLVM/Utils/LLVMIRToSrc.h index 9432e9c92..b36149fbe 100644 --- a/include/phasar/PhasarLLVM/Utils/LLVMIRToSrc.h +++ b/include/phasar/PhasarLLVM/Utils/LLVMIRToSrc.h @@ -17,6 +17,8 @@ #ifndef PHASAR_PHASARLLVM_UTILS_LLVMIRTOSRC_H #define PHASAR_PHASARLLVM_UTILS_LLVMIRTOSRC_H +#include "llvm/IR/DebugInfoMetadata.h" + #include "nlohmann/json.hpp" #include @@ -58,6 +60,8 @@ getLineAndColFromIR(const llvm::Value *V); [[nodiscard]] std::string getModuleIDFromIR(const llvm::Value *V); +[[nodiscard]] llvm::DILocalVariable *getDILocalVariable(const llvm::Value *V); + struct SourceCodeInfo { std::string SourceCodeLine; std::string SourceCodeFilename; diff --git a/include/phasar/Utils/IRDBOpaquePtrTypes.h b/include/phasar/Utils/IRDBOpaquePtrTypes.h deleted file mode 100644 index afd7e1ebc..000000000 --- a/include/phasar/Utils/IRDBOpaquePtrTypes.h +++ /dev/null @@ -1,29 +0,0 @@ - -#include "phasar/PhasarLLVM/DB/LLVMProjectIRDB.h" - -#include "llvm/IR/DebugInfoMetadata.h" -#include "llvm/IR/Type.h" -#include "llvm/IR/Value.h" - -#include - -namespace psr { - -class IRDBOpaquePtrTypes { -public: - IRDBOpaquePtrTypes(const LLVMProjectIRDB *IRDB); - const llvm::Type *getTypeOfPtr(const llvm::Value *Value); - -private: - std::map ValueToDIType; - std::map DITypeToValue; - std::map> - SubprogamVars; - std::map ValueToType; - - const llvm::DIType *getBaseType(const llvm::DIDerivedType *DerivedTy); - const llvm::Type *getPtrType(const llvm::Value *Value); -}; - -} // namespace psr \ No newline at end of file diff --git a/lib/Controller/AnalysisController.cpp b/lib/Controller/AnalysisController.cpp index fd77d2ec5..32922b2c9 100644 --- a/lib/Controller/AnalysisController.cpp +++ b/lib/Controller/AnalysisController.cpp @@ -10,7 +10,7 @@ #include "phasar/Controller/AnalysisController.h" #include "phasar/PhasarLLVM/Passes/GeneralStatisticsAnalysis.h" -#include "phasar/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.h" +#include "phasar/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.h" #include "phasar/Utils/NlohmannLogging.h" #include "AnalysisControllerInternal.h" diff --git a/lib/PhasarLLVM/ControlFlow/LLVMBasedICFG.cpp b/lib/PhasarLLVM/ControlFlow/LLVMBasedICFG.cpp index 7c4a5abcf..6ebd3af3d 100644 --- a/lib/PhasarLLVM/ControlFlow/LLVMBasedICFG.cpp +++ b/lib/PhasarLLVM/ControlFlow/LLVMBasedICFG.cpp @@ -17,7 +17,6 @@ #include "phasar/PhasarLLVM/DB/LLVMProjectIRDB.h" #include "phasar/PhasarLLVM/Pointer/LLVMAliasInfo.h" #include "phasar/PhasarLLVM/Pointer/LLVMAliasSet.h" -#include "phasar/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.h" #include "phasar/PhasarLLVM/Utils/LLVMBasedContainerConfig.h" #include "phasar/PhasarLLVM/Utils/LLVMShorthands.h" #include "phasar/Utils/Logger.h" @@ -234,15 +233,14 @@ bool LLVMBasedICFG::Builder::processFunction(const llvm::Function *F) { } static bool internalIsVirtualFunctionCall(const llvm::Instruction *Inst, - const LLVMVFTableProvider &VTP, - const LLVMProjectIRDB *IRDB) { + const LLVMVFTableProvider &VTP) { assert(Inst != nullptr); const auto *CallSite = llvm::dyn_cast(Inst); if (!CallSite) { return false; } // check potential receiver type - const auto *RecType = getReceiverType(CallSite, IRDB); + const auto *RecType = getReceiverType(CallSite); if (!RecType) { return false; } @@ -274,7 +272,7 @@ bool LLVMBasedICFG::Builder::constructDynamicCall(const llvm::Instruction *CS) { // call the resolve routine assert(VTP != nullptr); - auto PossibleTargets = internalIsVirtualFunctionCall(CallSite, *VTP, IRDB) + auto PossibleTargets = internalIsVirtualFunctionCall(CallSite, *VTP) ? Res->resolveVirtualCall(CallSite) : Res->resolveFunctionPointer(CallSite); @@ -339,7 +337,7 @@ void LLVMBasedICFG::initialize(LLVMProjectIRDB *IRDB, Resolver &CGResolver, LLVMBasedICFG::LLVMBasedICFG(LLVMProjectIRDB *IRDB, CallGraphAnalysisType CGType, llvm::ArrayRef EntryPoints, - LLVMTypeHierarchy *TH, LLVMAliasInfoRef PT, + DIBasedTypeHierarchy *TH, LLVMAliasInfoRef PT, Soundness S, bool IncludeGlobals) : IRDB(IRDB), VTP(*IRDB) { assert(IRDB != nullptr); @@ -413,7 +411,7 @@ bool LLVMBasedICFG::isPhasarGenerated(const llvm::Function &F) noexcept { } [[nodiscard]] bool LLVMBasedICFG::isVirtualFunctionCallImpl(n_t Inst) const { - return internalIsVirtualFunctionCall(Inst, VTP, IRDB); + return internalIsVirtualFunctionCall(Inst, VTP); } [[nodiscard]] auto LLVMBasedICFG::allNonCallStartNodesImpl() const diff --git a/lib/PhasarLLVM/ControlFlow/LLVMVFTableProvider.cpp b/lib/PhasarLLVM/ControlFlow/LLVMVFTableProvider.cpp index b34384bd2..0c4f20143 100644 --- a/lib/PhasarLLVM/ControlFlow/LLVMVFTableProvider.cpp +++ b/lib/PhasarLLVM/ControlFlow/LLVMVFTableProvider.cpp @@ -3,11 +3,13 @@ #include "phasar/PhasarLLVM/DB/LLVMProjectIRDB.h" #include "phasar/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.h" #include "phasar/PhasarLLVM/TypeHierarchy/LLVMVFTable.h" +#include "phasar/PhasarLLVM/Utils/LLVMIRToSrc.h" #include "phasar/Utils/Logger.h" #include "llvm/Demangle/Demangle.h" #include "llvm/IR/Constants.h" #include "llvm/IR/Module.h" +#include "llvm/Support/Casting.h" using namespace psr; @@ -49,6 +51,13 @@ LLVMVFTableProvider::LLVMVFTableProvider(const llvm::Module &Mod) { for (const auto *Ty : StructTypes) { TypeVFTMap.try_emplace(Ty, getVirtualFunctions(ClearNameTVMap, *Ty)); } + + for (const auto *StructTy : StructTypes) { + if (const auto *Val = llvm::dyn_cast(StructTy)) { + const auto *DILocalVar = getDILocalVariable(Val); + DITypeToStructType[DILocalVar->getType()] = StructTy; + } + } } LLVMVFTableProvider::LLVMVFTableProvider(const LLVMProjectIRDB &IRDB) @@ -58,6 +67,10 @@ bool LLVMVFTableProvider::hasVFTable(const llvm::StructType *Type) const { return TypeVFTMap.count(Type); } +bool LLVMVFTableProvider::hasVFTable(const llvm::DIType *Type) const { + return DITypeToStructType.count(Type); +} + const LLVMVFTable * LLVMVFTableProvider::getVFTableOrNull(const llvm::StructType *Type) const { auto It = TypeVFTMap.find(Type); diff --git a/lib/PhasarLLVM/ControlFlow/Resolver/CHAResolver.cpp b/lib/PhasarLLVM/ControlFlow/Resolver/CHAResolver.cpp index 9ee78fe92..7428f9fd8 100644 --- a/lib/PhasarLLVM/ControlFlow/Resolver/CHAResolver.cpp +++ b/lib/PhasarLLVM/ControlFlow/Resolver/CHAResolver.cpp @@ -33,10 +33,10 @@ using namespace psr; CHAResolver::CHAResolver(const LLVMProjectIRDB *IRDB, const LLVMVFTableProvider *VTP, - const LLVMTypeHierarchy *TH) + const DIBasedTypeHierarchy *TH) : Resolver(IRDB, VTP), TH(TH) { if (!TH) { - this->TH = std::make_unique(*IRDB); + this->TH = std::make_unique(*IRDB); } } @@ -63,7 +63,7 @@ auto CHAResolver::resolveVirtualCall(const llvm::CallBase *CallSite) PHASAR_LOG_LEVEL(DEBUG, "Virtual function table entry is: " << VtableIndex); - const auto *ReceiverTy = getReceiverType(CallSite, IRDB); + const auto *ReceiverTy = getReceiverType(CallSite); // also insert all possible subtypes vtable entries auto FallbackTys = TH->getSubTypes(ReceiverTy); diff --git a/lib/PhasarLLVM/ControlFlow/Resolver/DTAResolver.cpp b/lib/PhasarLLVM/ControlFlow/Resolver/DTAResolver.cpp index 5f44717b1..adfc97934 100644 --- a/lib/PhasarLLVM/ControlFlow/Resolver/DTAResolver.cpp +++ b/lib/PhasarLLVM/ControlFlow/Resolver/DTAResolver.cpp @@ -17,12 +17,13 @@ #include "phasar/PhasarLLVM/ControlFlow/Resolver/DTAResolver.h" #include "phasar/PhasarLLVM/ControlFlow/LLVMVFTableProvider.h" -#include "phasar/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.h" +#include "phasar/PhasarLLVM/Utils/LLVMIRToSrc.h" #include "phasar/PhasarLLVM/Utils/LLVMShorthands.h" #include "phasar/Utils/Logger.h" #include "phasar/Utils/Utilities.h" #include "llvm/IR/Constants.h" +#include "llvm/IR/DebugInfoMetadata.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/Function.h" #include "llvm/IR/InstIterator.h" @@ -30,6 +31,8 @@ #include "llvm/IR/Instructions.h" #include "llvm/IR/Module.h" #include "llvm/IR/Operator.h" +#include "llvm/IR/Value.h" +#include "llvm/Support/Casting.h" #include @@ -37,7 +40,7 @@ using namespace psr; DTAResolver::DTAResolver(const LLVMProjectIRDB *IRDB, const LLVMVFTableProvider *VTP, - const LLVMTypeHierarchy *TH) + const DIBasedTypeHierarchy *TH) : CHAResolver(IRDB, VTP, TH) {} bool DTAResolver::heuristicAntiConstructorThisType( @@ -185,9 +188,9 @@ auto DTAResolver::resolveVirtualCall(const llvm::CallBase *CallSite) PHASAR_LOG_LEVEL(DEBUG, "Virtual function table entry is: " << VtableIndex); - const auto *ReceiverType = getReceiverType(CallSite, IRDB); + const auto *ReceiverType = getReceiverType(CallSite); - auto PossibleTypes = TypeGraph.getTypes(ReceiverType); + auto PossibleTypes = TypeGraph.getTypes(DITypeToStructType[ReceiverType]); // WARNING We deactivated the check on allocated because it is // unabled to get the types allocated in the used libraries @@ -197,10 +200,15 @@ auto DTAResolver::resolveVirtualCall(const llvm::CallBase *CallSite) if (const auto *PossibleTypeStruct = llvm::dyn_cast(PossibleType)) { // if ( allocated_types.find(possible_type_struct) != end_it ) { - const auto *Target = - getNonPureVirtualVFTEntry(PossibleTypeStruct, VtableIndex, CallSite); - if (Target) { - PossibleCallTargets.insert(Target); + if (const auto *Val = llvm::dyn_cast(PossibleTypeStruct)) { + if (const auto *DITy = + llvm::dyn_cast(getDILocalVariable(Val))) { + const auto *Target = + getNonPureVirtualVFTEntry(DITy, VtableIndex, CallSite); + if (Target) { + PossibleCallTargets.insert(Target); + } + } } } } diff --git a/lib/PhasarLLVM/ControlFlow/Resolver/RTAResolver.cpp b/lib/PhasarLLVM/ControlFlow/Resolver/RTAResolver.cpp index 79c2bfcf2..1cd9cad40 100644 --- a/lib/PhasarLLVM/ControlFlow/Resolver/RTAResolver.cpp +++ b/lib/PhasarLLVM/ControlFlow/Resolver/RTAResolver.cpp @@ -17,7 +17,9 @@ #include "phasar/PhasarLLVM/ControlFlow/Resolver/RTAResolver.h" #include "phasar/PhasarLLVM/DB/LLVMProjectIRDB.h" +#include "phasar/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.h" #include "phasar/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.h" +#include "phasar/PhasarLLVM/Utils/LLVMIRToSrc.h" #include "phasar/PhasarLLVM/Utils/LLVMShorthands.h" #include "phasar/Utils/Logger.h" #include "phasar/Utils/Utilities.h" @@ -37,7 +39,7 @@ using namespace psr; RTAResolver::RTAResolver(const LLVMProjectIRDB *IRDB, const LLVMVFTableProvider *VTP, - const LLVMTypeHierarchy *TH) + const DIBasedTypeHierarchy *TH) : CHAResolver(IRDB, VTP, TH) { resolveAllocatedStructTypes(); } @@ -64,7 +66,7 @@ auto RTAResolver::resolveVirtualCall(const llvm::CallBase *CallSite) PHASAR_LOG_LEVEL(DEBUG, "Virtual function table entry is: " << VtableIndex); - const auto *ReceiverType = getReceiverType(CallSite, IRDB); + const auto *ReceiverType = getReceiverType(CallSite); // also insert all possible subtypes vtable entries auto ReachableTypes = TH->getSubTypes(ReceiverType); @@ -75,11 +77,16 @@ auto RTAResolver::resolveVirtualCall(const llvm::CallBase *CallSite) for (const auto *PossibleType : AllocatedStructTypes) { if (const auto *PossibleTypeStruct = llvm::dyn_cast(PossibleType)) { - if (ReachableTypes.find(PossibleTypeStruct) != EndIt) { - const auto *Target = getNonPureVirtualVFTEntry(PossibleTypeStruct, - VtableIndex, CallSite); - if (Target) { - PossibleCallTargets.insert(Target); + if (const auto *Val = llvm::dyn_cast(PossibleTypeStruct)) { + if (const auto *DITy = + llvm::dyn_cast(getDILocalVariable(Val))) { + if (ReachableTypes.find(DITy) != EndIt) { + const auto *Target = + getNonPureVirtualVFTEntry(DITy, VtableIndex, CallSite); + if (Target) { + PossibleCallTargets.insert(Target); + } + } } } } diff --git a/lib/PhasarLLVM/ControlFlow/Resolver/Resolver.cpp b/lib/PhasarLLVM/ControlFlow/Resolver/Resolver.cpp index bff1fb881..03bff4eca 100644 --- a/lib/PhasarLLVM/ControlFlow/Resolver/Resolver.cpp +++ b/lib/PhasarLLVM/ControlFlow/Resolver/Resolver.cpp @@ -24,7 +24,8 @@ #include "phasar/PhasarLLVM/ControlFlow/Resolver/OTFResolver.h" #include "phasar/PhasarLLVM/ControlFlow/Resolver/RTAResolver.h" #include "phasar/PhasarLLVM/DB/LLVMProjectIRDB.h" -#include "phasar/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.h" +#include "phasar/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.h" +#include "phasar/PhasarLLVM/Utils/LLVMIRToSrc.h" #include "phasar/PhasarLLVM/Utils/LLVMShorthands.h" #include "phasar/Utils/Logger.h" @@ -37,6 +38,7 @@ #include "llvm/IR/Instructions.h" #include "llvm/Support/Casting.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/raw_ostream.h" #include #include @@ -60,8 +62,7 @@ std::optional psr::getVFTIndex(const llvm::CallBase *CallSite) { return std::nullopt; } -const llvm::StructType *psr::getReceiverType(const llvm::CallBase *CallSite, - const LLVMProjectIRDB *IRDB) { +const llvm::DIType *psr::getReceiverType(const llvm::CallBase *CallSite) { if (CallSite->arg_empty() || (CallSite->hasStructRetAttr() && CallSite->arg_size() < 2)) { return nullptr; @@ -75,22 +76,31 @@ const llvm::StructType *psr::getReceiverType(const llvm::CallBase *CallSite, } if (Receiver->getType()->isOpaquePointerTy()) { - return nullptr; + if (const auto *Load = llvm::dyn_cast(Receiver)) { + if (const auto *DerivedTy = llvm::dyn_cast( + getDILocalVariable(Load->getPointerOperand())->getType())) { + return DerivedTy->getBaseType(); + } + } } if (!Receiver->getType()->isOpaquePointerTy()) { if (const auto *ReceiverTy = llvm::dyn_cast( Receiver->getType()->getNonOpaquePointerElementType())) { - return ReceiverTy; + if (const auto *ValueTy = llvm::dyn_cast(ReceiverTy)) { + if (const auto *DerivedTy = llvm::dyn_cast( + getDILocalVariable(ValueTy))) { + return DerivedTy->getBaseType(); + } + } } } return nullptr; } -std::string psr::getReceiverTypeName(const llvm::CallBase *CallSite, - const LLVMProjectIRDB *IRDB) { - const auto *RT = getReceiverType(CallSite, IRDB); +std::string psr::getReceiverTypeName(const llvm::CallBase *CallSite) { + const auto *RT = getReceiverType(CallSite); if (RT) { return RT->getName().str(); } @@ -113,27 +123,35 @@ bool psr::isConsistentCall(const llvm::CallBase *CallSite, namespace psr { -Resolver::Resolver(const LLVMProjectIRDB *IRDB) - : IRDB(IRDB), VTP(nullptr), OpaquePtrTypes(IRDB) { +Resolver::Resolver(const LLVMProjectIRDB *IRDB) : IRDB(IRDB), VTP(nullptr) { assert(IRDB != nullptr); + initializeTypeMap(); } Resolver::Resolver(const LLVMProjectIRDB *IRDB, const LLVMVFTableProvider *VTP) - : IRDB(IRDB), VTP(VTP), OpaquePtrTypes(IRDB) {} + : IRDB(IRDB), VTP(VTP) { + initializeTypeMap(); +} const llvm::Function * -Resolver::getNonPureVirtualVFTEntry(const llvm::StructType *T, unsigned Idx, +Resolver::getNonPureVirtualVFTEntry(const llvm::DIType *T, unsigned Idx, const llvm::CallBase *CallSite) { if (!VTP) { return nullptr; } - if (const auto *VT = VTP->getVFTableOrNull(T)) { - const auto *Target = VT->getFunction(Idx); - if (Target && Target->getName() != LLVMTypeHierarchy::PureVirtualCallName && - isConsistentCall(CallSite, Target)) { - return Target; + + if (const auto *StructTy = + llvm::dyn_cast(DITypeToStructType[T])) { + if (const auto *VT = VTP->getVFTableOrNull(StructTy)) { + const auto *Target = VT->getFunction(Idx); + if (Target && + Target->getName() != DIBasedTypeHierarchy::PureVirtualCallName && + isConsistentCall(CallSite, Target)) { + return Target; + } } } + return nullptr; } @@ -167,7 +185,7 @@ void Resolver::otherInst(const llvm::Instruction *Inst) {} std::unique_ptr Resolver::create(CallGraphAnalysisType Ty, const LLVMProjectIRDB *IRDB, const LLVMVFTableProvider *VTP, - const LLVMTypeHierarchy *TH, + const DIBasedTypeHierarchy *TH, LLVMAliasInfoRef PT) { assert(IRDB != nullptr); assert(VTP != nullptr); @@ -198,4 +216,16 @@ std::unique_ptr Resolver::create(CallGraphAnalysisType Ty, "above switch"); } +void Resolver::initializeTypeMap() { + for (const auto *Instr : IRDB->getAllInstructions()) { + if (const auto *Val = llvm::dyn_cast(Instr)) { + const auto *DILocalVar = getDILocalVariable(Val); + if (const auto *StructTy = + llvm::dyn_cast(Val->getType())) { + DITypeToStructType[DILocalVar->getType()] = StructTy; + } + } + } +} + } // namespace psr diff --git a/lib/PhasarLLVM/DataFlow/Mono/Problems/InterMonoSolverTest.cpp b/lib/PhasarLLVM/DataFlow/Mono/Problems/InterMonoSolverTest.cpp index 5d14d7fa4..51b8a9260 100644 --- a/lib/PhasarLLVM/DataFlow/Mono/Problems/InterMonoSolverTest.cpp +++ b/lib/PhasarLLVM/DataFlow/Mono/Problems/InterMonoSolverTest.cpp @@ -12,7 +12,7 @@ #include "phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h" #include "phasar/PhasarLLVM/DB/LLVMProjectIRDB.h" #include "phasar/PhasarLLVM/Pointer/LLVMAliasInfo.h" -#include "phasar/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.h" +#include "phasar/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.h" #include "phasar/PhasarLLVM/Utils/LLVMShorthands.h" #include "phasar/Utils/Utilities.h" @@ -26,7 +26,7 @@ namespace psr { InterMonoSolverTest::InterMonoSolverTest(const LLVMProjectIRDB *IRDB, - const LLVMTypeHierarchy *TH, + const DIBasedTypeHierarchy *TH, const LLVMBasedICFG *ICF, LLVMAliasInfoRef PT, std::vector EntryPoints) diff --git a/lib/PhasarLLVM/HelperAnalyses.cpp b/lib/PhasarLLVM/HelperAnalyses.cpp index 815f9d887..ce9b2f095 100644 --- a/lib/PhasarLLVM/HelperAnalyses.cpp +++ b/lib/PhasarLLVM/HelperAnalyses.cpp @@ -3,7 +3,7 @@ #include "phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h" #include "phasar/PhasarLLVM/DB/LLVMProjectIRDB.h" #include "phasar/PhasarLLVM/Pointer/LLVMAliasSet.h" -#include "phasar/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.h" +#include "phasar/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.h" #include #include @@ -79,9 +79,9 @@ LLVMAliasSet &HelperAnalyses::getAliasInfo() { return *PT; } -LLVMTypeHierarchy &HelperAnalyses::getTypeHierarchy() { +DIBasedTypeHierarchy &HelperAnalyses::getTypeHierarchy() { if (!TH) { - TH = std::make_unique(getProjectIRDB()); + TH = std::make_unique(getProjectIRDB()); } return *TH; } diff --git a/lib/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.cpp b/lib/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.cpp index fd01a0759..4d581373e 100644 --- a/lib/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.cpp +++ b/lib/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.cpp @@ -241,6 +241,11 @@ void DIBasedTypeHierarchy::print(llvm::raw_ostream &OS) const { llvm::report_fatal_error("Not implemented"); } +void DIBasedTypeHierarchy::printAsJson(llvm::raw_ostream &OS) const { + /// TODO: implement + llvm::report_fatal_error("Not implemented"); +} + void DIBasedTypeHierarchy::printAsDot(llvm::raw_ostream &OS) const { OS << "digraph TypeHierarchy{\n"; scope_exit CloseBrace = [&OS] { OS << "}\n"; }; diff --git a/lib/PhasarLLVM/Utils/LLVMIRToSrc.cpp b/lib/PhasarLLVM/Utils/LLVMIRToSrc.cpp index 01dd07603..d4b9372a9 100644 --- a/lib/PhasarLLVM/Utils/LLVMIRToSrc.cpp +++ b/lib/PhasarLLVM/Utils/LLVMIRToSrc.cpp @@ -12,7 +12,6 @@ #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringRef.h" #include "llvm/Demangle/Demangle.h" -#include "llvm/IR/DebugInfoMetadata.h" #include "llvm/IR/DebugLoc.h" #include "llvm/IR/Instruction.h" #include "llvm/IR/Instructions.h" @@ -56,7 +55,7 @@ static llvm::DbgVariableIntrinsic *getDbgVarIntrinsic(const llvm::Value *V) { return nullptr; } -static llvm::DILocalVariable *getDILocalVariable(const llvm::Value *V) { +llvm::DILocalVariable *getDILocalVariable(const llvm::Value *V) { if (auto *DbgIntr = getDbgVarIntrinsic(V)) { if (auto *DDI = llvm::dyn_cast(DbgIntr)) { return DDI->getVariable(); diff --git a/lib/PhasarPass/PhasarPass.cpp b/lib/PhasarPass/PhasarPass.cpp index d16a1fb78..7d133b761 100644 --- a/lib/PhasarPass/PhasarPass.cpp +++ b/lib/PhasarPass/PhasarPass.cpp @@ -32,7 +32,7 @@ #include "phasar/PhasarLLVM/DataFlow/Mono/Problems/IntraMonoSolverTest.h" #include "phasar/PhasarLLVM/Pointer/LLVMAliasSet.h" #include "phasar/PhasarLLVM/TaintConfig/LLVMTaintConfig.h" -#include "phasar/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.h" +#include "phasar/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.h" #include "phasar/PhasarLLVM/Utils/DataFlowAnalysisType.h" #include "phasar/PhasarPass/Options.h" #include "phasar/Utils/EnumFlags.h" @@ -62,7 +62,7 @@ bool PhasarPass::runOnModule(llvm::Module &M) { } // set up the call-graph algorithm to be used CallGraphAnalysisType CGTy = toCallGraphAnalysisType(CallGraphAnalysis); - LLVMTypeHierarchy H(DB); + DIBasedTypeHierarchy H(DB); LLVMAliasSet PT(&DB); // LLVMBasedCFG CFG; LLVMBasedICFG I(&DB, CGTy, EntryPoints, &H, &PT); diff --git a/lib/Utils/IRDBOpaquePtrTypes.cpp b/lib/Utils/IRDBOpaquePtrTypes.cpp deleted file mode 100644 index 36c94b77d..000000000 --- a/lib/Utils/IRDBOpaquePtrTypes.cpp +++ /dev/null @@ -1,126 +0,0 @@ -#include "phasar/Utils/IRDBOpaquePtrTypes.h" - -#include "llvm/IR/DebugInfo.h" -#include "llvm/IR/DebugInfoMetadata.h" -#include "llvm/IR/DerivedTypes.h" -#include "llvm/IR/IntrinsicInst.h" -#include "llvm/Support/Casting.h" -#include "llvm/Support/ErrorHandling.h" - -namespace psr { - -IRDBOpaquePtrTypes::IRDBOpaquePtrTypes(const LLVMProjectIRDB *IRDB) { - llvm::DebugInfoFinder DIF; - const auto *M = IRDB->getModule(); - DIF.processModule(*M); - - for (const auto *Instr : IRDB->getAllInstructions()) { - if (Instr->getType()->isOpaquePointerTy()) { - llvm::outs() << "is opaque pointer\n"; - } - } - - // Map values to DITypes - for (const auto *Instr : IRDB->getAllInstructions()) { - // Check if the current instruction has debug information - if (const auto *DbgDeclare = llvm::dyn_cast(Instr)) { - if (auto *Var = llvm::dyn_cast( - DbgDeclare->getVariable())) { - for (const auto *DIFType : DIF.types()) { - if (Var->getType() == DIFType) { - ValueToDIType.try_emplace(DbgDeclare->getAddress(), DIFType); - } - } - } - } - } - - // Map local variables to their according subprograms - for (const auto *DITy : DIF.types()) { - if (const auto *Var = llvm::dyn_cast(DITy)) { - llvm::outs() << "cast to localVar successful\n"; - if (SubprogamVars.find(Var->getScope()->getSubprogram()) == - SubprogamVars.end()) { - std::vector InitVector; - SubprogamVars.try_emplace(Var->getScope()->getSubprogram(), - std::move(InitVector)); - } - SubprogamVars[Var->getScope()->getSubprogram()].push_back(Var); - } - } - - // Map pointers to the type they are pointing to - for (const auto *Instr : IRDB->getAllInstructions()) { - if (const auto *Value = llvm::dyn_cast(Instr)) { - if (Value->getType()->isOpaquePointerTy()) { - ValueToType.try_emplace(Value, getPtrType(Value)); - } - } - } - - llvm::outs() << "ValueToDIType map:\n"; - for (const auto &[Key, Val] : ValueToDIType) { - llvm::outs() << "Key: " << *Key << " Value: " << *Val << "\n"; - } - - llvm::outs() << "DITypeToValue map:\n"; - for (const auto &[Key, Val] : DITypeToValue) { - llvm::outs() << "Key: " << *Key << " Value: " << *Val << "\n"; - } - - llvm::outs() << "\nSubprogamVars map:\n"; - for (const auto &[Key, Val] : SubprogamVars) { - llvm::outs() << "Key: " << Key << " Values\n{"; - for (const auto &Elem : Val) { - llvm::outs() << Elem << ", "; - } - llvm::outs() << "}\n"; - } - llvm::outs() << "\nValueToType map:\n"; - for (const auto &[Key, Val] : ValueToType) { - llvm::outs() << "Key: " << Key << " Value: " << Val << "\n"; - } -} - -const llvm::Type *IRDBOpaquePtrTypes::getTypeOfPtr(const llvm::Value *Value) { - return ValueToType[Value]; -} - -const llvm::DIType * -IRDBOpaquePtrTypes::getBaseType(const llvm::DIDerivedType *DerivedTy) { - if (const auto *BaseTy = - llvm::dyn_cast(DerivedTy->getBaseType())) { - return BaseTy; - }; - - if (const auto *CompTy = - llvm::dyn_cast(DerivedTy->getBaseType())) { - return CompTy; - } - - // case: getBaseType() is a derived type itself - if (const auto *BaseIsDerivedTy = - llvm::dyn_cast(DerivedTy->getBaseType())) { - return getBaseType(BaseIsDerivedTy); - } - - // case: getBaseType() returns a DISubroutineType, in which we need to - // find the type inside the corresponding subprogram - /* - if (const auto *BaseIsInSubprogram = - llvm::dyn_cast(DerivedTy)) { - return; - }*/ - llvm::report_fatal_error("No base type found"); -} - -const llvm::Type *IRDBOpaquePtrTypes::getPtrType(const llvm::Value *Value) { - const auto *CorrespondingDIType = ValueToDIType[Value]; - if (const auto *DerivedTyTy = - llvm::dyn_cast(CorrespondingDIType)) { - return DITypeToValue[getBaseType(DerivedTyTy)]->getType(); - } - llvm::report_fatal_error("Value is not a derived type"); -} - -} // namespace psr diff --git a/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFGExportTest.cpp b/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFGExportTest.cpp index d89cd9931..d8c05b849 100644 --- a/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFGExportTest.cpp +++ b/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFGExportTest.cpp @@ -4,7 +4,7 @@ #include "phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h" #include "phasar/PhasarLLVM/DB/LLVMProjectIRDB.h" #include "phasar/PhasarLLVM/Passes/ValueAnnotationPass.h" -#include "phasar/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.h" +#include "phasar/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.h" #include "phasar/PhasarLLVM/Utils/LLVMIRToSrc.h" #include "phasar/PhasarLLVM/Utils/LLVMShorthands.h" #include "phasar/Utils/IO.h" @@ -43,7 +43,7 @@ class LLVMBasedICFGExportTest : public ::testing::Test { nlohmann::json exportICFG(const std::string &TestFile, bool AsSrcCode = false) { LLVMProjectIRDB IRDB(PathToLLFiles + TestFile); - LLVMTypeHierarchy TH(IRDB); + DIBasedTypeHierarchy TH(IRDB); LLVMBasedICFG ICFG(&IRDB, CallGraphAnalysisType::OTF, {"main"}, &TH, nullptr, Soundness::Soundy, /*IncludeGlobals*/ false); @@ -189,7 +189,7 @@ class LLVMBasedICFGExportTest : public ::testing::Test { void verifyExportICFG(const llvm::Twine &TestFile, bool WithDebugOutput = false) { LLVMProjectIRDB IRDB(PathToLLFiles + TestFile); - LLVMTypeHierarchy TH(IRDB); + DIBasedTypeHierarchy TH(IRDB); LLVMBasedICFG ICFG(&IRDB, CallGraphAnalysisType::OTF, {"main"}, &TH, nullptr, Soundness::Soundy, /*IncludeGlobals*/ false); diff --git a/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFGGlobCtorDtorTest.cpp b/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFGGlobCtorDtorTest.cpp index 0977c8189..6e95f9c1a 100644 --- a/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFGGlobCtorDtorTest.cpp +++ b/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFGGlobCtorDtorTest.cpp @@ -15,7 +15,7 @@ #include "phasar/PhasarLLVM/DataFlow/IfdsIde/Problems/IDELinearConstantAnalysis.h" #include "phasar/PhasarLLVM/Passes/ValueAnnotationPass.h" #include "phasar/PhasarLLVM/Pointer/LLVMAliasSet.h" -#include "phasar/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.h" +#include "phasar/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.h" #include "phasar/PhasarLLVM/Utils/LLVMShorthands.h" #include "phasar/Utils/Logger.h" @@ -83,7 +83,7 @@ class LLVMBasedICFGGlobCtorDtorTest : public ::testing::Test { TEST_F(LLVMBasedICFGGlobCtorDtorTest, CtorTest) { LLVMProjectIRDB IRDB(PathToLLFiles + "globals_ctor_1_cpp.ll"); - LLVMTypeHierarchy TH(IRDB); + DIBasedTypeHierarchy TH(IRDB); LLVMAliasSet PT(&IRDB); LLVMBasedICFG ICFG(&IRDB, CallGraphAnalysisType::OTF, {"main"}, &TH, &PT, Soundness::Soundy, /*IncludeGlobals*/ true); @@ -114,7 +114,7 @@ TEST_F(LLVMBasedICFGGlobCtorDtorTest, CtorTest2) { ASSERT_FALSE(LinkerError); LLVMProjectIRDB IRDB(std::move(M1), /*DoPreprocessing*/ true); - LLVMTypeHierarchy TH(IRDB); + DIBasedTypeHierarchy TH(IRDB); LLVMAliasSet PT(&IRDB); LLVMBasedICFG ICFG(&IRDB, CallGraphAnalysisType::OTF, {"main"}, &TH, &PT, Soundness::Soundy, /*IncludeGlobals*/ true); @@ -132,7 +132,7 @@ TEST_F(LLVMBasedICFGGlobCtorDtorTest, CtorTest2) { TEST_F(LLVMBasedICFGGlobCtorDtorTest, DtorTest1) { LLVMProjectIRDB IRDB(PathToLLFiles + "globals_dtor_1_cpp.ll"); - LLVMTypeHierarchy TH(IRDB); + DIBasedTypeHierarchy TH(IRDB); LLVMAliasSet PT(&IRDB); LLVMBasedICFG ICFG(&IRDB, CallGraphAnalysisType::OTF, {"main"}, &TH, &PT, Soundness::Soundy, /*IncludeGlobals*/ true); @@ -167,7 +167,7 @@ TEST_F(LLVMBasedICFGGlobCtorDtorTest, DtorTest1) { TEST_F(LLVMBasedICFGGlobCtorDtorTest, LCATest1) { LLVMProjectIRDB IRDB(PathToLLFiles + "globals_lca_1_cpp.ll"); - LLVMTypeHierarchy TH(IRDB); + DIBasedTypeHierarchy TH(IRDB); LLVMAliasSet PT(&IRDB); LLVMBasedICFG ICFG(&IRDB, CallGraphAnalysisType::OTF, {"main"}, &TH, &PT, Soundness::Soundy, /*IncludeGlobals*/ true); @@ -203,7 +203,7 @@ TEST_F(LLVMBasedICFGGlobCtorDtorTest, LCATest1) { TEST_F(LLVMBasedICFGGlobCtorDtorTest, LCATest2) { LLVMProjectIRDB IRDB(PathToLLFiles + "globals_lca_2_cpp.ll"); - LLVMTypeHierarchy TH(IRDB); + DIBasedTypeHierarchy TH(IRDB); LLVMAliasSet PT(&IRDB); LLVMBasedICFG ICFG(&IRDB, CallGraphAnalysisType::OTF, {"main"}, &TH, &PT, Soundness::Soundy, /*IncludeGlobals*/ true); @@ -244,7 +244,7 @@ TEST_F(LLVMBasedICFGGlobCtorDtorTest, LCATest2) { TEST_F(LLVMBasedICFGGlobCtorDtorTest, LCATest3) { LLVMProjectIRDB IRDB(PathToLLFiles + "globals_lca_3_cpp.ll"); - LLVMTypeHierarchy TH(IRDB); + DIBasedTypeHierarchy TH(IRDB); LLVMAliasSet PT(&IRDB); LLVMBasedICFG ICFG(&IRDB, CallGraphAnalysisType::OTF, {"main"}, &TH, &PT, Soundness::Soundy, /*IncludeGlobals*/ true); @@ -288,7 +288,7 @@ TEST_F(LLVMBasedICFGGlobCtorDtorTest, LCATest3) { TEST_F(LLVMBasedICFGGlobCtorDtorTest, DISABLED_LCATest4) { LLVMProjectIRDB IRDB(PathToLLFiles + "globals_lca_4_cpp.ll"); - LLVMTypeHierarchy TH(IRDB); + DIBasedTypeHierarchy TH(IRDB); LLVMAliasSet PT(&IRDB); LLVMBasedICFG ICFG( &IRDB, CallGraphAnalysisType::OTF, {"main"}, &TH, &PT, Soundness::Soundy, @@ -321,7 +321,7 @@ TEST_F(LLVMBasedICFGGlobCtorDtorTest, DISABLED_LCATest4) { TEST_F(LLVMBasedICFGGlobCtorDtorTest, LCATest4_1) { LLVMProjectIRDB IRDB(PathToLLFiles + "globals_lca_4_1_cpp.ll"); - LLVMTypeHierarchy TH(IRDB); + DIBasedTypeHierarchy TH(IRDB); LLVMAliasSet PT(&IRDB); LLVMBasedICFG ICFG( &IRDB, CallGraphAnalysisType::OTF, {"main"}, &TH, &PT, Soundness::Soundy, @@ -354,7 +354,7 @@ TEST_F(LLVMBasedICFGGlobCtorDtorTest, LCATest4_1) { TEST_F(LLVMBasedICFGGlobCtorDtorTest, LCATest5) { LLVMProjectIRDB IRDB(PathToLLFiles + "globals_lca_5_cpp.ll"); - LLVMTypeHierarchy TH(IRDB); + DIBasedTypeHierarchy TH(IRDB); LLVMAliasSet PT(&IRDB); LLVMBasedICFG ICFG(&IRDB, CallGraphAnalysisType::OTF, {"main"}, &TH, &PT, Soundness::Soundy, diff --git a/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFGTest.cpp b/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFGTest.cpp index 249283fde..aa9b79ded 100644 --- a/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFGTest.cpp +++ b/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFGTest.cpp @@ -3,10 +3,9 @@ #include "phasar/Config/Configuration.h" #include "phasar/ControlFlow/CallGraphAnalysisType.h" #include "phasar/PhasarLLVM/ControlFlow/LLVMBasedCFG.h" -#include "phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h" #include "phasar/PhasarLLVM/DB/LLVMProjectIRDB.h" #include "phasar/PhasarLLVM/Pointer/LLVMAliasSet.h" -#include "phasar/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.h" +#include "phasar/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.h" #include "phasar/PhasarLLVM/Utils/LLVMShorthands.h" #include "llvm/Support/raw_ostream.h" @@ -28,7 +27,7 @@ template static auto makeSet(T &&Vec) { TEST(LLVMBasedICFGTest, StaticCallSite_1) { LLVMProjectIRDB IRDB(unittest::PathToLLTestFiles + "call_graphs/static_callsite_1_c.ll"); - LLVMTypeHierarchy TH(IRDB); + DIBasedTypeHierarchy TH(IRDB); LLVMAliasSet PT(&IRDB); LLVMBasedICFG ICFG(&IRDB, CallGraphAnalysisType::CHA, {"main"}, &TH, &PT); const llvm::Function *F = IRDB.getFunctionDefinition("main"); @@ -49,7 +48,7 @@ TEST(LLVMBasedICFGTest, StaticCallSite_1) { TEST(LLVMBasedICFGTest, StaticCallSite_2a) { LLVMProjectIRDB IRDB(unittest::PathToLLTestFiles + "call_graphs/static_callsite_2_c.ll"); - LLVMTypeHierarchy TH(IRDB); + DIBasedTypeHierarchy TH(IRDB); LLVMAliasSet PT(&IRDB); LLVMBasedICFG ICFG(&IRDB, CallGraphAnalysisType::CHA, {"main"}, &TH, &PT, Soundness::Soundy, false); @@ -76,7 +75,7 @@ TEST(LLVMBasedICFGTest, StaticCallSite_2a) { TEST(LLVMBasedICFGTest, StaticCallSite_2b) { LLVMProjectIRDB IRDB(unittest::PathToLLTestFiles + "call_graphs/static_callsite_2_c.ll"); - LLVMTypeHierarchy TH(IRDB); + DIBasedTypeHierarchy TH(IRDB); LLVMAliasSet PT(&IRDB); LLVMBasedICFG ICFG(&IRDB, CallGraphAnalysisType::CHA, {"main"}, &TH, &PT); const llvm::Function *F = IRDB.getFunctionDefinition("main"); @@ -110,7 +109,7 @@ TEST(LLVMBasedICFGTest, StaticCallSite_2b) { TEST(LLVMBasedICFGTest, VirtualCallSite_1) { LLVMProjectIRDB IRDB(unittest::PathToLLTestFiles + "call_graphs/virtual_call_1_cpp.ll"); - LLVMTypeHierarchy TH(IRDB); + DIBasedTypeHierarchy TH(IRDB); LLVMAliasSet PT(&IRDB); LLVMBasedICFG ICFG(&IRDB, CallGraphAnalysisType::CHA, {"main"}, &TH, &PT); const llvm::Function *F = IRDB.getFunctionDefinition("main"); @@ -130,7 +129,7 @@ TEST(LLVMBasedICFGTest, VirtualCallSite_1) { TEST(LLVMBasedICFGTest, FunctionPointer_1) { LLVMProjectIRDB IRDB(unittest::PathToLLTestFiles + "call_graphs/function_pointer_1_c.ll"); - LLVMTypeHierarchy TH(IRDB); + DIBasedTypeHierarchy TH(IRDB); LLVMAliasSet PT(&IRDB); LLVMBasedICFG ICFG(&IRDB, CallGraphAnalysisType::CHA, {"main"}, &TH, &PT); const llvm::Function *F = IRDB.getFunctionDefinition("main"); @@ -149,7 +148,7 @@ TEST(LLVMBasedICFGTest, FunctionPointer_1) { TEST(LLVMBasedICFGTest, StaticCallSite_3) { LLVMProjectIRDB IRDB(unittest::PathToLLTestFiles + "call_graphs/static_callsite_3_c.ll"); - LLVMTypeHierarchy TH(IRDB); + DIBasedTypeHierarchy TH(IRDB); LLVMAliasSet PT(&IRDB); LLVMBasedICFG ICFG(&IRDB, CallGraphAnalysisType::CHA, {"main"}, &TH, &PT); const llvm::Function *Factorial = IRDB.getFunctionDefinition("factorial"); @@ -169,7 +168,7 @@ TEST(LLVMBasedICFGTest, StaticCallSite_3) { TEST(LLVMBasedICFGTest, StaticCallSite_4) { LLVMProjectIRDB IRDB(unittest::PathToLLTestFiles + "call_graphs/static_callsite_4_cpp.ll"); - LLVMTypeHierarchy TH(IRDB); + DIBasedTypeHierarchy TH(IRDB); LLVMAliasSet PT(&IRDB); LLVMBasedICFG ICFG(&IRDB, CallGraphAnalysisType::CHA, {"main"}, &TH, &PT); const llvm::Function *F = IRDB.getFunctionDefinition("main"); @@ -202,7 +201,7 @@ TEST(LLVMBasedICFGTest, StaticCallSite_4) { TEST(LLVMBasedICFGTest, StaticCallSite_5) { LLVMProjectIRDB IRDB(unittest::PathToLLTestFiles + "call_graphs/static_callsite_5_cpp.ll"); - LLVMTypeHierarchy TH(IRDB); + DIBasedTypeHierarchy TH(IRDB); LLVMAliasSet PT(&IRDB); LLVMBasedICFG ICFG(&IRDB, CallGraphAnalysisType::CHA, {"main"}, &TH, &PT); const llvm::Function *F = IRDB.getFunctionDefinition("main"); @@ -225,7 +224,7 @@ TEST(LLVMBasedICFGTest, StaticCallSite_5) { TEST(LLVMBasedICFGTest, StaticCallSite_6) { LLVMProjectIRDB IRDB(unittest::PathToLLTestFiles + "call_graphs/static_callsite_6_cpp.ll"); - LLVMTypeHierarchy TH(IRDB); + DIBasedTypeHierarchy TH(IRDB); LLVMAliasSet PT(&IRDB); LLVMBasedICFG ICFG(&IRDB, CallGraphAnalysisType::CHA, {"main"}, &TH, &PT); const llvm::Function *F = IRDB.getFunctionDefinition("main"); @@ -251,7 +250,7 @@ TEST(LLVMBasedICFGTest, StaticCallSite_6) { TEST(LLVMBasedICFGTest, StaticCallSite_7) { LLVMProjectIRDB IRDB(unittest::PathToLLTestFiles + "call_graphs/static_callsite_7_cpp.ll"); - LLVMTypeHierarchy TH(IRDB); + DIBasedTypeHierarchy TH(IRDB); LLVMAliasSet PT(&IRDB); LLVMBasedICFG ICFG(&IRDB, CallGraphAnalysisType::CHA, {"main"}, &TH, &PT); const llvm::Function *Main = IRDB.getFunctionDefinition("main"); @@ -275,7 +274,7 @@ TEST(LLVMBasedICFGTest, StaticCallSite_7) { TEST(LLVMBasedICFGTest, StaticCallSite_8) { LLVMProjectIRDB IRDB(unittest::PathToLLTestFiles + "call_graphs/static_callsite_8_cpp.ll"); - LLVMTypeHierarchy TH(IRDB); + DIBasedTypeHierarchy TH(IRDB); LLVMAliasSet PT(&IRDB); LLVMBasedICFG ICFG(&IRDB, CallGraphAnalysisType::CHA, {"main"}, &TH, &PT); const llvm::Function *F = IRDB.getFunctionDefinition("main"); @@ -299,7 +298,7 @@ TEST(LLVMBasedICFGTest, StaticCallSite_8) { TEST(LLVMBasedICFGTest, GlobalCtorDtor_1) { LLVMProjectIRDB IRDB(unittest::PathToLLTestFiles + "call_graphs/global_ctor_dtor_1_cpp.ll"); - LLVMTypeHierarchy TH(IRDB); + DIBasedTypeHierarchy TH(IRDB); LLVMAliasSet PT(&IRDB); LLVMBasedICFG ICFG(&IRDB, CallGraphAnalysisType::CHA, {"main"}, &TH, &PT, Soundness::Soundy, true); @@ -326,7 +325,7 @@ TEST(LLVMBasedICFGTest, GlobalCtorDtor_1) { TEST(LLVMBasedICFGTest, GlobalCtorDtor_2) { LLVMProjectIRDB IRDB(unittest::PathToLLTestFiles + "call_graphs/global_ctor_dtor_2_cpp.ll"); - LLVMTypeHierarchy TH(IRDB); + DIBasedTypeHierarchy TH(IRDB); LLVMAliasSet PT(&IRDB); LLVMBasedICFG ICFG(&IRDB, CallGraphAnalysisType::CHA, {"main"}, &TH, &PT, Soundness::Soundy, true); @@ -350,7 +349,7 @@ TEST(LLVMBasedICFGTest, GlobalCtorDtor_2) { TEST(LLVMBasedICFGTest, GlobalCtorDtor_3) { LLVMProjectIRDB IRDB(unittest::PathToLLTestFiles + "call_graphs/global_ctor_dtor_3_cpp.ll"); - LLVMTypeHierarchy TH(IRDB); + DIBasedTypeHierarchy TH(IRDB); LLVMAliasSet PT(&IRDB); LLVMBasedICFG ICFG(&IRDB, CallGraphAnalysisType::CHA, {"main"}, &TH, &PT, Soundness::Soundy, true); @@ -371,7 +370,7 @@ TEST(LLVMBasedICFGTest, GlobalCtorDtor_3) { TEST(LLVMBasedICFGTest, GlobalCtorDtor_4) { LLVMProjectIRDB IRDB(unittest::PathToLLTestFiles + "call_graphs/global_ctor_dtor_4_cpp.ll"); - LLVMTypeHierarchy TH(IRDB); + DIBasedTypeHierarchy TH(IRDB); LLVMAliasSet PT(&IRDB); LLVMBasedICFG ICFG(&IRDB, CallGraphAnalysisType::CHA, {"main"}, &TH, &PT, Soundness::Soundy, true); diff --git a/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFG_DTATest.cpp b/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFG_DTATest.cpp index 07f5b80b9..73e3aa948 100644 --- a/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFG_DTATest.cpp +++ b/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFG_DTATest.cpp @@ -15,7 +15,7 @@ using namespace psr; TEST(LLVMBasedICFG_DTATest, VirtualCallSite_5) { LLVMProjectIRDB IRDB(unittest::PathToLLTestFiles + "call_graphs/virtual_call_5_cpp.ll"); - LLVMTypeHierarchy TH(IRDB); + DIBasedTypeHierarchy TH(IRDB); LLVMAliasSet PT(&IRDB); LLVMBasedICFG ICFG(&IRDB, CallGraphAnalysisType::DTA, {"main"}, &TH, &PT); const llvm::Function *F = IRDB.getFunctionDefinition("main"); @@ -43,7 +43,7 @@ TEST(LLVMBasedICFG_DTATest, VirtualCallSite_5) { TEST(LLVMBasedICFG_DTATest, VirtualCallSite_6) { LLVMProjectIRDB IRDB(unittest::PathToLLTestFiles + "call_graphs/virtual_call_6_cpp.ll"); - LLVMTypeHierarchy TH(IRDB); + DIBasedTypeHierarchy TH(IRDB); LLVMAliasSet PT(&IRDB); LLVMBasedICFG ICFG(&IRDB, CallGraphAnalysisType::DTA, {"main"}, &TH, &PT); const llvm::Function *F = IRDB.getFunctionDefinition("main"); diff --git a/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFG_OTFTest.cpp b/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFG_OTFTest.cpp index ebe5345d4..43de67881 100644 --- a/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFG_OTFTest.cpp +++ b/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFG_OTFTest.cpp @@ -20,7 +20,7 @@ using namespace psr; TEST(LLVMBasedICFG_OTFTest, VirtualCallSite_7) { LLVMProjectIRDB IRDB(unittest::PathToLLTestFiles + "call_graphs/virtual_call_7_cpp_dbg.ll"); - LLVMTypeHierarchy TH(IRDB); + DIBasedTypeHierarchy TH(IRDB); LLVMAliasSet PT(&IRDB, false); LLVMBasedICFG ICFG(&IRDB, CallGraphAnalysisType::OTF, {"main"}, &TH, &PT); @@ -50,7 +50,7 @@ TEST(LLVMBasedICFG_OTFTest, VirtualCallSite_7) { // TEST(LLVMBasedICFG_OTFTest, VirtualCallSite_8) { // ProjectIRDB IRDB({pathToLLFiles + "call_graphs/virtual_call_8_cpp.ll"}, // IRDBOptions::WPA); -// LLVMTypeHierarchy TH(IRDB); +// DIBasedTypeHierarchy TH(IRDB); // LLVMAliasInfo PT(IRDB); // LLVMBasedICFG ICFG(IRDB, CallGraphAnalysisType::OTF, {"main"}, &TH, &PT); // const llvm::Function *F = IRDB.getFunctionDefinition("main"); @@ -71,7 +71,7 @@ TEST(LLVMBasedICFG_OTFTest, VirtualCallSite_7) { TEST(LLVMBasedICFG_OTFTest, FunctionPtrCall_2) { LLVMProjectIRDB IRDB(unittest::PathToLLTestFiles + "call_graphs/function_pointer_2_cpp.ll"); - LLVMTypeHierarchy TH(IRDB); + DIBasedTypeHierarchy TH(IRDB); LLVMAliasSet PT(&IRDB, false); LLVMBasedICFG ICFG(&IRDB, CallGraphAnalysisType::OTF, {"main"}, &TH, &PT); @@ -109,7 +109,7 @@ TEST(LLVMBasedICFG_OTFTest, FunctionPtrCall_2) { TEST(LLVMBasedICFG_OTFTest, FunctionPtrCall_3) { LLVMProjectIRDB IRDB(unittest::PathToLLTestFiles + "call_graphs/function_pointer_3_cpp.ll"); - LLVMTypeHierarchy TH(IRDB); + DIBasedTypeHierarchy TH(IRDB); LLVMAliasSet PT(&IRDB, false); LLVMBasedICFG ICFG(&IRDB, CallGraphAnalysisType::OTF, {"main"}, &TH, &PT); diff --git a/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFG_RTATest.cpp b/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFG_RTATest.cpp index 7503bca44..c807f5512 100644 --- a/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFG_RTATest.cpp +++ b/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFG_RTATest.cpp @@ -3,7 +3,7 @@ #include "phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h" #include "phasar/PhasarLLVM/DB/LLVMProjectIRDB.h" #include "phasar/PhasarLLVM/Pointer/LLVMAliasSet.h" -#include "phasar/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.h" +#include "phasar/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.h" #include "phasar/PhasarLLVM/Utils/LLVMShorthands.h" #include "TestConfig.h" @@ -15,7 +15,7 @@ using namespace psr; TEST(LLVMBasedICFG_RTATest, VirtualCallSite_9) { LLVMProjectIRDB IRDB(unittest::PathToLLTestFiles + "call_graphs/virtual_call_9_cpp.ll"); - LLVMTypeHierarchy TH(IRDB); + DIBasedTypeHierarchy TH(IRDB); LLVMAliasSet PT(&IRDB); LLVMBasedICFG ICFG(&IRDB, CallGraphAnalysisType::RTA, {"main"}, &TH, &PT); const llvm::Function *F = IRDB.getFunctionDefinition("main"); @@ -41,7 +41,7 @@ TEST(LLVMBasedICFG_RTATest, VirtualCallSite_9) { TEST(LLVMBasedICFG_RTATest, VirtualCallSite_3) { LLVMProjectIRDB IRDB(unittest::PathToLLTestFiles + "call_graphs/virtual_call_3_cpp.ll"); - LLVMTypeHierarchy TH(IRDB); + DIBasedTypeHierarchy TH(IRDB); LLVMAliasSet PT(&IRDB); LLVMBasedICFG ICFG(&IRDB, CallGraphAnalysisType::RTA, {"main"}, &TH, &PT); const llvm::Function *F = IRDB.getFunctionDefinition("main"); @@ -61,7 +61,7 @@ TEST(LLVMBasedICFG_RTATest, VirtualCallSite_3) { TEST(LLVMBasedICFG_RTATest, StaticCallSite_13) { LLVMProjectIRDB IRDB(unittest::PathToLLTestFiles + "call_graphs/static_callsite_13_cpp.ll"); - LLVMTypeHierarchy TH(IRDB); + DIBasedTypeHierarchy TH(IRDB); LLVMAliasSet PT(&IRDB); LLVMBasedICFG ICFG(&IRDB, CallGraphAnalysisType::RTA, {"main"}, &TH, &PT); const llvm::Function *F = IRDB.getFunctionDefinition("main"); diff --git a/unittests/PhasarLLVM/DataFlow/PathSensitivity/PathTracingTest.cpp b/unittests/PhasarLLVM/DataFlow/PathSensitivity/PathTracingTest.cpp index 0194d0eea..262073e92 100644 --- a/unittests/PhasarLLVM/DataFlow/PathSensitivity/PathTracingTest.cpp +++ b/unittests/PhasarLLVM/DataFlow/PathSensitivity/PathTracingTest.cpp @@ -11,7 +11,7 @@ #include "phasar/PhasarLLVM/Passes/ValueAnnotationPass.h" #include "phasar/PhasarLLVM/Pointer/LLVMAliasSet.h" #include "phasar/PhasarLLVM/TaintConfig/LLVMTaintConfig.h" -#include "phasar/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.h" +#include "phasar/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.h" #include "phasar/PhasarLLVM/Utils/LLVMShorthands.h" #include "phasar/Utils/AdjacencyList.h" #include "phasar/Utils/DFAMinimizer.h" @@ -81,7 +81,7 @@ class PathTracingTest : public ::testing::Test { psr::FlowPathSequence doAnalysis(const std::string &LlvmFilePath, bool PrintDump = false) { IRDB = std::make_unique(PathToLlFiles + LlvmFilePath); - psr::LLVMTypeHierarchy TH(*IRDB); + psr::DIBasedTypeHierarchy TH(*IRDB); psr::LLVMAliasSet PT(IRDB.get()); psr::LLVMBasedICFG ICFG(IRDB.get(), psr::CallGraphAnalysisType::OTF, {"main"}, &TH, &PT, psr::Soundness::Soundy, @@ -113,7 +113,7 @@ class PathTracingTest : public ::testing::Test { doLambdaAnalysis(const std::string &LlvmFilePath, size_t MaxDAGDepth = SIZE_MAX) { IRDB = std::make_unique(PathToLlFiles + LlvmFilePath); - psr::LLVMTypeHierarchy TH(*IRDB); + psr::DIBasedTypeHierarchy TH(*IRDB); psr::LLVMAliasSet PT(IRDB.get()); psr::LLVMBasedICFG ICFG(IRDB.get(), psr::CallGraphAnalysisType::OTF, {"main"}, &TH, &PT, psr::Soundness::Soundy, @@ -797,7 +797,7 @@ std::vector> getPaths(const GraphTy &G) { TEST(PathsDAGTest, InLLVMSSA) { psr::LLVMProjectIRDB IRDB(PathTracingTest::PathToLlFiles + "inter_01_cpp.ll"); - psr::LLVMTypeHierarchy TH(IRDB); + psr::DIBasedTypeHierarchy TH(IRDB); psr::LLVMAliasSet PT(&IRDB); psr::LLVMBasedICFG ICFG(&IRDB, psr::CallGraphAnalysisType::OTF, {"main"}, &TH, &PT, psr::Soundness::Soundy, diff --git a/unittests/PhasarLLVM/Pointer/LLVMAliasSetTest.cpp b/unittests/PhasarLLVM/Pointer/LLVMAliasSetTest.cpp index b6144d68b..74a242dec 100644 --- a/unittests/PhasarLLVM/Pointer/LLVMAliasSetTest.cpp +++ b/unittests/PhasarLLVM/Pointer/LLVMAliasSetTest.cpp @@ -5,7 +5,7 @@ #include "phasar/PhasarLLVM/DB/LLVMProjectIRDB.h" #include "phasar/PhasarLLVM/Passes/ValueAnnotationPass.h" #include "phasar/PhasarLLVM/Pointer/LLVMPointsToUtils.h" -#include "phasar/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.h" +#include "phasar/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.h" #include "TestConfig.h" #include "gtest/gtest.h" @@ -32,7 +32,7 @@ TEST(LLVMAliasSet, Inter_01) { ValueAnnotationPass::resetValueID(); LLVMProjectIRDB IRDB(unittest::PathToLLTestFiles + "pointers/call_01_cpp.ll"); LLVMAliasSet PTS(&IRDB, false); - LLVMTypeHierarchy TH(IRDB); + DIBasedTypeHierarchy TH(IRDB); LLVMBasedICFG ICF(&IRDB, CallGraphAnalysisType::OTF, {"main"}, &TH, &PTS); const auto *Main = IRDB.getFunctionDefinition("main"); for (const auto &BB : *Main) { @@ -49,7 +49,7 @@ TEST(LLVMAliasSet, Global_01) { LLVMProjectIRDB IRDB(unittest::PathToLLTestFiles + "pointers/global_01_cpp.ll"); LLVMAliasSet PTS(&IRDB, false); - LLVMTypeHierarchy TH(IRDB); + DIBasedTypeHierarchy TH(IRDB); LLVMBasedICFG ICF(&IRDB, CallGraphAnalysisType::OTF, {"main"}, &TH, &PTS); const auto *Main = IRDB.getFunctionDefinition("main"); for (const auto &G : Main->getParent()->globals()) { From 0b7575e1690d987044defdd4249c7412a52522db Mon Sep 17 00:00:00 2001 From: mxHuber Date: Sun, 23 Jun 2024 19:26:02 +0200 Subject: [PATCH 31/78] full switch to DIBasedTypeHierarchy + Test fixes --- .../ControlFlow/LLVMVFTableProvider.h | 3 +- .../ControlFlow/Resolver/OTFResolver.h | 2 +- .../ControlFlow/Resolver/Resolver.h | 10 ++- .../InterMonoFullConstantPropagation.h | 4 +- .../Mono/Problems/InterMonoTaintAnalysis.h | 7 +- .../IntraMonoFullConstantPropagation.h | 4 +- .../Mono/Problems/IntraMonoUninitVariables.h | 6 +- .../PhasarLLVM/Domain/LLVMAnalysisDomain.h | 4 +- .../PhasarLLVM/SimpleAnalysisConstructor.h | 6 +- .../TypeHierarchy/DIBasedTypeHierarchy.h | 9 ++ .../ControlFlow/LLVMVFTableProvider.cpp | 73 +++++++++++++--- .../ControlFlow/Resolver/DTAResolver.cpp | 17 ++-- .../ControlFlow/Resolver/OTFResolver.cpp | 6 +- .../ControlFlow/Resolver/RTAResolver.cpp | 17 ++-- .../ControlFlow/Resolver/Resolver.cpp | 85 +++++++++++++++---- .../InterMonoFullConstantPropagation.cpp | 4 +- .../Mono/Problems/InterMonoTaintAnalysis.cpp | 4 +- .../IntraMonoFullConstantPropagation.cpp | 4 +- .../Mono/Problems/IntraMonoSolverTest.cpp | 4 +- .../Problems/IntraMonoUninitVariables.cpp | 4 +- .../TypeHierarchy/DIBasedTypeHierarchy.cpp | 32 +++++++ lib/PhasarLLVM/Utils/LLVMIRToSrc.cpp | 2 +- .../ControlFlow/LLVMBasedICFG_CHATest.cpp | 10 +-- .../ControlFlow/LLVMBasedICFG_OTFTest.cpp | 4 +- .../ControlFlow/LLVMVFTableProviderTest.cpp | 27 +++--- .../Pointer/LLVMAliasSetSerializationTest.cpp | 4 +- unittests/Utils/LLVMIRToSrcTest.cpp | 6 +- 27 files changed, 255 insertions(+), 103 deletions(-) diff --git a/include/phasar/PhasarLLVM/ControlFlow/LLVMVFTableProvider.h b/include/phasar/PhasarLLVM/ControlFlow/LLVMVFTableProvider.h index 126251da8..d27fe4b3a 100644 --- a/include/phasar/PhasarLLVM/ControlFlow/LLVMVFTableProvider.h +++ b/include/phasar/PhasarLLVM/ControlFlow/LLVMVFTableProvider.h @@ -37,7 +37,8 @@ class LLVMVFTableProvider { private: std::unordered_map TypeVFTMap; - std::map DITypeToStructType; + std::unordered_map DITypeVFTMap; + std::map DITypeToType; }; } // namespace psr diff --git a/include/phasar/PhasarLLVM/ControlFlow/Resolver/OTFResolver.h b/include/phasar/PhasarLLVM/ControlFlow/Resolver/OTFResolver.h index e278cf786..24f5a0f0d 100644 --- a/include/phasar/PhasarLLVM/ControlFlow/Resolver/OTFResolver.h +++ b/include/phasar/PhasarLLVM/ControlFlow/Resolver/OTFResolver.h @@ -35,7 +35,7 @@ class Value; namespace psr { -class LLVMTypeHierarchy; +class DIBasedTypeHierarchy; class OTFResolver : public Resolver { protected: diff --git a/include/phasar/PhasarLLVM/ControlFlow/Resolver/Resolver.h b/include/phasar/PhasarLLVM/ControlFlow/Resolver/Resolver.h index d2e311daa..9992c8167 100644 --- a/include/phasar/PhasarLLVM/ControlFlow/Resolver/Resolver.h +++ b/include/phasar/PhasarLLVM/ControlFlow/Resolver/Resolver.h @@ -45,6 +45,9 @@ getVFTIndex(const llvm::CallBase *CallSite); [[nodiscard]] const llvm::DIType * getReceiverType(const llvm::CallBase *CallSite); +[[nodiscard]] const llvm::StructType * +getReceiverStructType(const llvm::CallBase *CallSite); + [[nodiscard]] std::string getReceiverTypeName(const llvm::CallBase *CallSite); [[nodiscard]] bool isConsistentCall(const llvm::CallBase *CallSite, @@ -54,7 +57,8 @@ class Resolver { protected: const LLVMProjectIRDB *IRDB; const LLVMVFTableProvider *VTP; - std::map DITypeToStructType; + std::map DITypeToType; + std::map TypeToDIType; Resolver(const LLVMProjectIRDB *IRDB); void initializeTypeMap(); @@ -63,6 +67,10 @@ class Resolver { getNonPureVirtualVFTEntry(const llvm::DIType *T, unsigned Idx, const llvm::CallBase *CallSite); + const llvm::Function * + getNonPureVirtualVFTEntry(const llvm::StructType *T, unsigned Idx, + const llvm::CallBase *CallSite); + public: using FunctionSetTy = llvm::SmallDenseSet; diff --git a/include/phasar/PhasarLLVM/DataFlow/Mono/Problems/InterMonoFullConstantPropagation.h b/include/phasar/PhasarLLVM/DataFlow/Mono/Problems/InterMonoFullConstantPropagation.h index df91bce7d..d1e1ffce7 100644 --- a/include/phasar/PhasarLLVM/DataFlow/Mono/Problems/InterMonoFullConstantPropagation.h +++ b/include/phasar/PhasarLLVM/DataFlow/Mono/Problems/InterMonoFullConstantPropagation.h @@ -32,7 +32,7 @@ class StructType; namespace psr { class LLVMBasedICFG; -class LLVMTypeHierarchy; +class DIBasedTypeHierarchy; class InterMonoFullConstantPropagation : public IntraMonoFullConstantPropagation, @@ -48,7 +48,7 @@ class InterMonoFullConstantPropagation using mono_container_t = IntraMonoFullConstantPropagation::mono_container_t; InterMonoFullConstantPropagation(const LLVMProjectIRDB *IRDB, - const LLVMTypeHierarchy *TH, + const DIBasedTypeHierarchy *TH, const LLVMBasedICFG *ICF, LLVMAliasInfoRef PT, std::vector EntryPoints = {}); diff --git a/include/phasar/PhasarLLVM/DataFlow/Mono/Problems/InterMonoTaintAnalysis.h b/include/phasar/PhasarLLVM/DataFlow/Mono/Problems/InterMonoTaintAnalysis.h index 211de3a91..7a78746ec 100644 --- a/include/phasar/PhasarLLVM/DataFlow/Mono/Problems/InterMonoTaintAnalysis.h +++ b/include/phasar/PhasarLLVM/DataFlow/Mono/Problems/InterMonoTaintAnalysis.h @@ -37,7 +37,7 @@ class StructType; namespace psr { -class LLVMTypeHierarchy; +class DIBasedTypeHierarchy; struct InterMonoTaintAnalysisDomain : LLVMAnalysisDomainDefault { using mono_container_t = BitVectorSet; @@ -56,8 +56,9 @@ class InterMonoTaintAnalysis using ConfigurationTy = LLVMTaintConfig; InterMonoTaintAnalysis(const LLVMProjectIRDB *IRDB, - const LLVMTypeHierarchy *TH, const LLVMBasedICFG *ICF, - LLVMAliasInfoRef PT, const LLVMTaintConfig &Config, + const DIBasedTypeHierarchy *TH, + const LLVMBasedICFG *ICF, LLVMAliasInfoRef PT, + const LLVMTaintConfig &Config, std::vector EntryPoints = {}); ~InterMonoTaintAnalysis() override = default; diff --git a/include/phasar/PhasarLLVM/DataFlow/Mono/Problems/IntraMonoFullConstantPropagation.h b/include/phasar/PhasarLLVM/DataFlow/Mono/Problems/IntraMonoFullConstantPropagation.h index 010e2f517..0bebfc4e6 100644 --- a/include/phasar/PhasarLLVM/DataFlow/Mono/Problems/IntraMonoFullConstantPropagation.h +++ b/include/phasar/PhasarLLVM/DataFlow/Mono/Problems/IntraMonoFullConstantPropagation.h @@ -42,7 +42,7 @@ namespace psr { class LLVMBasedCFG; class LLVMBasedICFG; -class LLVMTypeHierarchy; +class DIBasedTypeHierarchy; class InterMonoFullConstantPropagation; struct IntraMonoFCAFact { @@ -81,7 +81,7 @@ class IntraMonoFullConstantPropagation public: IntraMonoFullConstantPropagation(const LLVMProjectIRDB *IRDB, - const LLVMTypeHierarchy *TH, + const DIBasedTypeHierarchy *TH, const LLVMBasedCFG *CF, LLVMAliasInfoRef PT, std::vector EntryPoints = {}); diff --git a/include/phasar/PhasarLLVM/DataFlow/Mono/Problems/IntraMonoUninitVariables.h b/include/phasar/PhasarLLVM/DataFlow/Mono/Problems/IntraMonoUninitVariables.h index e813e38d3..b08b91179 100644 --- a/include/phasar/PhasarLLVM/DataFlow/Mono/Problems/IntraMonoUninitVariables.h +++ b/include/phasar/PhasarLLVM/DataFlow/Mono/Problems/IntraMonoUninitVariables.h @@ -28,7 +28,7 @@ class StructType; namespace psr { -class LLVMTypeHierarchy; +class DIBasedTypeHierarchy; class LLVMBasedCFG; class LLVMBasedICFG; @@ -48,8 +48,8 @@ class IntraMonoUninitVariables using mono_container_t = IntraMonoUninitVariablesDomain::mono_container_t; IntraMonoUninitVariables(const LLVMProjectIRDB *IRDB, - const LLVMTypeHierarchy *TH, const LLVMBasedCFG *CF, - LLVMAliasInfoRef PT, + const DIBasedTypeHierarchy *TH, + const LLVMBasedCFG *CF, LLVMAliasInfoRef PT, std::vector EntryPoints = {}); ~IntraMonoUninitVariables() override = default; diff --git a/include/phasar/PhasarLLVM/Domain/LLVMAnalysisDomain.h b/include/phasar/PhasarLLVM/Domain/LLVMAnalysisDomain.h index 11490fe20..3fd7fd584 100644 --- a/include/phasar/PhasarLLVM/Domain/LLVMAnalysisDomain.h +++ b/include/phasar/PhasarLLVM/Domain/LLVMAnalysisDomain.h @@ -12,6 +12,8 @@ #include "phasar/Domain/AnalysisDomain.h" +#include "llvm/IR/DebugInfoMetadata.h" + namespace llvm { class Value; class Instruction; @@ -28,7 +30,7 @@ struct LLVMAnalysisDomainDefault : public AnalysisDomain { using d_t = const llvm::Value *; using n_t = const llvm::Instruction *; using f_t = const llvm::Function *; - using t_t = const llvm::StructType *; + using t_t = const llvm::DIType *; using v_t = const llvm::Value *; using c_t = LLVMBasedCFG; using i_t = LLVMBasedICFG; diff --git a/include/phasar/PhasarLLVM/SimpleAnalysisConstructor.h b/include/phasar/PhasarLLVM/SimpleAnalysisConstructor.h index fce91ea9c..e6e80094a 100644 --- a/include/phasar/PhasarLLVM/SimpleAnalysisConstructor.h +++ b/include/phasar/PhasarLLVM/SimpleAnalysisConstructor.h @@ -19,7 +19,7 @@ namespace psr { class LLVMProjectIRDB; class LLVMAliasSet; class LLVMBasedICFG; -class LLVMTypeHierarchy; +class DIBasedTypeHierarchy; template ProblemTy createAnalysisProblem(HelperAnalyses &HA, ArgTys &&...Args) { @@ -46,13 +46,13 @@ ProblemTy createAnalysisProblem(HelperAnalyses &HA, ArgTys &&...Args) { std::forward(Args)...); } else if constexpr (std::is_constructible_v< ProblemTy, const LLVMProjectIRDB *, - const LLVMTypeHierarchy *, const LLVMBasedCFG *, + const DIBasedTypeHierarchy *, const LLVMBasedCFG *, LLVMAliasSet *, ArgTys...>) { return ProblemTy(&HA.getProjectIRDB(), &HA.getTypeHierarchy(), &HA.getCFG(), &HA.getAliasInfo(), std::forward(Args)...); } else if constexpr (std::is_constructible_v< ProblemTy, const LLVMProjectIRDB *, - const LLVMTypeHierarchy *, const LLVMBasedICFG *, + const DIBasedTypeHierarchy *, const LLVMBasedICFG *, LLVMAliasSet *, ArgTys...>) { return ProblemTy(&HA.getProjectIRDB(), &HA.getTypeHierarchy(), &HA.getICFG(), &HA.getAliasInfo(), diff --git a/include/phasar/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.h b/include/phasar/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.h index 34b194350..9bb317803 100644 --- a/include/phasar/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.h +++ b/include/phasar/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.h @@ -31,12 +31,21 @@ class DIBasedTypeHierarchy using ClassType = const llvm::DIType *; using f_t = const llvm::Function *; + static inline constexpr llvm::StringLiteral StructPrefix = "struct."; + static inline constexpr llvm::StringLiteral ClassPrefix = "class."; + static inline constexpr llvm::StringLiteral VTablePrefix = "_ZTV"; + static inline constexpr llvm::StringLiteral VTablePrefixDemang = + "vtable for "; static inline constexpr llvm::StringLiteral PureVirtualCallName = "__cxa_pure_virtual"; explicit DIBasedTypeHierarchy(const LLVMProjectIRDB &IRDB); ~DIBasedTypeHierarchy() override = default; + static bool isVTable(llvm::StringRef VarName); + static std::string removeStructOrClassPrefix(llvm::StringRef TypeName); + static std::string removeVTablePrefix(llvm::StringRef VarName); + [[nodiscard]] bool hasType(ClassType Type) const override { return TypeToVertex.count(Type); } diff --git a/lib/PhasarLLVM/ControlFlow/LLVMVFTableProvider.cpp b/lib/PhasarLLVM/ControlFlow/LLVMVFTableProvider.cpp index 0c4f20143..afad9c05d 100644 --- a/lib/PhasarLLVM/ControlFlow/LLVMVFTableProvider.cpp +++ b/lib/PhasarLLVM/ControlFlow/LLVMVFTableProvider.cpp @@ -1,13 +1,14 @@ #include "phasar/PhasarLLVM/ControlFlow/LLVMVFTableProvider.h" #include "phasar/PhasarLLVM/DB/LLVMProjectIRDB.h" -#include "phasar/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.h" +#include "phasar/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.h" #include "phasar/PhasarLLVM/TypeHierarchy/LLVMVFTable.h" #include "phasar/PhasarLLVM/Utils/LLVMIRToSrc.h" #include "phasar/Utils/Logger.h" #include "llvm/Demangle/Demangle.h" #include "llvm/IR/Constants.h" +#include "llvm/IR/DebugInfoMetadata.h" #include "llvm/IR/Module.h" #include "llvm/Support/Casting.h" @@ -16,14 +17,39 @@ using namespace psr; static std::vector getVirtualFunctions( const llvm::StringMap &ClearNameTVMap, const llvm::StructType &Type) { - auto ClearName = LLVMTypeHierarchy::removeStructOrClassPrefix(Type.getName()); + auto ClearName = + DIBasedTypeHierarchy::removeStructOrClassPrefix(Type.getName()); auto It = ClearNameTVMap.find(ClearName); if (It != ClearNameTVMap.end()) { if (const auto *TI = llvm::dyn_cast(It->second)) { if (!TI->hasInitializer()) { - PHASAR_LOG_LEVEL_CAT(DEBUG, "LLVMTypeHierarchy", + PHASAR_LOG_LEVEL_CAT(DEBUG, "DIBasedTypeHierarchy", + ClearName << " does not have initializer"); + return {}; + } + if (const auto *I = + llvm::dyn_cast(TI->getInitializer())) { + return LLVMVFTable::getVFVectorFromIRVTable(*I); + } + } + } + return {}; +} + +static std::vector getVirtualFunctionsDIBased( + const llvm::StringMap &ClearNameTVMap, + const llvm::DIType &Type) { + auto ClearName = + DIBasedTypeHierarchy::removeStructOrClassPrefix(Type.getName()); + + auto It = ClearNameTVMap.find(ClearName); + + if (It != ClearNameTVMap.end()) { + if (const auto *TI = llvm::dyn_cast(It->second)) { + if (!TI->hasInitializer()) { + PHASAR_LOG_LEVEL_CAT(DEBUG, "DIBasedTypeHierarchy", ClearName << " does not have initializer"); return {}; } @@ -38,12 +64,13 @@ static std::vector getVirtualFunctions( LLVMVFTableProvider::LLVMVFTableProvider(const llvm::Module &Mod) { auto StructTypes = Mod.getIdentifiedStructTypes(); + llvm::StringMap ClearNameTVMap; for (const auto &Glob : Mod.globals()) { - if (LLVMTypeHierarchy::isVTable(Glob.getName())) { + if (DIBasedTypeHierarchy::isVTable(Glob.getName())) { auto Demang = llvm::demangle(Glob.getName().str()); - auto ClearName = LLVMTypeHierarchy::removeVTablePrefix(Demang); + auto ClearName = DIBasedTypeHierarchy::removeVTablePrefix(Demang); ClearNameTVMap.try_emplace(ClearName, &Glob); } } @@ -51,24 +78,44 @@ LLVMVFTableProvider::LLVMVFTableProvider(const llvm::Module &Mod) { for (const auto *Ty : StructTypes) { TypeVFTMap.try_emplace(Ty, getVirtualFunctions(ClearNameTVMap, *Ty)); } +} - for (const auto *StructTy : StructTypes) { - if (const auto *Val = llvm::dyn_cast(StructTy)) { - const auto *DILocalVar = getDILocalVariable(Val); - DITypeToStructType[DILocalVar->getType()] = StructTy; +LLVMVFTableProvider::LLVMVFTableProvider(const LLVMProjectIRDB &IRDB) + : LLVMVFTableProvider(*IRDB.getModule()) { + for (const auto *Instr : IRDB.getAllInstructions()) { + if (const auto *Val = llvm::dyn_cast(Instr)) { + if (const auto *DILocalVar = getDILocalVariable(Val)) { + if (const auto *DerivedTy = + llvm::dyn_cast(DILocalVar->getType())) { + DITypeToType[DerivedTy->getBaseType()] = Val->getType(); + continue; + } + DITypeToType[DILocalVar->getType()] = Val->getType(); + } } } -} + llvm::StringMap ClearNameTVMap; -LLVMVFTableProvider::LLVMVFTableProvider(const LLVMProjectIRDB &IRDB) - : LLVMVFTableProvider(*IRDB.getModule()) {} + for (const auto &Glob : IRDB.getModule()->globals()) { + if (DIBasedTypeHierarchy::isVTable(Glob.getName())) { + auto Demang = llvm::demangle(Glob.getName().str()); + auto ClearName = DIBasedTypeHierarchy::removeVTablePrefix(Demang); + ClearNameTVMap.try_emplace(ClearName, &Glob); + } + } + + for (const auto &Elem : DITypeToType) { + DITypeVFTMap.try_emplace( + Elem.first, getVirtualFunctionsDIBased(ClearNameTVMap, *Elem.first)); + } +} bool LLVMVFTableProvider::hasVFTable(const llvm::StructType *Type) const { return TypeVFTMap.count(Type); } bool LLVMVFTableProvider::hasVFTable(const llvm::DIType *Type) const { - return DITypeToStructType.count(Type); + return DITypeToType.count(Type); } const LLVMVFTable * diff --git a/lib/PhasarLLVM/ControlFlow/Resolver/DTAResolver.cpp b/lib/PhasarLLVM/ControlFlow/Resolver/DTAResolver.cpp index adfc97934..002c1211f 100644 --- a/lib/PhasarLLVM/ControlFlow/Resolver/DTAResolver.cpp +++ b/lib/PhasarLLVM/ControlFlow/Resolver/DTAResolver.cpp @@ -188,9 +188,9 @@ auto DTAResolver::resolveVirtualCall(const llvm::CallBase *CallSite) PHASAR_LOG_LEVEL(DEBUG, "Virtual function table entry is: " << VtableIndex); - const auto *ReceiverType = getReceiverType(CallSite); + const auto *ReceiverType = getReceiverStructType(CallSite); - auto PossibleTypes = TypeGraph.getTypes(DITypeToStructType[ReceiverType]); + auto PossibleTypes = TypeGraph.getTypes(ReceiverType); // WARNING We deactivated the check on allocated because it is // unabled to get the types allocated in the used libraries @@ -200,15 +200,10 @@ auto DTAResolver::resolveVirtualCall(const llvm::CallBase *CallSite) if (const auto *PossibleTypeStruct = llvm::dyn_cast(PossibleType)) { // if ( allocated_types.find(possible_type_struct) != end_it ) { - if (const auto *Val = llvm::dyn_cast(PossibleTypeStruct)) { - if (const auto *DITy = - llvm::dyn_cast(getDILocalVariable(Val))) { - const auto *Target = - getNonPureVirtualVFTEntry(DITy, VtableIndex, CallSite); - if (Target) { - PossibleCallTargets.insert(Target); - } - } + const auto *Target = + getNonPureVirtualVFTEntry(PossibleTypeStruct, VtableIndex, CallSite); + if (Target) { + PossibleCallTargets.insert(Target); } } } diff --git a/lib/PhasarLLVM/ControlFlow/Resolver/OTFResolver.cpp b/lib/PhasarLLVM/ControlFlow/Resolver/OTFResolver.cpp index c1f783d54..be2dbe913 100644 --- a/lib/PhasarLLVM/ControlFlow/Resolver/OTFResolver.cpp +++ b/lib/PhasarLLVM/ControlFlow/Resolver/OTFResolver.cpp @@ -11,7 +11,7 @@ #include "phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h" #include "phasar/PhasarLLVM/ControlFlow/Resolver/Resolver.h" -#include "phasar/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.h" +#include "phasar/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.h" #include "phasar/PhasarLLVM/Utils/LLVMShorthands.h" #include "phasar/Utils/Logger.h" #include "phasar/Utils/Utilities.h" @@ -94,7 +94,7 @@ auto OTFResolver::resolveVirtualCall(const llvm::CallBase *CallSite) for (const auto *P : *PTS) { if (const auto *PGV = llvm::dyn_cast(P)) { if (PGV->hasName() && - PGV->getName().startswith(LLVMTypeHierarchy::VTablePrefix) && + PGV->getName().startswith(DIBasedTypeHierarchy::VTablePrefix) && PGV->hasInitializer()) { if (const auto *PCS = llvm::dyn_cast(PGV->getInitializer())) { @@ -104,7 +104,7 @@ auto OTFResolver::resolveVirtualCall(const llvm::CallBase *CallSite) } const auto *Callee = VFs[VtableIndex]; if (Callee == nullptr || !Callee->hasName() || - Callee->getName() == LLVMTypeHierarchy::PureVirtualCallName || + Callee->getName() == DIBasedTypeHierarchy::PureVirtualCallName || !isConsistentCall(CallSite, Callee)) { continue; } diff --git a/lib/PhasarLLVM/ControlFlow/Resolver/RTAResolver.cpp b/lib/PhasarLLVM/ControlFlow/Resolver/RTAResolver.cpp index 1cd9cad40..12120ac62 100644 --- a/lib/PhasarLLVM/ControlFlow/Resolver/RTAResolver.cpp +++ b/lib/PhasarLLVM/ControlFlow/Resolver/RTAResolver.cpp @@ -18,7 +18,6 @@ #include "phasar/PhasarLLVM/DB/LLVMProjectIRDB.h" #include "phasar/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.h" -#include "phasar/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.h" #include "phasar/PhasarLLVM/Utils/LLVMIRToSrc.h" #include "phasar/PhasarLLVM/Utils/LLVMShorthands.h" #include "phasar/Utils/Logger.h" @@ -72,20 +71,16 @@ auto RTAResolver::resolveVirtualCall(const llvm::CallBase *CallSite) auto ReachableTypes = TH->getSubTypes(ReceiverType); // also insert all possible subtypes vtable entries - auto EndIt = ReachableTypes.end(); for (const auto *PossibleType : AllocatedStructTypes) { if (const auto *PossibleTypeStruct = llvm::dyn_cast(PossibleType)) { - if (const auto *Val = llvm::dyn_cast(PossibleTypeStruct)) { - if (const auto *DITy = - llvm::dyn_cast(getDILocalVariable(Val))) { - if (ReachableTypes.find(DITy) != EndIt) { - const auto *Target = - getNonPureVirtualVFTEntry(DITy, VtableIndex, CallSite); - if (Target) { - PossibleCallTargets.insert(Target); - } + if (const auto *Ty = llvm::dyn_cast(PossibleTypeStruct)) { + if (ReachableTypes.find(TypeToDIType[Ty]) != EndIt) { + const auto *Target = getNonPureVirtualVFTEntry(TypeToDIType[Ty], + VtableIndex, CallSite); + if (Target) { + PossibleCallTargets.insert(Target); } } } diff --git a/lib/PhasarLLVM/ControlFlow/Resolver/Resolver.cpp b/lib/PhasarLLVM/ControlFlow/Resolver/Resolver.cpp index 03bff4eca..a38bdff34 100644 --- a/lib/PhasarLLVM/ControlFlow/Resolver/Resolver.cpp +++ b/lib/PhasarLLVM/ControlFlow/Resolver/Resolver.cpp @@ -75,25 +75,64 @@ const llvm::DIType *psr::getReceiverType(const llvm::CallBase *CallSite) { return nullptr; } - if (Receiver->getType()->isOpaquePointerTy()) { - if (const auto *Load = llvm::dyn_cast(Receiver)) { - if (const auto *DerivedTy = llvm::dyn_cast( - getDILocalVariable(Load->getPointerOperand())->getType())) { + if (const auto *Load = llvm::dyn_cast(Receiver)) { + if (const auto *DITy = getDILocalVariable(Load->getPointerOperand())) { + if (const auto *DerivedTy = + llvm::dyn_cast(DITy->getType())) { return DerivedTy->getBaseType(); } } } - - if (!Receiver->getType()->isOpaquePointerTy()) { - if (const auto *ReceiverTy = llvm::dyn_cast( - Receiver->getType()->getNonOpaquePointerElementType())) { - if (const auto *ValueTy = llvm::dyn_cast(ReceiverTy)) { + /* + if (Receiver->getType()->isOpaquePointerTy()) { + if (const auto *Load = llvm::dyn_cast(Receiver)) { if (const auto *DerivedTy = llvm::dyn_cast( - getDILocalVariable(ValueTy))) { + getDILocalVariable(Load->getPointerOperand())->getType())) { return DerivedTy->getBaseType(); } } } + + if (!Receiver->getType()->isOpaquePointerTy()) { + if (const auto *ReceiverTy = llvm::dyn_cast( + Receiver->getType()->getNonOpaquePointerElementType())) { + if (const auto *ValueTy = llvm::dyn_cast(ReceiverTy)) { + if (const auto *DerivedTy = llvm::dyn_cast( + getDILocalVariable(TypeToDIType[ValueTy]))) { + return DerivedTy->getBaseType(); + } + } + } + } +*/ + return nullptr; +} + +const llvm::StructType * +psr::getReceiverStructType(const llvm::CallBase *CallSite) { + if (CallSite->arg_empty() || + (CallSite->hasStructRetAttr() && CallSite->arg_size() < 2)) { + return nullptr; + } + + const auto *Receiver = + CallSite->getArgOperand(unsigned(CallSite->hasStructRetAttr())); + + if (!Receiver->getType()->isPointerTy()) { + return nullptr; + } + + if (Receiver->getType()->isOpaquePointerTy()) { + llvm::errs() << "WARNING: The IR under analysis uses opaque pointers, " + "which are not supported by phasar yet!\n"; + return nullptr; + } + + if (!Receiver->getType()->isOpaquePointerTy()) { + if (const auto *ReceiverTy = llvm::dyn_cast( + Receiver->getType()->getNonOpaquePointerElementType())) { + return ReceiverTy; + } } return nullptr; @@ -141,7 +180,7 @@ Resolver::getNonPureVirtualVFTEntry(const llvm::DIType *T, unsigned Idx, } if (const auto *StructTy = - llvm::dyn_cast(DITypeToStructType[T])) { + llvm::dyn_cast(DITypeToType[T])) { if (const auto *VT = VTP->getVFTableOrNull(StructTy)) { const auto *Target = VT->getFunction(Idx); if (Target && @@ -155,6 +194,23 @@ Resolver::getNonPureVirtualVFTEntry(const llvm::DIType *T, unsigned Idx, return nullptr; } +const llvm::Function * +Resolver::getNonPureVirtualVFTEntry(const llvm::StructType *T, unsigned Idx, + const llvm::CallBase *CallSite) { + if (!VTP) { + return nullptr; + } + if (const auto *VT = VTP->getVFTableOrNull(T)) { + const auto *Target = VT->getFunction(Idx); + if (Target && + Target->getName() != DIBasedTypeHierarchy::PureVirtualCallName && + isConsistentCall(CallSite, Target)) { + return Target; + } + } + return nullptr; +} + void Resolver::preCall(const llvm::Instruction *Inst) {} void Resolver::handlePossibleTargets(const llvm::CallBase *CallSite, @@ -219,10 +275,9 @@ std::unique_ptr Resolver::create(CallGraphAnalysisType Ty, void Resolver::initializeTypeMap() { for (const auto *Instr : IRDB->getAllInstructions()) { if (const auto *Val = llvm::dyn_cast(Instr)) { - const auto *DILocalVar = getDILocalVariable(Val); - if (const auto *StructTy = - llvm::dyn_cast(Val->getType())) { - DITypeToStructType[DILocalVar->getType()] = StructTy; + if (const auto *DITy = getDILocalVariable(Val)) { + DITypeToType[DITy->getType()] = Val->getType(); + TypeToDIType[Val->getType()] = DITy->getType(); } } } diff --git a/lib/PhasarLLVM/DataFlow/Mono/Problems/InterMonoFullConstantPropagation.cpp b/lib/PhasarLLVM/DataFlow/Mono/Problems/InterMonoFullConstantPropagation.cpp index b2c2365b9..8f5630d23 100644 --- a/lib/PhasarLLVM/DataFlow/Mono/Problems/InterMonoFullConstantPropagation.cpp +++ b/lib/PhasarLLVM/DataFlow/Mono/Problems/InterMonoFullConstantPropagation.cpp @@ -12,7 +12,7 @@ #include "phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h" #include "phasar/PhasarLLVM/DB/LLVMProjectIRDB.h" #include "phasar/PhasarLLVM/Pointer/LLVMAliasInfo.h" -#include "phasar/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.h" +#include "phasar/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.h" #include "phasar/PhasarLLVM/Utils/LLVMShorthands.h" #include "phasar/Utils/BitVectorSet.h" @@ -34,7 +34,7 @@ using namespace psr; namespace psr { InterMonoFullConstantPropagation::InterMonoFullConstantPropagation( - const LLVMProjectIRDB *IRDB, const LLVMTypeHierarchy *TH, + const LLVMProjectIRDB *IRDB, const DIBasedTypeHierarchy *TH, const LLVMBasedICFG *ICF, LLVMAliasInfoRef PT, std::vector EntryPoints) : IntraMonoFullConstantPropagation(IRDB, TH, ICF, PT, diff --git a/lib/PhasarLLVM/DataFlow/Mono/Problems/InterMonoTaintAnalysis.cpp b/lib/PhasarLLVM/DataFlow/Mono/Problems/InterMonoTaintAnalysis.cpp index 04830d72c..2d552d64c 100644 --- a/lib/PhasarLLVM/DataFlow/Mono/Problems/InterMonoTaintAnalysis.cpp +++ b/lib/PhasarLLVM/DataFlow/Mono/Problems/InterMonoTaintAnalysis.cpp @@ -13,7 +13,7 @@ #include "phasar/PhasarLLVM/DB/LLVMProjectIRDB.h" #include "phasar/PhasarLLVM/Pointer/LLVMAliasInfo.h" #include "phasar/PhasarLLVM/TaintConfig/TaintConfigUtilities.h" -#include "phasar/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.h" +#include "phasar/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.h" #include "phasar/PhasarLLVM/Utils/LLVMShorthands.h" #include "phasar/Utils/BitVectorSet.h" #include "phasar/Utils/Logger.h" @@ -31,7 +31,7 @@ namespace psr { InterMonoTaintAnalysis::InterMonoTaintAnalysis( - const LLVMProjectIRDB *IRDB, const LLVMTypeHierarchy *TH, + const LLVMProjectIRDB *IRDB, const DIBasedTypeHierarchy *TH, const LLVMBasedICFG *ICF, LLVMAliasInfoRef PT, const LLVMTaintConfig &Config, std::vector EntryPoints) : InterMonoProblem(IRDB, TH, ICF, PT, diff --git a/lib/PhasarLLVM/DataFlow/Mono/Problems/IntraMonoFullConstantPropagation.cpp b/lib/PhasarLLVM/DataFlow/Mono/Problems/IntraMonoFullConstantPropagation.cpp index 41aeb91a4..ca659b551 100644 --- a/lib/PhasarLLVM/DataFlow/Mono/Problems/IntraMonoFullConstantPropagation.cpp +++ b/lib/PhasarLLVM/DataFlow/Mono/Problems/IntraMonoFullConstantPropagation.cpp @@ -13,7 +13,7 @@ #include "phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h" #include "phasar/PhasarLLVM/DB/LLVMProjectIRDB.h" #include "phasar/PhasarLLVM/Pointer/LLVMAliasInfo.h" -#include "phasar/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.h" +#include "phasar/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.h" #include "phasar/PhasarLLVM/Utils/LLVMShorthands.h" #include "phasar/Utils/BitVectorSet.h" @@ -43,7 +43,7 @@ using namespace psr; namespace psr { IntraMonoFullConstantPropagation::IntraMonoFullConstantPropagation( - const LLVMProjectIRDB *IRDB, const LLVMTypeHierarchy *TH, + const LLVMProjectIRDB *IRDB, const DIBasedTypeHierarchy *TH, const LLVMBasedCFG *CF, LLVMAliasInfoRef PT, std::vector EntryPoints) : IntraMonoProblem( diff --git a/lib/PhasarLLVM/DataFlow/Mono/Problems/IntraMonoSolverTest.cpp b/lib/PhasarLLVM/DataFlow/Mono/Problems/IntraMonoSolverTest.cpp index dc0a9782d..8d59c0683 100644 --- a/lib/PhasarLLVM/DataFlow/Mono/Problems/IntraMonoSolverTest.cpp +++ b/lib/PhasarLLVM/DataFlow/Mono/Problems/IntraMonoSolverTest.cpp @@ -19,7 +19,7 @@ #include "phasar/PhasarLLVM/ControlFlow/LLVMBasedCFG.h" #include "phasar/PhasarLLVM/DB/LLVMProjectIRDB.h" #include "phasar/PhasarLLVM/Pointer/LLVMAliasInfo.h" -#include "phasar/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.h" +#include "phasar/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.h" #include "phasar/PhasarLLVM/Utils/LLVMShorthands.h" #include "llvm/IR/Instruction.h" @@ -34,7 +34,7 @@ using namespace psr; namespace psr { IntraMonoSolverTest::IntraMonoSolverTest(const LLVMProjectIRDB *IRDB, - const LLVMTypeHierarchy *TH, + const DIBasedTypeHierarchy *TH, const LLVMBasedCFG *CF, LLVMAliasInfoRef PT, std::vector EntryPoints) diff --git a/lib/PhasarLLVM/DataFlow/Mono/Problems/IntraMonoUninitVariables.cpp b/lib/PhasarLLVM/DataFlow/Mono/Problems/IntraMonoUninitVariables.cpp index 3d7aa3a8a..ebbe5e586 100644 --- a/lib/PhasarLLVM/DataFlow/Mono/Problems/IntraMonoUninitVariables.cpp +++ b/lib/PhasarLLVM/DataFlow/Mono/Problems/IntraMonoUninitVariables.cpp @@ -12,7 +12,7 @@ #include "phasar/PhasarLLVM/ControlFlow/LLVMBasedCFG.h" #include "phasar/PhasarLLVM/DB/LLVMProjectIRDB.h" #include "phasar/PhasarLLVM/Pointer/LLVMAliasInfo.h" -#include "phasar/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.h" +#include "phasar/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.h" #include "phasar/PhasarLLVM/Utils/LLVMShorthands.h" #include "phasar/Utils/BitVectorSet.h" @@ -29,7 +29,7 @@ using namespace psr; namespace psr { IntraMonoUninitVariables::IntraMonoUninitVariables( - const LLVMProjectIRDB *IRDB, const LLVMTypeHierarchy *TH, + const LLVMProjectIRDB *IRDB, const DIBasedTypeHierarchy *TH, const LLVMBasedCFG *CF, LLVMAliasInfoRef PT, std::vector EntryPoints) : IntraMonoProblem(IRDB, TH, CF, PT, diff --git a/lib/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.cpp b/lib/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.cpp index 4d581373e..493dc456f 100644 --- a/lib/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.cpp +++ b/lib/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.cpp @@ -207,6 +207,38 @@ auto DIBasedTypeHierarchy::subTypesOf(ClassType Ty) const noexcept return subTypesOf(It->second); } +bool DIBasedTypeHierarchy::isVTable(llvm::StringRef VarName) { + if (VarName.startswith("_ZTV")) { + return true; + } + // In LLVM 16 demangle() takes a StringRef + auto Demang = llvm::demangle(VarName.str()); + return llvm::StringRef(Demang).startswith(VTablePrefixDemang); +} + +std::string +DIBasedTypeHierarchy::removeStructOrClassPrefix(llvm::StringRef TypeName) { + if (TypeName.startswith(StructPrefix)) { + TypeName = TypeName.drop_front(StructPrefix.size()); + } else if (TypeName.startswith(ClassPrefix)) { + TypeName = TypeName.drop_front(ClassPrefix.size()); + } + if (TypeName.endswith(".base")) { + TypeName = TypeName.drop_back(llvm::StringRef(".base").size()); + } + return TypeName.str(); +} + +std::string DIBasedTypeHierarchy::removeVTablePrefix(llvm::StringRef VarName) { + if (VarName.startswith(VTablePrefixDemang)) { + return VarName.drop_front(VTablePrefixDemang.size()).str(); + } + if (VarName.startswith(VTablePrefix)) { + return VarName.drop_front(VTablePrefix.size()).str(); + } + return VarName.str(); +} + void DIBasedTypeHierarchy::print(llvm::raw_ostream &OS) const { { OS << "Type Hierarchy:\n"; diff --git a/lib/PhasarLLVM/Utils/LLVMIRToSrc.cpp b/lib/PhasarLLVM/Utils/LLVMIRToSrc.cpp index d4b9372a9..49fdc29a3 100644 --- a/lib/PhasarLLVM/Utils/LLVMIRToSrc.cpp +++ b/lib/PhasarLLVM/Utils/LLVMIRToSrc.cpp @@ -55,7 +55,7 @@ static llvm::DbgVariableIntrinsic *getDbgVarIntrinsic(const llvm::Value *V) { return nullptr; } -llvm::DILocalVariable *getDILocalVariable(const llvm::Value *V) { +llvm::DILocalVariable *psr::getDILocalVariable(const llvm::Value *V) { if (auto *DbgIntr = getDbgVarIntrinsic(V)) { if (auto *DDI = llvm::dyn_cast(DbgIntr)) { return DDI->getVariable(); diff --git a/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFG_CHATest.cpp b/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFG_CHATest.cpp index b062bdd4c..832836639 100644 --- a/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFG_CHATest.cpp +++ b/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFG_CHATest.cpp @@ -3,7 +3,7 @@ #include "phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h" #include "phasar/PhasarLLVM/DB/LLVMProjectIRDB.h" #include "phasar/PhasarLLVM/Pointer/LLVMAliasSet.h" -#include "phasar/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.h" +#include "phasar/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.h" #include "phasar/PhasarLLVM/Utils/LLVMShorthands.h" #include "TestConfig.h" @@ -17,7 +17,7 @@ using namespace psr; TEST(LLVMBasedICFG_CHATest, StaticCallSite_1) { LLVMProjectIRDB IRDB(unittest::PathToLLTestFiles + "call_graphs/static_callsite_1_c.ll"); - LLVMTypeHierarchy TH(IRDB); + DIBasedTypeHierarchy TH(IRDB); LLVMAliasSet PT(&IRDB); LLVMBasedICFG ICFG(&IRDB, CallGraphAnalysisType::CHA, {"main"}, &TH, &PT); const llvm::Function *F = IRDB.getFunctionDefinition("main"); @@ -39,7 +39,7 @@ TEST(LLVMBasedICFG_CHATest, StaticCallSite_1) { TEST(LLVMBasedICFG_CHATest, VirtualCallSite_2) { LLVMProjectIRDB IRDB(unittest::PathToLLTestFiles + "call_graphs/virtual_call_2_cpp.ll"); - LLVMTypeHierarchy TH(IRDB); + DIBasedTypeHierarchy TH(IRDB); LLVMAliasSet PT(&IRDB); LLVMBasedICFG ICFG(&IRDB, CallGraphAnalysisType::CHA, {"main"}, &TH, &PT); const llvm::Function *F = IRDB.getFunctionDefinition("main"); @@ -61,7 +61,7 @@ TEST(LLVMBasedICFG_CHATest, VirtualCallSite_2) { TEST(LLVMBasedICFG_CHATest, VirtualCallSite_9) { LLVMProjectIRDB IRDB(unittest::PathToLLTestFiles + "call_graphs/virtual_call_9_cpp.ll"); - LLVMTypeHierarchy TH(IRDB); + DIBasedTypeHierarchy TH(IRDB); LLVMAliasSet PT(&IRDB); LLVMBasedICFG ICFG(&IRDB, CallGraphAnalysisType::CHA, {"main"}, &TH, &PT); const llvm::Function *F = IRDB.getFunctionDefinition("main"); @@ -88,7 +88,7 @@ TEST(LLVMBasedICFG_CHATest, VirtualCallSite_9) { TEST(LLVMBasedICFG_CHATest, VirtualCallSite_7) { LLVMProjectIRDB IRDB(unittest::PathToLLTestFiles + "call_graphs/virtual_call_7_cpp.ll"); - LLVMTypeHierarchy TH(IRDB); + DIBasedTypeHierarchy TH(IRDB); LLVMAliasSet PT(&IRDB); LLVMBasedICFG ICFG(&IRDB, CallGraphAnalysisType::CHA, {"main"}, &TH, &PT); const llvm::Function *F = IRDB.getFunctionDefinition("main"); diff --git a/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFG_OTFTest.cpp b/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFG_OTFTest.cpp index 43de67881..7ebb50987 100644 --- a/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFG_OTFTest.cpp +++ b/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFG_OTFTest.cpp @@ -32,14 +32,14 @@ TEST(LLVMBasedICFG_OTFTest, VirtualCallSite_7) { ASSERT_TRUE(VFuncA); ASSERT_TRUE(VFuncB); - const auto *CallToAFunc = getNthInstruction(F, 19); + const auto *CallToAFunc = getNthInstruction(F, 22); ASSERT_TRUE(ICFG.isVirtualFunctionCall(CallToAFunc)); const auto &AsCallees = ICFG.getCalleesOfCallAt(CallToAFunc); ASSERT_EQ(AsCallees.size(), 2U); ASSERT_TRUE(llvm::is_contained(AsCallees, VFuncA)); ASSERT_TRUE(llvm::is_contained(ICFG.getCallersOf(VFuncA), CallToAFunc)); - const auto *CallToBFunc = getNthInstruction(F, 25); + const auto *CallToBFunc = getNthInstruction(F, 29); ASSERT_TRUE(ICFG.isVirtualFunctionCall(CallToBFunc)); const auto &BsCallees = ICFG.getCalleesOfCallAt(CallToBFunc); ASSERT_EQ(BsCallees.size(), 2U); diff --git a/unittests/PhasarLLVM/ControlFlow/LLVMVFTableProviderTest.cpp b/unittests/PhasarLLVM/ControlFlow/LLVMVFTableProviderTest.cpp index 1cd66805e..f1ae8b084 100644 --- a/unittests/PhasarLLVM/ControlFlow/LLVMVFTableProviderTest.cpp +++ b/unittests/PhasarLLVM/ControlFlow/LLVMVFTableProviderTest.cpp @@ -86,20 +86,20 @@ TEST(VTableTest, VTableConstruction_04) { "type_hierarchies/type_hierarchy_9_cpp.ll"}); LLVMVFTableProvider TH(IRDB); - ASSERT_TRUE(TH.hasVFTable(getType(IRDB, "struct.Base"))); + ASSERT_TRUE(TH.hasVFTable(getType(IRDB, "struct.Base.base"))); ASSERT_TRUE(TH.hasVFTable(getType(IRDB, "struct.Child"))); - EXPECT_EQ(demangle(TH.getVFTableOrNull(getType(IRDB, "struct.Base")) + EXPECT_EQ(demangle(TH.getVFTableOrNull(getType(IRDB, "struct.Base.base")) ->getFunction(0) ->getName() .str()), "Base::foo()"); - EXPECT_EQ(demangle(TH.getVFTableOrNull(getType(IRDB, "struct.Base")) + EXPECT_EQ(demangle(TH.getVFTableOrNull(getType(IRDB, "struct.Base.base")) ->getFunction(1) ->getName() .str()), "Base::bar()"); - EXPECT_EQ(TH.getVFTableOrNull(getType(IRDB, "struct.Base"))->size(), 2U); + EXPECT_EQ(TH.getVFTableOrNull(getType(IRDB, "struct.Base.base"))->size(), 2U); EXPECT_EQ(demangle(TH.getVFTableOrNull(getType(IRDB, "struct.Child")) ->getFunction(0) ->getName() @@ -123,20 +123,20 @@ TEST(VTableTest, VTableConstruction_05) { "type_hierarchies/type_hierarchy_10_cpp.ll"}); LLVMVFTableProvider TH(IRDB); - ASSERT_TRUE(TH.hasVFTable(getType(IRDB, "struct.Base"))); + ASSERT_TRUE(TH.hasVFTable(getType(IRDB, "struct.Base.base"))); ASSERT_TRUE(TH.hasVFTable(getType(IRDB, "struct.Child"))); - EXPECT_EQ(demangle(TH.getVFTableOrNull(getType(IRDB, "struct.Base")) + EXPECT_EQ(demangle(TH.getVFTableOrNull(getType(IRDB, "struct.Base.base")) ->getFunction(0) ->getName() .str()), "__cxa_pure_virtual"); - EXPECT_EQ(demangle(TH.getVFTableOrNull(getType(IRDB, "struct.Base")) + EXPECT_EQ(demangle(TH.getVFTableOrNull(getType(IRDB, "struct.Base.base")) ->getFunction(1) ->getName() .str()), "Base::bar()"); - EXPECT_EQ(TH.getVFTableOrNull(getType(IRDB, "struct.Base"))->size(), 2U); + EXPECT_EQ(TH.getVFTableOrNull(getType(IRDB, "struct.Base.base"))->size(), 2U); EXPECT_EQ(demangle(TH.getVFTableOrNull(getType(IRDB, "struct.Child")) ->getFunction(0) ->getName() @@ -161,8 +161,15 @@ TEST(VTableTest, VTableConstruction_6) { LLVMVFTableProvider TH(IRDB); - ASSERT_TRUE(TH.hasVFTable(getType(IRDB, "class.Base"))); - EXPECT_EQ(TH.getVFTableOrNull(getType(IRDB, "class.Base"))->size(), 3U); + llvm::outs() << "Number of Struct Types: " + << IRDB.getModule()->getIdentifiedStructTypes().size() << "\n"; + int Counter = 0; + for (const auto *StructTy : IRDB.getModule()->getIdentifiedStructTypes()) { + llvm::outs() << Counter++ << ": " << StructTy->getName() << "\n"; + } + + ASSERT_TRUE(TH.hasVFTable(getType(IRDB, "class.Base.base"))); + EXPECT_EQ(TH.getVFTableOrNull(getType(IRDB, "class.Base.base"))->size(), 3U); } } // namespace diff --git a/unittests/PhasarLLVM/Pointer/LLVMAliasSetSerializationTest.cpp b/unittests/PhasarLLVM/Pointer/LLVMAliasSetSerializationTest.cpp index f0ee361b0..73bb6d152 100644 --- a/unittests/PhasarLLVM/Pointer/LLVMAliasSetSerializationTest.cpp +++ b/unittests/PhasarLLVM/Pointer/LLVMAliasSetSerializationTest.cpp @@ -3,7 +3,7 @@ #include "phasar/PhasarLLVM/DB/LLVMProjectIRDB.h" #include "phasar/PhasarLLVM/Passes/ValueAnnotationPass.h" #include "phasar/PhasarLLVM/Pointer/LLVMAliasSet.h" -#include "phasar/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.h" +#include "phasar/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.h" #include "phasar/Utils/Logger.h" #include "llvm/ADT/StringRef.h" @@ -80,7 +80,7 @@ static void analyze(llvm::StringRef File, const GroundTruthTy &Gt, // llvm::outs() << *IRDB.getWPAModule() << '\n'; LLVMAliasSet PTS(&IRDB, false); - LLVMTypeHierarchy TH(IRDB); + DIBasedTypeHierarchy TH(IRDB); LLVMBasedICFG ICF(&IRDB, CallGraphAnalysisType::OTF, {EntryPoint.str()}, &TH, &PTS); diff --git a/unittests/Utils/LLVMIRToSrcTest.cpp b/unittests/Utils/LLVMIRToSrcTest.cpp index beb7620ed..01f1f4dbd 100644 --- a/unittests/Utils/LLVMIRToSrcTest.cpp +++ b/unittests/Utils/LLVMIRToSrcTest.cpp @@ -5,7 +5,7 @@ #include "phasar/PhasarLLVM/DB/LLVMProjectIRDB.h" #include "phasar/PhasarLLVM/Passes/ValueAnnotationPass.h" #include "phasar/PhasarLLVM/Pointer/LLVMAliasSet.h" -#include "phasar/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.h" +#include "phasar/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.h" #include "phasar/PhasarLLVM/Utils/LLVMShorthands.h" #include "phasar/Utils/Logger.h" @@ -27,7 +27,7 @@ class LLVMIRToSrcTest : public ::testing::Test { static constexpr auto PathToLlFiles = PHASAR_BUILD_SUBFOLDER("llvmIRtoSrc/"); unique_ptr IRDB; - unique_ptr TH; + unique_ptr TH; unique_ptr PT; unique_ptr ICFG; @@ -36,7 +36,7 @@ class LLVMIRToSrcTest : public ::testing::Test { void initialize(const llvm::Twine &IRFile) { IRDB = make_unique(IRFile); - TH = make_unique(*IRDB); + TH = make_unique(*IRDB); PT = make_unique(IRDB.get()); auto EntryPoints = {"main"s}; ICFG = make_unique(IRDB.get(), CallGraphAnalysisType::OTF, From 5b39a187b93f0fd7617c650665bc223634718451 Mon Sep 17 00:00:00 2001 From: mxHuber Date: Tue, 25 Jun 2024 18:56:50 +0200 Subject: [PATCH 32/78] fixed PathTracingTest --- .../ControlFlow/LLVMVFTableProvider.h | 2 + .../ControlFlow/LLVMVFTableProvider.cpp | 13 ++ .../ControlFlow/LLVMBasedICFG_OTFTest.cpp | 5 +- .../ControlFlow/LLVMVFTableProviderTest.cpp | 30 ++- .../PathSensitivity/PathTracingTest.cpp | 176 +++++++++++------- 5 files changed, 143 insertions(+), 83 deletions(-) diff --git a/include/phasar/PhasarLLVM/ControlFlow/LLVMVFTableProvider.h b/include/phasar/PhasarLLVM/ControlFlow/LLVMVFTableProvider.h index d27fe4b3a..9e0ee8592 100644 --- a/include/phasar/PhasarLLVM/ControlFlow/LLVMVFTableProvider.h +++ b/include/phasar/PhasarLLVM/ControlFlow/LLVMVFTableProvider.h @@ -34,6 +34,8 @@ class LLVMVFTableProvider { [[nodiscard]] bool hasVFTable(const llvm::DIType *Type) const; [[nodiscard]] const LLVMVFTable * getVFTableOrNull(const llvm::StructType *Type) const; + [[nodiscard]] const LLVMVFTable * + getVFTableOrNull(const llvm::DIType *Type) const; private: std::unordered_map TypeVFTMap; diff --git a/lib/PhasarLLVM/ControlFlow/LLVMVFTableProvider.cpp b/lib/PhasarLLVM/ControlFlow/LLVMVFTableProvider.cpp index afad9c05d..0c4f5703b 100644 --- a/lib/PhasarLLVM/ControlFlow/LLVMVFTableProvider.cpp +++ b/lib/PhasarLLVM/ControlFlow/LLVMVFTableProvider.cpp @@ -9,6 +9,7 @@ #include "llvm/Demangle/Demangle.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DebugInfoMetadata.h" +#include "llvm/IR/DerivedTypes.h" #include "llvm/IR/Module.h" #include "llvm/Support/Casting.h" @@ -94,6 +95,7 @@ LLVMVFTableProvider::LLVMVFTableProvider(const LLVMProjectIRDB &IRDB) } } } + llvm::StringMap ClearNameTVMap; for (const auto &Glob : IRDB.getModule()->globals()) { @@ -123,3 +125,14 @@ LLVMVFTableProvider::getVFTableOrNull(const llvm::StructType *Type) const { auto It = TypeVFTMap.find(Type); return It != TypeVFTMap.end() ? &It->second : nullptr; } + +const LLVMVFTable * +LLVMVFTableProvider::getVFTableOrNull(const llvm::DIType *Type) const { + if (const auto *Ty = DITypeToType.at(Type)) { + if (const auto *StructTy = llvm::dyn_cast(Ty)) { + return getVFTableOrNull(StructTy); + } + } + + return nullptr; +} diff --git a/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFG_OTFTest.cpp b/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFG_OTFTest.cpp index 7ebb50987..69c26705c 100644 --- a/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFG_OTFTest.cpp +++ b/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFG_OTFTest.cpp @@ -43,6 +43,7 @@ TEST(LLVMBasedICFG_OTFTest, VirtualCallSite_7) { ASSERT_TRUE(ICFG.isVirtualFunctionCall(CallToBFunc)); const auto &BsCallees = ICFG.getCalleesOfCallAt(CallToBFunc); ASSERT_EQ(BsCallees.size(), 2U); + ASSERT_TRUE(llvm::is_contained(BsCallees, VFuncB)); ASSERT_TRUE(llvm::is_contained(ICFG.getCallersOf(VFuncB), CallToBFunc)); } @@ -70,7 +71,7 @@ TEST(LLVMBasedICFG_OTFTest, VirtualCallSite_7) { TEST(LLVMBasedICFG_OTFTest, FunctionPtrCall_2) { LLVMProjectIRDB IRDB(unittest::PathToLLTestFiles + - "call_graphs/function_pointer_2_cpp.ll"); + "call_graphs/function_pointer_2_cpp_dbg.ll"); DIBasedTypeHierarchy TH(IRDB); LLVMAliasSet PT(&IRDB, false); LLVMBasedICFG ICFG(&IRDB, CallGraphAnalysisType::OTF, {"main"}, &TH, &PT); @@ -108,7 +109,7 @@ TEST(LLVMBasedICFG_OTFTest, FunctionPtrCall_2) { TEST(LLVMBasedICFG_OTFTest, FunctionPtrCall_3) { LLVMProjectIRDB IRDB(unittest::PathToLLTestFiles + - "call_graphs/function_pointer_3_cpp.ll"); + "call_graphs/function_pointer_3_cpp_dbg.ll"); DIBasedTypeHierarchy TH(IRDB); LLVMAliasSet PT(&IRDB, false); LLVMBasedICFG ICFG(&IRDB, CallGraphAnalysisType::OTF, {"main"}, &TH, &PT); diff --git a/unittests/PhasarLLVM/ControlFlow/LLVMVFTableProviderTest.cpp b/unittests/PhasarLLVM/ControlFlow/LLVMVFTableProviderTest.cpp index f1ae8b084..1608749eb 100644 --- a/unittests/PhasarLLVM/ControlFlow/LLVMVFTableProviderTest.cpp +++ b/unittests/PhasarLLVM/ControlFlow/LLVMVFTableProviderTest.cpp @@ -2,11 +2,14 @@ #include "phasar/PhasarLLVM/DB/LLVMProjectIRDB.h" #include "phasar/PhasarLLVM/TypeHierarchy/LLVMVFTable.h" +#include "phasar/PhasarLLVM/Utils/LLVMIRToSrc.h" #include "llvm/ADT/StringRef.h" #include "llvm/Demangle/Demangle.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/Module.h" +#include "llvm/IR/Value.h" +#include "llvm/Support/Casting.h" #include "TestConfig.h" #include "gtest/gtest.h" @@ -28,6 +31,21 @@ static const llvm::StructType *getType(const LLVMProjectIRDB &IRDB, return nullptr; } +static const llvm::DIType *getDIType(const LLVMProjectIRDB &IRDB, + llvm::StringRef Name) { + // TODO: Optimize + for (const auto *Instr : IRDB.getAllInstructions()) { + if (const auto *Val = llvm::dyn_cast(Instr)) { + if (const auto *DILocVal = getDILocalVariable(Val)) { + if (DILocVal->getName() == Name) { + return DILocVal->getType(); + } + } + } + } + return nullptr; +} + // check if the vtables are constructed correctly in more complex scenarios TEST(VTableTest, VTableConstruction_01) { @@ -161,15 +179,9 @@ TEST(VTableTest, VTableConstruction_6) { LLVMVFTableProvider TH(IRDB); - llvm::outs() << "Number of Struct Types: " - << IRDB.getModule()->getIdentifiedStructTypes().size() << "\n"; - int Counter = 0; - for (const auto *StructTy : IRDB.getModule()->getIdentifiedStructTypes()) { - llvm::outs() << Counter++ << ": " << StructTy->getName() << "\n"; - } - - ASSERT_TRUE(TH.hasVFTable(getType(IRDB, "class.Base.base"))); - EXPECT_EQ(TH.getVFTableOrNull(getType(IRDB, "class.Base.base"))->size(), 3U); + ASSERT_TRUE(TH.hasVFTable(getDIType(IRDB, "class.Base.base"))); + EXPECT_EQ(TH.getVFTableOrNull(getDIType(IRDB, "class.Base.base"))->size(), + 3U); } } // namespace diff --git a/unittests/PhasarLLVM/DataFlow/PathSensitivity/PathTracingTest.cpp b/unittests/PhasarLLVM/DataFlow/PathSensitivity/PathTracingTest.cpp index 262073e92..76261020e 100644 --- a/unittests/PhasarLLVM/DataFlow/PathSensitivity/PathTracingTest.cpp +++ b/unittests/PhasarLLVM/DataFlow/PathSensitivity/PathTracingTest.cpp @@ -536,9 +536,9 @@ TEST_F(PathTracingTest, Handle_Inter_11) { auto PathsVec = doAnalysis("inter_11_cpp.ll"); // Note: The alias analysis is strong enough to see that Three::assignValue // can never be called - comparePaths(PathsVec, {{8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 27, 28, 29, - 30, 31, 35, 36, 37, 38, 39, 40, 32, 33, 34, 18, 19, - 20, 21, 22, 23, 24, 25, 41, 44, 46, 47, 48, 26}}); + comparePaths(PathsVec, {{8, 9, 10, 11, 12, 13, 14, 15, 16, 24, 25, + 26, 27, 30, 31, 32, 33, 34, 28, 29, 17, 18, + 19, 20, 21, 22, 35, 38, 40, 41, 42, 23}}); } TEST_F(PathTracingTest, Lambda_Inter_11) { @@ -547,46 +547,63 @@ TEST_F(PathTracingTest, Lambda_Inter_11) { auto PathsVec = doLambdaAnalysis("inter_11_cpp.ll"); // Note: The alias analysis is strong enough to see that Three::assignValue // can never be called - comparePaths(PathsVec, - {{8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 27, 28, 29, 30, - 31, 35, 36, 37, 38, 39, 40, 32, 33, 34, 18, 19, 20, 21, - 22, 23, 24, 25, 41, 42, 43, 44, 45, 46, 47, 48, 26}}); + comparePaths(PathsVec, {{8, 9, 10, 11, 12, 13, 14, 15, 16, 24, 25, 26, + 27, 30, 31, 32, 33, 34, 28, 29, 17, 18, 19, 20, + 21, 22, 35, 36, 37, 38, 39, 40, 41, 42, 23}}); } TEST_F(PathTracingTest, Handle_Inter_12) { auto PathsVec = doAnalysis("inter_12_cpp.ll"); comparePaths( PathsVec, - {{11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 44, 45, 46, 47, 48, - 60, 61, 62, 63, 64, 65, 49, 50, 51, 21, 22, 23, 24, 25, 32, - 33, 34, 52, 53, 54, 55, 56, 60, 61, 62, 63, 64, 65, 57, 58, - 59, 35, 36, 37, 38, 39, 40, 41, 42, 79, 82, 84, 85, 86, 43}, - {11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 44, 45, 46, 47, 48, - 60, 61, 62, 63, 64, 65, 49, 50, 51, 21, 22, 23, 24, 25, 32, - 33, 34, 52, 53, 54, 55, 56, 60, 61, 62, 63, 64, 65, 57, 58, - 59, 35, 36, 37, 38, 39, 40, 41, 42, 109, 112, 114, 115, 116, 43}, - {11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 44, 45, 46, 47, 48, 60, 61, - 62, 63, 64, 65, 49, 50, 51, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, - 72, 73, 74, 75, 66, 67, 68, 69, 70, 87, 88, 89, 90, 71, 76, 77, 78, - 31, 32, 33, 34, 52, 53, 54, 55, 56, 60, 61, 62, 63, 64, 65, 57, 58, - 59, 35, 36, 37, 38, 39, 40, 41, 42, 79, 82, 84, 85, 86, 43}, - {11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 44, 45, 46, 47, 48, 60, 61, - 62, 63, 64, 65, 49, 50, 51, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, - 72, 73, 74, 75, 66, 67, 68, 69, 70, 87, 88, 89, 90, 71, 76, 77, 78, - 31, 32, 33, 34, 52, 53, 54, 55, 56, 60, 61, 62, 63, 64, 65, 57, 58, - 59, 35, 36, 37, 38, 39, 40, 41, 42, 109, 112, 114, 115, 116, 43}, - {11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 44, 45, 46, 47, - 48, 60, 61, 62, 63, 64, 65, 49, 50, 51, 21, 22, 23, 24, - 25, 26, 27, 28, 29, 30, 102, 103, 104, 105, 96, 97, 98, 99, - 100, 87, 88, 89, 90, 101, 106, 107, 108, 31, 32, 33, 34, 52, - 53, 54, 55, 56, 60, 61, 62, 63, 64, 65, 57, 58, 59, 35, - 36, 37, 38, 39, 40, 41, 42, 79, 82, 84, 85, 86, 43}, - {11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 44, 45, 46, 47, - 48, 60, 61, 62, 63, 64, 65, 49, 50, 51, 21, 22, 23, 24, - 25, 26, 27, 28, 29, 30, 102, 103, 104, 105, 96, 97, 98, 99, - 100, 87, 88, 89, 90, 101, 106, 107, 108, 31, 32, 33, 34, 52, - 53, 54, 55, 56, 60, 61, 62, 63, 64, 65, 57, 58, 59, 35, - 36, 37, 38, 39, 40, 41, 42, 109, 112, 114, 115, 116, 43}}); + {{11, 12, 13, 14, 15, 16, 17, 18, 19, 38, 39, 40, 41, 50, 51, 52, 53, + 54, 42, 43, 20, 21, 22, 23, 29, 30, 44, 45, 46, 47, 50, 51, 52, 53, + 54, 48, 49, 31, 32, 33, 34, 35, 36, 66, 69, 71, 72, 73, 37}, + {11, 12, 13, 14, 15, 16, 17, 18, 19, 38, 39, 40, 41, 50, 51, 52, 53, + 54, 42, 43, 20, 21, 22, 23, 29, 30, 44, 45, 46, 47, 50, 51, 52, 53, + 54, 48, 49, 31, 32, 33, 34, 35, 36, 94, 97, 99, 100, 101, 37}, + {11, 12, 13, 14, 15, 16, 17, 18, 19, 38, 39, 40, 41, 50, 51, + 52, 53, 54, 42, 43, 20, 21, 22, 23, 24, 25, 26, 27, 74, 75, + 76, 77, 28, 29, 30, 44, 45, 46, 47, 50, 51, 52, 53, 54, 48, + 49, 31, 32, 33, 34, 35, 36, 66, 69, 71, 72, 73, 37}, + {11, 12, 13, 14, 15, 16, 17, 18, 19, 38, 39, 40, 41, 50, 51, + 52, 53, 54, 42, 43, 20, 21, 22, 23, 24, 25, 26, 27, 74, 75, + 76, 77, 28, 29, 30, 44, 45, 46, 47, 50, 51, 52, 53, 54, 48, + 49, 31, 32, 33, 34, 35, 36, 94, 97, 99, 100, 101, 37}, + {11, 12, 13, 14, 15, 16, 17, 18, 19, 38, 39, 40, 41, 50, 51, 52, + 53, 54, 42, 43, 20, 21, 22, 23, 24, 25, 26, 27, 83, 84, 85, 86, + 74, 75, 76, 77, 87, 28, 29, 30, 44, 45, 46, 47, 50, 51, 52, 53, + 54, 48, 49, 31, 32, 33, 34, 35, 36, 66, 69, 71, 72, 73, 37}, + {11, 12, 13, 14, 15, 16, 17, 18, 19, 38, 39, 40, 41, 50, 51, 52, + 53, 54, 42, 43, 20, 21, 22, 23, 24, 25, 26, 27, 83, 84, 85, 86, + 74, 75, 76, 77, 87, 28, 29, 30, 44, 45, 46, 47, 50, 51, 52, 53, + 54, 48, 49, 31, 32, 33, 34, 35, 36, 94, 97, 99, 100, 101, 37}, + {11, 12, 13, 14, 15, 16, 17, 18, 19, 38, 39, 40, 41, 50, 51, 52, + 53, 54, 42, 43, 20, 21, 22, 23, 24, 25, 26, 27, 55, 56, 57, 58, + 74, 75, 76, 77, 59, 28, 29, 30, 44, 45, 46, 47, 50, 51, 52, 53, + 54, 48, 49, 31, 32, 33, 34, 35, 36, 66, 69, 71, 72, 73, 37}, + {11, 12, 13, 14, 15, 16, 17, 18, 19, 38, 39, 40, 41, 50, 51, 52, + 53, 54, 42, 43, 20, 21, 22, 23, 24, 25, 26, 27, 55, 56, 57, 58, + 74, 75, 76, 77, 59, 28, 29, 30, 44, 45, 46, 47, 50, 51, 52, 53, + 54, 48, 49, 31, 32, 33, 34, 35, 36, 94, 97, 99, 100, 101, 37}, + {11, 12, 13, 14, 15, 16, 17, 18, 19, 38, 39, 40, 41, 50, 51, 52, 53, 54, + 42, 43, 20, 21, 22, 23, 24, 25, 26, 27, 88, 89, 90, 91, 83, 84, 85, 86, + 74, 75, 76, 77, 87, 92, 93, 28, 29, 30, 44, 45, 46, 47, 50, 51, 52, 53, + 54, 48, 49, 31, 32, 33, 34, 35, 36, 66, 69, 71, 72, 73, 37}, + {11, 12, 13, 14, 15, 16, 17, 18, 19, 38, 39, 40, 41, 50, + 51, 52, 53, 54, 42, 43, 20, 21, 22, 23, 24, 25, 26, 27, + 88, 89, 90, 91, 83, 84, 85, 86, 74, 75, 76, 77, 87, 92, + 93, 28, 29, 30, 44, 45, 46, 47, 50, 51, 52, 53, 54, 48, + 49, 31, 32, 33, 34, 35, 36, 94, 97, 99, 100, 101, 37}, + {11, 12, 13, 14, 15, 16, 17, 18, 19, 38, 39, 40, 41, 50, 51, 52, 53, 54, + 42, 43, 20, 21, 22, 23, 24, 25, 26, 27, 60, 61, 62, 63, 55, 56, 57, 58, + 74, 75, 76, 77, 59, 64, 65, 28, 29, 30, 44, 45, 46, 47, 50, 51, 52, 53, + 54, 48, 49, 31, 32, 33, 34, 35, 36, 66, 69, 71, 72, 73, 37}, + {11, 12, 13, 14, 15, 16, 17, 18, 19, 38, 39, 40, 41, 50, + 51, 52, 53, 54, 42, 43, 20, 21, 22, 23, 24, 25, 26, 27, + 60, 61, 62, 63, 55, 56, 57, 58, 74, 75, 76, 77, 59, 64, + 65, 28, 29, 30, 44, 45, 46, 47, 50, 51, 52, 53, 54, 48, + 49, 31, 32, 33, 34, 35, 36, 94, 97, 99, 100, 101, 37}}); } TEST_F(PathTracingTest, Lambda_Inter_12) { @@ -595,41 +612,56 @@ TEST_F(PathTracingTest, Lambda_Inter_12) { auto PathsVec = doLambdaAnalysis("inter_12_cpp.ll"); comparePaths( PathsVec, - { - {11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 44, 45, 46, - 47, 48, 60, 61, 62, 63, 64, 65, 49, 50, 51, 21, 22, - 23, 24, 25, 32, 33, 34, 52, 53, 54, 55, 56, 60, 61, - 62, 63, 64, 65, 57, 58, 59, 35, 36, 37, 38, 39, 40, - 41, 42, 109, 110, 111, 112, 113, 114, 115, 116, 43}, - {11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 44, 45, 46, 47, 48, - 60, 61, 62, 63, 64, 65, 49, 50, 51, 21, 22, 23, 24, 25, 26, - 27, 28, 29, 30, 72, 73, 74, 75, 66, 67, 68, 69, 70, 87, 88, - 89, 90, 71, 76, 77, 78, 31, 32, 33, 34, 52, 53, 54, 55, 56, - 60, 61, 62, 63, 64, 65, 57, 58, 59, 35, 36, 37, 38, 39, 40, - 41, 42, 79, 80, 81, 82, 83, 84, 85, 86, 43}, - {11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 44, 45, 46, 47, 48, - 60, 61, 62, 63, 64, 65, 49, 50, 51, 21, 22, 23, 24, 25, 26, - 27, 28, 29, 30, 72, 73, 74, 75, 66, 67, 68, 69, 70, 87, 88, - 89, 90, 71, 76, 77, 78, 31, 32, 33, 34, 52, 53, 54, 55, 56, - 60, 61, 62, 63, 64, 65, 57, 58, 59, 35, 36, 37, 38, 39, 40, - 41, 42, 109, 110, 111, 112, 113, 114, 115, 116, 43}, - {11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 44, 45, 46, 47, 48, - 60, 61, 62, 63, 64, 65, 49, 50, 51, 21, 22, 23, 24, 25, 26, - 27, 28, 29, 30, 102, 103, 104, 105, 96, 97, 98, 99, 100, 87, 88, - 89, 90, 101, 106, 107, 108, 31, 32, 33, 34, 52, 53, 54, 55, 56, - 60, 61, 62, 63, 64, 65, 57, 58, 59, 35, 36, 37, 38, 39, 40, - 41, 42, 79, 80, 81, 82, 83, 84, 85, 86, 43}, - {11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 44, 45, 46, 47, 48, - 60, 61, 62, 63, 64, 65, 49, 50, 51, 21, 22, 23, 24, 25, 26, - 27, 28, 29, 30, 102, 103, 104, 105, 96, 97, 98, 99, 100, 87, 88, - 89, 90, 101, 106, 107, 108, 31, 32, 33, 34, 52, 53, 54, 55, 56, - 60, 61, 62, 63, 64, 65, 57, 58, 59, 35, 36, 37, 38, 39, 40, - 41, 42, 109, 110, 111, 112, 113, 114, 115, 116, 43}, - {11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 44, 45, 46, 47, 48, 60, - 61, 62, 63, 64, 65, 49, 50, 51, 21, 22, 23, 24, 25, 32, 33, 34, - 52, 53, 54, 55, 56, 60, 61, 62, 63, 64, 65, 57, 58, 59, 35, 36, - 37, 38, 39, 40, 41, 42, 79, 80, 81, 82, 83, 84, 85, 86, 43}, - }); + {{11, 12, 13, 14, 15, 16, 17, 18, 19, 38, 39, 40, 41, + 50, 51, 52, 53, 54, 42, 43, 20, 21, 22, 23, 29, 30, + 44, 45, 46, 47, 50, 51, 52, 53, 54, 48, 49, 31, 32, + 33, 34, 35, 36, 94, 95, 96, 97, 98, 99, 100, 101, 37}, + {11, 12, 13, 14, 15, 16, 17, 18, 19, 38, 39, 40, 41, 50, 51, 52, 53, 54, + 42, 43, 20, 21, 22, 23, 29, 30, 44, 45, 46, 47, 50, 51, 52, 53, 54, 48, + 49, 31, 32, 33, 34, 35, 36, 66, 67, 68, 69, 70, 71, 72, 73, 37}, + {11, 12, 13, 14, 15, 16, 17, 18, 19, 38, 39, 40, 41, 50, 51, 52, + 53, 54, 42, 43, 20, 21, 22, 23, 24, 25, 26, 27, 74, 75, 76, 77, + 28, 29, 30, 44, 45, 46, 47, 50, 51, 52, 53, 54, 48, 49, 31, 32, + 33, 34, 35, 36, 94, 95, 96, 97, 98, 99, 100, 101, 37}, + {11, 12, 13, 14, 15, 16, 17, 18, 19, 38, 39, 40, 41, 50, 51, 52, + 53, 54, 42, 43, 20, 21, 22, 23, 24, 25, 26, 27, 74, 75, 76, 77, + 28, 29, 30, 44, 45, 46, 47, 50, 51, 52, 53, 54, 48, 49, 31, 32, + 33, 34, 35, 36, 66, 67, 68, 69, 70, 71, 72, 73, 37}, + {11, 12, 13, 14, 15, 16, 17, 18, 19, 38, 39, 40, 41, 50, 51, 52, 53, + 54, 42, 43, 20, 21, 22, 23, 24, 25, 26, 27, 55, 56, 57, 58, 74, 75, + 76, 77, 59, 28, 29, 30, 44, 45, 46, 47, 50, 51, 52, 53, 54, 48, 49, + 31, 32, 33, 34, 35, 36, 94, 95, 96, 97, 98, 99, 100, 101, 37}, + {11, 12, 13, 14, 15, 16, 17, 18, 19, 38, 39, 40, 41, 50, 51, 52, 53, + 54, 42, 43, 20, 21, 22, 23, 24, 25, 26, 27, 55, 56, 57, 58, 74, 75, + 76, 77, 59, 28, 29, 30, 44, 45, 46, 47, 50, 51, 52, 53, 54, 48, 49, + 31, 32, 33, 34, 35, 36, 66, 67, 68, 69, 70, 71, 72, 73, 37}, + {11, 12, 13, 14, 15, 16, 17, 18, 19, 38, 39, 40, 41, 50, 51, 52, 53, + 54, 42, 43, 20, 21, 22, 23, 24, 25, 26, 27, 83, 84, 85, 86, 74, 75, + 76, 77, 87, 28, 29, 30, 44, 45, 46, 47, 50, 51, 52, 53, 54, 48, 49, + 31, 32, 33, 34, 35, 36, 94, 95, 96, 97, 98, 99, 100, 101, 37}, + {11, 12, 13, 14, 15, 16, 17, 18, 19, 38, 39, 40, 41, 50, 51, 52, 53, + 54, 42, 43, 20, 21, 22, 23, 24, 25, 26, 27, 83, 84, 85, 86, 74, 75, + 76, 77, 87, 28, 29, 30, 44, 45, 46, 47, 50, 51, 52, 53, 54, 48, 49, + 31, 32, 33, 34, 35, 36, 66, 67, 68, 69, 70, 71, 72, 73, 37}, + {11, 12, 13, 14, 15, 16, 17, 18, 19, 38, 39, 40, 41, 50, 51, + 52, 53, 54, 42, 43, 20, 21, 22, 23, 24, 25, 26, 27, 88, 89, + 90, 91, 83, 84, 85, 86, 74, 75, 76, 77, 87, 92, 93, 28, 29, + 30, 44, 45, 46, 47, 50, 51, 52, 53, 54, 48, 49, 31, 32, 33, + 34, 35, 36, 94, 95, 96, 97, 98, 99, 100, 101, 37}, + {11, 12, 13, 14, 15, 16, 17, 18, 19, 38, 39, 40, 41, 50, 51, 52, 53, 54, + 42, 43, 20, 21, 22, 23, 24, 25, 26, 27, 88, 89, 90, 91, 83, 84, 85, 86, + 74, 75, 76, 77, 87, 92, 93, 28, 29, 30, 44, 45, 46, 47, 50, 51, 52, 53, + 54, 48, 49, 31, 32, 33, 34, 35, 36, 66, 67, 68, 69, 70, 71, 72, 73, 37}, + {11, 12, 13, 14, 15, 16, 17, 18, 19, 38, 39, 40, 41, 50, 51, + 52, 53, 54, 42, 43, 20, 21, 22, 23, 24, 25, 26, 27, 60, 61, + 62, 63, 55, 56, 57, 58, 74, 75, 76, 77, 59, 64, 65, 28, 29, + 30, 44, 45, 46, 47, 50, 51, 52, 53, 54, 48, 49, 31, 32, 33, + 34, 35, 36, 94, 95, 96, 97, 98, 99, 100, 101, 37}, + {11, 12, 13, 14, 15, 16, 17, 18, 19, 38, 39, 40, 41, 50, 51, + 52, 53, 54, 42, 43, 20, 21, 22, 23, 24, 25, 26, 27, 60, 61, + 62, 63, 55, 56, 57, 58, 74, 75, 76, 77, 59, 64, 65, 28, 29, + 30, 44, 45, 46, 47, 50, 51, 52, 53, 54, 48, 49, 31, 32, 33, + 34, 35, 36, 66, 67, 68, 69, 70, 71, 72, 73, 37}}); } TEST_F(PathTracingTest, Handle_Intra_01) { From 85b0f24f98553a32a8ee5ddde603ab1e701baa92 Mon Sep 17 00:00:00 2001 From: mxHuber Date: Mon, 1 Jul 2024 06:47:40 +0200 Subject: [PATCH 33/78] dtaresolver deprecated and test fixes --- .../ControlFlow/LLVMVFTableProvider.h | 9 +- .../ControlFlow/Resolver/DTAResolver.h | 20 ++- .../ControlFlow/Resolver/Resolver.h | 4 - .../PhasarLLVM/TypeHierarchy/LLVMVFTable.h | 1 - .../ControlFlow/LLVMVFTableProvider.cpp | 121 ++++++------------ .../ControlFlow/Resolver/DTAResolver.cpp | 23 +++- .../ControlFlow/Resolver/Resolver.cpp | 22 +--- .../ControlFlow/LLVMBasedICFG_DTATest.cpp | 5 +- .../ControlFlow/LLVMVFTableProviderTest.cpp | 113 ++++++++-------- 9 files changed, 142 insertions(+), 176 deletions(-) diff --git a/include/phasar/PhasarLLVM/ControlFlow/LLVMVFTableProvider.h b/include/phasar/PhasarLLVM/ControlFlow/LLVMVFTableProvider.h index 9e0ee8592..ce5d26b54 100644 --- a/include/phasar/PhasarLLVM/ControlFlow/LLVMVFTableProvider.h +++ b/include/phasar/PhasarLLVM/ControlFlow/LLVMVFTableProvider.h @@ -18,7 +18,7 @@ namespace llvm { class Module; -class StructType; +class DIType; class GlobalVariable; } // namespace llvm @@ -30,17 +30,12 @@ class LLVMVFTableProvider { explicit LLVMVFTableProvider(const llvm::Module &Mod); explicit LLVMVFTableProvider(const LLVMProjectIRDB &IRDB); - [[nodiscard]] bool hasVFTable(const llvm::StructType *Type) const; [[nodiscard]] bool hasVFTable(const llvm::DIType *Type) const; [[nodiscard]] const LLVMVFTable * - getVFTableOrNull(const llvm::StructType *Type) const; - [[nodiscard]] const LLVMVFTable * getVFTableOrNull(const llvm::DIType *Type) const; private: - std::unordered_map TypeVFTMap; - std::unordered_map DITypeVFTMap; - std::map DITypeToType; + std::unordered_map TypeVFTMap; }; } // namespace psr diff --git a/include/phasar/PhasarLLVM/ControlFlow/Resolver/DTAResolver.h b/include/phasar/PhasarLLVM/ControlFlow/Resolver/DTAResolver.h index 3e8e1ed95..0c047c950 100644 --- a/include/phasar/PhasarLLVM/ControlFlow/Resolver/DTAResolver.h +++ b/include/phasar/PhasarLLVM/ControlFlow/Resolver/DTAResolver.h @@ -45,7 +45,7 @@ class DTAResolver : public CHAResolver { * An heuristic that return true if the bitcast instruction is interesting to * take into the DTA relational graph */ - static bool + [[deprecated("Does not work with opaque pointers anymore")]] static bool heuristicAntiConstructorThisType(const llvm::BitCastInst *BitCast); /** @@ -53,19 +53,25 @@ class DTAResolver : public CHAResolver { * interesting to take into the DTA relational graph (use the presence or not * of vtable) */ - bool heuristicAntiConstructorVtablePos(const llvm::BitCastInst *BitCast); + [[deprecated("Does not work with opaque pointers anymore")]] bool + heuristicAntiConstructorVtablePos(const llvm::BitCastInst *BitCast); public: - DTAResolver(const LLVMProjectIRDB *IRDB, const LLVMVFTableProvider *VTP, - const DIBasedTypeHierarchy *TH); + [[deprecated("Does not work with opaque pointers anymore")]] DTAResolver( + const LLVMProjectIRDB *IRDB, const LLVMVFTableProvider *VTP, + const DIBasedTypeHierarchy *TH); ~DTAResolver() override = default; - FunctionSetTy resolveVirtualCall(const llvm::CallBase *CallSite) override; + [[deprecated("Does not work with opaque pointers anymore")]] FunctionSetTy + resolveVirtualCall(const llvm::CallBase *CallSite) override; - void otherInst(const llvm::Instruction *Inst) override; + [[deprecated("Does not work with opaque pointers anymore")]] void + otherInst(const llvm::Instruction *Inst) override; - [[nodiscard]] std::string str() const override; + [[nodiscard]] [[deprecated( + "Does not work with opaque pointers anymore")]] std::string + str() const override; }; } // namespace psr diff --git a/include/phasar/PhasarLLVM/ControlFlow/Resolver/Resolver.h b/include/phasar/PhasarLLVM/ControlFlow/Resolver/Resolver.h index 9992c8167..45cd13c2f 100644 --- a/include/phasar/PhasarLLVM/ControlFlow/Resolver/Resolver.h +++ b/include/phasar/PhasarLLVM/ControlFlow/Resolver/Resolver.h @@ -67,10 +67,6 @@ class Resolver { getNonPureVirtualVFTEntry(const llvm::DIType *T, unsigned Idx, const llvm::CallBase *CallSite); - const llvm::Function * - getNonPureVirtualVFTEntry(const llvm::StructType *T, unsigned Idx, - const llvm::CallBase *CallSite); - public: using FunctionSetTy = llvm::SmallDenseSet; diff --git a/include/phasar/PhasarLLVM/TypeHierarchy/LLVMVFTable.h b/include/phasar/PhasarLLVM/TypeHierarchy/LLVMVFTable.h index fd55a006a..3ab40dc18 100644 --- a/include/phasar/PhasarLLVM/TypeHierarchy/LLVMVFTable.h +++ b/include/phasar/PhasarLLVM/TypeHierarchy/LLVMVFTable.h @@ -31,7 +31,6 @@ namespace psr { */ class LLVMVFTable : public VFTable { private: - friend class LLVMTypeHierarchy; friend class DIBasedTypeHierarchy; std::vector VFT; diff --git a/lib/PhasarLLVM/ControlFlow/LLVMVFTableProvider.cpp b/lib/PhasarLLVM/ControlFlow/LLVMVFTableProvider.cpp index 0c4f5703b..a96052a15 100644 --- a/lib/PhasarLLVM/ControlFlow/LLVMVFTableProvider.cpp +++ b/lib/PhasarLLVM/ControlFlow/LLVMVFTableProvider.cpp @@ -6,6 +6,7 @@ #include "phasar/PhasarLLVM/Utils/LLVMIRToSrc.h" #include "phasar/Utils/Logger.h" +#include "llvm/BinaryFormat/Dwarf.h" #include "llvm/Demangle/Demangle.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DebugInfoMetadata.h" @@ -15,57 +16,41 @@ using namespace psr; -static std::vector getVirtualFunctions( - const llvm::StringMap &ClearNameTVMap, - const llvm::StructType &Type) { - auto ClearName = - DIBasedTypeHierarchy::removeStructOrClassPrefix(Type.getName()); - - auto It = ClearNameTVMap.find(ClearName); - - if (It != ClearNameTVMap.end()) { - if (const auto *TI = llvm::dyn_cast(It->second)) { - if (!TI->hasInitializer()) { - PHASAR_LOG_LEVEL_CAT(DEBUG, "DIBasedTypeHierarchy", - ClearName << " does not have initializer"); - return {}; - } - if (const auto *I = - llvm::dyn_cast(TI->getInitializer())) { - return LLVMVFTable::getVFVectorFromIRVTable(*I); - } - } +static std::string getTypeName(const llvm::DIType *DITy) { + if (const auto *CompTy = llvm::dyn_cast(DITy)) { + auto Ident = CompTy->getIdentifier(); + return Ident.empty() ? llvm::demangle(CompTy->getName().str()) + : llvm::demangle(Ident.str()); } - return {}; + return llvm::demangle(DITy->getName().str()); } -static std::vector getVirtualFunctionsDIBased( +static std::vector getVirtualFunctions( const llvm::StringMap &ClearNameTVMap, - const llvm::DIType &Type) { - auto ClearName = - DIBasedTypeHierarchy::removeStructOrClassPrefix(Type.getName()); + const llvm::DIType *Type) { + auto ClearName = getTypeName(Type); + + if (ClearName.substr(0, 18) == "typeinfo name for ") { + ClearName = ClearName.substr(18, ClearName.size() - 1); + } auto It = ClearNameTVMap.find(ClearName); if (It != ClearNameTVMap.end()) { - if (const auto *TI = llvm::dyn_cast(It->second)) { - if (!TI->hasInitializer()) { - PHASAR_LOG_LEVEL_CAT(DEBUG, "DIBasedTypeHierarchy", - ClearName << " does not have initializer"); - return {}; - } - if (const auto *I = - llvm::dyn_cast(TI->getInitializer())) { - return LLVMVFTable::getVFVectorFromIRVTable(*I); - } + if (!It->second->hasInitializer()) { + PHASAR_LOG_LEVEL_CAT(DEBUG, "DIBasedTypeHierarchy", + ClearName << " does not have initializer"); + return {}; + } + if (const auto *I = llvm::dyn_cast( + It->second->getInitializer())) { + return LLVMVFTable::getVFVectorFromIRVTable(*I); } } return {}; } LLVMVFTableProvider::LLVMVFTableProvider(const llvm::Module &Mod) { - auto StructTypes = Mod.getIdentifiedStructTypes(); - llvm::StringMap ClearNameTVMap; for (const auto &Glob : Mod.globals()) { @@ -76,63 +61,33 @@ LLVMVFTableProvider::LLVMVFTableProvider(const llvm::Module &Mod) { } } - for (const auto *Ty : StructTypes) { - TypeVFTMap.try_emplace(Ty, getVirtualFunctions(ClearNameTVMap, *Ty)); - } -} - -LLVMVFTableProvider::LLVMVFTableProvider(const LLVMProjectIRDB &IRDB) - : LLVMVFTableProvider(*IRDB.getModule()) { - for (const auto *Instr : IRDB.getAllInstructions()) { - if (const auto *Val = llvm::dyn_cast(Instr)) { - if (const auto *DILocalVar = getDILocalVariable(Val)) { - if (const auto *DerivedTy = - llvm::dyn_cast(DILocalVar->getType())) { - DITypeToType[DerivedTy->getBaseType()] = Val->getType(); - continue; + llvm::DebugInfoFinder DIF; + DIF.processModule(Mod); + for (const auto *Ty : DIF.types()) { + if (const auto *DerivedTy = llvm::dyn_cast(Ty)) { + if (const auto *BaseTy = DerivedTy->getBaseType()) { + if (const auto *CompTy = + llvm::dyn_cast(BaseTy)) { + if (CompTy->getTag() == llvm::dwarf::DW_TAG_class_type || + CompTy->getTag() == llvm::dwarf::DW_TAG_structure_type) { + TypeVFTMap.try_emplace(CompTy, + getVirtualFunctions(ClearNameTVMap, CompTy)); + } } - DITypeToType[DILocalVar->getType()] = Val->getType(); } } } - - llvm::StringMap ClearNameTVMap; - - for (const auto &Glob : IRDB.getModule()->globals()) { - if (DIBasedTypeHierarchy::isVTable(Glob.getName())) { - auto Demang = llvm::demangle(Glob.getName().str()); - auto ClearName = DIBasedTypeHierarchy::removeVTablePrefix(Demang); - ClearNameTVMap.try_emplace(ClearName, &Glob); - } - } - - for (const auto &Elem : DITypeToType) { - DITypeVFTMap.try_emplace( - Elem.first, getVirtualFunctionsDIBased(ClearNameTVMap, *Elem.first)); - } } -bool LLVMVFTableProvider::hasVFTable(const llvm::StructType *Type) const { - return TypeVFTMap.count(Type); -} +LLVMVFTableProvider::LLVMVFTableProvider(const LLVMProjectIRDB &IRDB) + : LLVMVFTableProvider(*IRDB.getModule()) {} bool LLVMVFTableProvider::hasVFTable(const llvm::DIType *Type) const { - return DITypeToType.count(Type); + return TypeVFTMap.count(Type); } const LLVMVFTable * -LLVMVFTableProvider::getVFTableOrNull(const llvm::StructType *Type) const { +LLVMVFTableProvider::getVFTableOrNull(const llvm::DIType *Type) const { auto It = TypeVFTMap.find(Type); return It != TypeVFTMap.end() ? &It->second : nullptr; } - -const LLVMVFTable * -LLVMVFTableProvider::getVFTableOrNull(const llvm::DIType *Type) const { - if (const auto *Ty = DITypeToType.at(Type)) { - if (const auto *StructTy = llvm::dyn_cast(Ty)) { - return getVFTableOrNull(StructTy); - } - } - - return nullptr; -} diff --git a/lib/PhasarLLVM/ControlFlow/Resolver/DTAResolver.cpp b/lib/PhasarLLVM/ControlFlow/Resolver/DTAResolver.cpp index 002c1211f..b6731637a 100644 --- a/lib/PhasarLLVM/ControlFlow/Resolver/DTAResolver.cpp +++ b/lib/PhasarLLVM/ControlFlow/Resolver/DTAResolver.cpp @@ -33,6 +33,7 @@ #include "llvm/IR/Operator.h" #include "llvm/IR/Value.h" #include "llvm/Support/Casting.h" +#include "llvm/Support/ErrorHandling.h" #include @@ -45,6 +46,10 @@ DTAResolver::DTAResolver(const LLVMProjectIRDB *IRDB, bool DTAResolver::heuristicAntiConstructorThisType( const llvm::BitCastInst *BitCast) { + + llvm::report_fatal_error("Does not work with opaque pointers anymore"); + +#if 0 // We check if the caller is a constructor, and if the this argument has the // same type as the source type of the bitcast. If it is the case, it returns // false, true otherwise. @@ -62,13 +67,20 @@ bool DTAResolver::heuristicAntiConstructorThisType( } return true; +#endif } bool DTAResolver::heuristicAntiConstructorVtablePos( const llvm::BitCastInst *BitCast) { + + llvm::report_fatal_error("Does not work with opaque pointers anymore"); + +#if 0 + // Better heuristic than the previous one, can handle the CRTP. Based on the // previous one. + if (heuristicAntiConstructorThisType(BitCast)) { return true; } @@ -142,9 +154,14 @@ bool DTAResolver::heuristicAntiConstructorVtablePos( } return (BitcastNum > VtableNum); +#endif } void DTAResolver::otherInst(const llvm::Instruction *Inst) { + + llvm::report_fatal_error("Does not work with opaque pointers anymore"); + +#if 0 if (Inst->getType()->isOpaquePointerTy()) { /// XXX: We may want to get these information on a different way, e.g. by /// analyzing the debug info @@ -165,10 +182,13 @@ void DTAResolver::otherInst(const llvm::Instruction *Inst) { TypeGraph.addLink(DestStructType, SrcStructType); } } +#endif } - auto DTAResolver::resolveVirtualCall(const llvm::CallBase *CallSite) -> FunctionSetTy { + llvm::report_fatal_error("Does not work with opaque pointers anymore"); + +#if 0 FunctionSetTy PossibleCallTargets; PHASAR_LOG_LEVEL(DEBUG, @@ -220,6 +240,7 @@ auto DTAResolver::resolveVirtualCall(const llvm::CallBase *CallSite) #endif return PossibleCallTargets; +#endif } std::string DTAResolver::str() const { return "DTA"; } diff --git a/lib/PhasarLLVM/ControlFlow/Resolver/Resolver.cpp b/lib/PhasarLLVM/ControlFlow/Resolver/Resolver.cpp index a38bdff34..c651ec106 100644 --- a/lib/PhasarLLVM/ControlFlow/Resolver/Resolver.cpp +++ b/lib/PhasarLLVM/ControlFlow/Resolver/Resolver.cpp @@ -179,27 +179,6 @@ Resolver::getNonPureVirtualVFTEntry(const llvm::DIType *T, unsigned Idx, return nullptr; } - if (const auto *StructTy = - llvm::dyn_cast(DITypeToType[T])) { - if (const auto *VT = VTP->getVFTableOrNull(StructTy)) { - const auto *Target = VT->getFunction(Idx); - if (Target && - Target->getName() != DIBasedTypeHierarchy::PureVirtualCallName && - isConsistentCall(CallSite, Target)) { - return Target; - } - } - } - - return nullptr; -} - -const llvm::Function * -Resolver::getNonPureVirtualVFTEntry(const llvm::StructType *T, unsigned Idx, - const llvm::CallBase *CallSite) { - if (!VTP) { - return nullptr; - } if (const auto *VT = VTP->getVFTableOrNull(T)) { const auto *Target = VT->getFunction(Idx); if (Target && @@ -208,6 +187,7 @@ Resolver::getNonPureVirtualVFTEntry(const llvm::StructType *T, unsigned Idx, return Target; } } + return nullptr; } diff --git a/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFG_DTATest.cpp b/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFG_DTATest.cpp index 73e3aa948..d3838d840 100644 --- a/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFG_DTATest.cpp +++ b/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFG_DTATest.cpp @@ -11,8 +11,8 @@ using namespace std; using namespace psr; - TEST(LLVMBasedICFG_DTATest, VirtualCallSite_5) { +#if 0 LLVMProjectIRDB IRDB(unittest::PathToLLTestFiles + "call_graphs/virtual_call_5_cpp.ll"); DIBasedTypeHierarchy TH(IRDB); @@ -38,9 +38,11 @@ TEST(LLVMBasedICFG_DTATest, VirtualCallSite_5) { ASSERT_TRUE(llvm::is_contained(ICFG.getCallersOf(VFuncA), I)); ASSERT_TRUE(llvm::is_contained(ICFG.getCallersOf(VFuncB), I)); } +#endif } TEST(LLVMBasedICFG_DTATest, VirtualCallSite_6) { +#if 0 LLVMProjectIRDB IRDB(unittest::PathToLLTestFiles + "call_graphs/virtual_call_6_cpp.ll"); DIBasedTypeHierarchy TH(IRDB); @@ -57,6 +59,7 @@ TEST(LLVMBasedICFG_DTATest, VirtualCallSite_6) { const auto &Callers = ICFG.getCallersOf(VFuncA); ASSERT_EQ(Callers.size(), 1U); ASSERT_TRUE(llvm::is_contained(Callers, I)); +#endif } int main(int Argc, char **Argv) { diff --git a/unittests/PhasarLLVM/ControlFlow/LLVMVFTableProviderTest.cpp b/unittests/PhasarLLVM/ControlFlow/LLVMVFTableProviderTest.cpp index 1608749eb..54ef8b0d7 100644 --- a/unittests/PhasarLLVM/ControlFlow/LLVMVFTableProviderTest.cpp +++ b/unittests/PhasarLLVM/ControlFlow/LLVMVFTableProviderTest.cpp @@ -6,6 +6,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/Demangle/Demangle.h" +#include "llvm/IR/DebugInfoMetadata.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/Module.h" #include "llvm/IR/Value.h" @@ -20,25 +21,26 @@ namespace { using llvm::demangle; -static const llvm::StructType *getType(const LLVMProjectIRDB &IRDB, - llvm::StringRef Name) { - // TODO: Optimize - for (const auto *Ty : IRDB.getModule()->getIdentifiedStructTypes()) { - if (Ty->getName() == Name) { - return Ty; - } - } - return nullptr; -} - -static const llvm::DIType *getDIType(const LLVMProjectIRDB &IRDB, - llvm::StringRef Name) { +static const llvm::DIType *getType(const LLVMProjectIRDB &IRDB, + llvm::StringRef Name) { // TODO: Optimize for (const auto *Instr : IRDB.getAllInstructions()) { if (const auto *Val = llvm::dyn_cast(Instr)) { if (const auto *DILocVal = getDILocalVariable(Val)) { - if (DILocVal->getName() == Name) { - return DILocVal->getType(); + // case: is DIDerivedType + if (const auto *DerivedTy = + llvm::dyn_cast(DILocVal->getType())) { + if (const auto *DITy = DerivedTy->getBaseType()) { + if (DITy->getName() == Name) { + return DITy; + } + } + } + // case: isn't DIDerivedType + if (const auto *DITy = DILocVal->getType()) { + if (DITy->getName() == Name) { + return DITy; + } } } } @@ -50,138 +52,147 @@ static const llvm::DIType *getDIType(const LLVMProjectIRDB &IRDB, TEST(VTableTest, VTableConstruction_01) { LLVMProjectIRDB IRDB({unittest::PathToLLTestFiles + - "type_hierarchies/type_hierarchy_1_cpp.ll"}); + "type_hierarchies/type_hierarchy_1_cpp_dbg.ll"}); LLVMVFTableProvider TH(IRDB); // TODO } TEST(VTableTest, VTableConstruction_02) { LLVMProjectIRDB IRDB({unittest::PathToLLTestFiles + - "type_hierarchies/type_hierarchy_7_cpp.ll"}); + "type_hierarchies/type_hierarchy_7_cpp_dbg.ll"}); LLVMVFTableProvider TH(IRDB); // TODO } TEST(VTableTest, VTableConstruction_03) { LLVMProjectIRDB IRDB({unittest::PathToLLTestFiles + - "type_hierarchies/type_hierarchy_8_cpp.ll"}); + "type_hierarchies/type_hierarchy_8_cpp_dbg.ll"}); LLVMVFTableProvider TH(IRDB); - ASSERT_TRUE(TH.hasVFTable(getType(IRDB, "struct.Base"))); - ASSERT_TRUE(TH.hasVFTable(getType(IRDB, "struct.Child"))); + ASSERT_TRUE(TH.hasVFTable(getType(IRDB, "Base"))); + ASSERT_TRUE(TH.hasVFTable(getType(IRDB, "Child"))); + + llvm::outs() << "AllFuncs:\n"; + for (const auto *CurrFunc : + TH.getVFTableOrNull(getType(IRDB, "Base"))->getAllFunctions()) { + llvm::outs() << CurrFunc << "\n"; + } + + llvm::outs() << "getFunction(0)\n" + << TH.getVFTableOrNull(getType(IRDB, "Base"))->getFunction(0) + << "\n"; - EXPECT_EQ(demangle(TH.getVFTableOrNull(getType(IRDB, "struct.Base")) + EXPECT_EQ(demangle(TH.getVFTableOrNull(getType(IRDB, "Base")) ->getFunction(0) ->getName() .str()), "Base::foo()"); - EXPECT_EQ(demangle(TH.getVFTableOrNull(getType(IRDB, "struct.Base")) + EXPECT_EQ(demangle(TH.getVFTableOrNull(getType(IRDB, "Base")) ->getFunction(1) ->getName() .str()), "Base::bar()"); - EXPECT_EQ(TH.getVFTableOrNull(getType(IRDB, "struct.Base"))->size(), 2U); - EXPECT_EQ(demangle(TH.getVFTableOrNull(getType(IRDB, "struct.Child")) + EXPECT_EQ(TH.getVFTableOrNull(getType(IRDB, "Base"))->size(), 2U); + EXPECT_EQ(demangle(TH.getVFTableOrNull(getType(IRDB, "Child")) ->getFunction(0) ->getName() .str()), "Child::foo()"); - EXPECT_EQ(demangle(TH.getVFTableOrNull(getType(IRDB, "struct.Child")) + EXPECT_EQ(demangle(TH.getVFTableOrNull(getType(IRDB, "Child")) ->getFunction(1) ->getName() .str()), "Base::bar()"); - EXPECT_EQ(demangle(TH.getVFTableOrNull(getType(IRDB, "struct.Child")) + EXPECT_EQ(demangle(TH.getVFTableOrNull(getType(IRDB, "Child")) ->getFunction(2) ->getName() .str()), "Child::baz()"); - EXPECT_EQ(TH.getVFTableOrNull(getType(IRDB, "struct.Child"))->size(), 3U); + EXPECT_EQ(TH.getVFTableOrNull(getType(IRDB, "Child"))->size(), 3U); } TEST(VTableTest, VTableConstruction_04) { LLVMProjectIRDB IRDB({unittest::PathToLLTestFiles + - "type_hierarchies/type_hierarchy_9_cpp.ll"}); + "type_hierarchies/type_hierarchy_9_cpp_dbg.ll"}); LLVMVFTableProvider TH(IRDB); - ASSERT_TRUE(TH.hasVFTable(getType(IRDB, "struct.Base.base"))); - ASSERT_TRUE(TH.hasVFTable(getType(IRDB, "struct.Child"))); + ASSERT_TRUE(TH.hasVFTable(getType(IRDB, "Base"))); + ASSERT_TRUE(TH.hasVFTable(getType(IRDB, "Child"))); - EXPECT_EQ(demangle(TH.getVFTableOrNull(getType(IRDB, "struct.Base.base")) + EXPECT_EQ(demangle(TH.getVFTableOrNull(getType(IRDB, "Base")) ->getFunction(0) ->getName() .str()), "Base::foo()"); - EXPECT_EQ(demangle(TH.getVFTableOrNull(getType(IRDB, "struct.Base.base")) + EXPECT_EQ(demangle(TH.getVFTableOrNull(getType(IRDB, "Base")) ->getFunction(1) ->getName() .str()), "Base::bar()"); - EXPECT_EQ(TH.getVFTableOrNull(getType(IRDB, "struct.Base.base"))->size(), 2U); - EXPECT_EQ(demangle(TH.getVFTableOrNull(getType(IRDB, "struct.Child")) + EXPECT_EQ(TH.getVFTableOrNull(getType(IRDB, "Base"))->size(), 2U); + EXPECT_EQ(demangle(TH.getVFTableOrNull(getType(IRDB, "Child")) ->getFunction(0) ->getName() .str()), "Child::foo()"); - EXPECT_EQ(demangle(TH.getVFTableOrNull(getType(IRDB, "struct.Child")) + EXPECT_EQ(demangle(TH.getVFTableOrNull(getType(IRDB, "Child")) ->getFunction(1) ->getName() .str()), "Base::bar()"); - EXPECT_EQ(demangle(TH.getVFTableOrNull(getType(IRDB, "struct.Child")) + EXPECT_EQ(demangle(TH.getVFTableOrNull(getType(IRDB, "Child")) ->getFunction(2) ->getName() .str()), "Child::baz()"); - EXPECT_EQ(TH.getVFTableOrNull(getType(IRDB, "struct.Child"))->size(), 3U); + EXPECT_EQ(TH.getVFTableOrNull(getType(IRDB, "Child"))->size(), 3U); } TEST(VTableTest, VTableConstruction_05) { LLVMProjectIRDB IRDB({unittest::PathToLLTestFiles + - "type_hierarchies/type_hierarchy_10_cpp.ll"}); + "type_hierarchies/type_hierarchy_10_cpp_dbg.ll"}); LLVMVFTableProvider TH(IRDB); - ASSERT_TRUE(TH.hasVFTable(getType(IRDB, "struct.Base.base"))); - ASSERT_TRUE(TH.hasVFTable(getType(IRDB, "struct.Child"))); + ASSERT_TRUE(TH.hasVFTable(getType(IRDB, "Child"))); + ASSERT_TRUE(TH.hasVFTable(getType(IRDB, "Child"))); - EXPECT_EQ(demangle(TH.getVFTableOrNull(getType(IRDB, "struct.Base.base")) + EXPECT_EQ(demangle(TH.getVFTableOrNull(getType(IRDB, "Base")) ->getFunction(0) ->getName() .str()), "__cxa_pure_virtual"); - EXPECT_EQ(demangle(TH.getVFTableOrNull(getType(IRDB, "struct.Base.base")) + EXPECT_EQ(demangle(TH.getVFTableOrNull(getType(IRDB, "Base")) ->getFunction(1) ->getName() .str()), "Base::bar()"); - EXPECT_EQ(TH.getVFTableOrNull(getType(IRDB, "struct.Base.base"))->size(), 2U); - EXPECT_EQ(demangle(TH.getVFTableOrNull(getType(IRDB, "struct.Child")) + EXPECT_EQ(TH.getVFTableOrNull(getType(IRDB, "Base"))->size(), 2U); + EXPECT_EQ(demangle(TH.getVFTableOrNull(getType(IRDB, "Child")) ->getFunction(0) ->getName() .str()), "Child::foo()"); - EXPECT_EQ(demangle(TH.getVFTableOrNull(getType(IRDB, "struct.Child")) + EXPECT_EQ(demangle(TH.getVFTableOrNull(getType(IRDB, "Child")) ->getFunction(1) ->getName() .str()), "Base::bar()"); - EXPECT_EQ(demangle(TH.getVFTableOrNull(getType(IRDB, "struct.Child")) + EXPECT_EQ(demangle(TH.getVFTableOrNull(getType(IRDB, "Child")) ->getFunction(2) ->getName() .str()), "Child::baz()"); - EXPECT_EQ(TH.getVFTableOrNull(getType(IRDB, "struct.Child"))->size(), 3U); + EXPECT_EQ(TH.getVFTableOrNull(getType(IRDB, "Child"))->size(), 3U); } TEST(VTableTest, VTableConstruction_6) { LLVMProjectIRDB IRDB({unittest::PathToLLTestFiles + - "type_hierarchies/type_hierarchy_14_cpp.ll"}); + "type_hierarchies/type_hierarchy_14_cpp_dbg.ll"}); LLVMVFTableProvider TH(IRDB); - ASSERT_TRUE(TH.hasVFTable(getDIType(IRDB, "class.Base.base"))); - EXPECT_EQ(TH.getVFTableOrNull(getDIType(IRDB, "class.Base.base"))->size(), - 3U); + ASSERT_TRUE(TH.hasVFTable(getType(IRDB, "Base"))); + EXPECT_EQ(TH.getVFTableOrNull(getType(IRDB, "Base"))->size(), 3U); } } // namespace From 16c4a8e1e777d65501766aa602df6bd2b3b4ed71 Mon Sep 17 00:00:00 2001 From: mxHuber Date: Mon, 1 Jul 2024 12:43:50 +0200 Subject: [PATCH 34/78] Fixed OTFTest --- .../PhasarLLVM/ControlFlow/LLVMBasedICFG_OTFTest.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFG_OTFTest.cpp b/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFG_OTFTest.cpp index 69c26705c..6509fd0be 100644 --- a/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFG_OTFTest.cpp +++ b/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFG_OTFTest.cpp @@ -32,14 +32,14 @@ TEST(LLVMBasedICFG_OTFTest, VirtualCallSite_7) { ASSERT_TRUE(VFuncA); ASSERT_TRUE(VFuncB); - const auto *CallToAFunc = getNthInstruction(F, 22); + const auto *CallToAFunc = getNthInstruction(F, 17); ASSERT_TRUE(ICFG.isVirtualFunctionCall(CallToAFunc)); const auto &AsCallees = ICFG.getCalleesOfCallAt(CallToAFunc); ASSERT_EQ(AsCallees.size(), 2U); ASSERT_TRUE(llvm::is_contained(AsCallees, VFuncA)); ASSERT_TRUE(llvm::is_contained(ICFG.getCallersOf(VFuncA), CallToAFunc)); - const auto *CallToBFunc = getNthInstruction(F, 29); + const auto *CallToBFunc = getNthInstruction(F, 22); ASSERT_TRUE(ICFG.isVirtualFunctionCall(CallToBFunc)); const auto &BsCallees = ICFG.getCalleesOfCallAt(CallToBFunc); ASSERT_EQ(BsCallees.size(), 2U); @@ -79,7 +79,7 @@ TEST(LLVMBasedICFG_OTFTest, FunctionPtrCall_2) { const llvm::Function *Main = IRDB.getFunctionDefinition("main"); const llvm::Function *Bar = IRDB.getFunctionDefinition("_Z3barv"); - const auto *FPtrCall = getNthInstruction(Main, 7); + const auto *FPtrCall = getNthInstruction(Main, 9); const auto &Callees = ICFG.getCalleesOfCallAt(FPtrCall); auto printCallees // NOLINT @@ -117,7 +117,8 @@ TEST(LLVMBasedICFG_OTFTest, FunctionPtrCall_3) { const llvm::Function *Main = IRDB.getFunctionDefinition("main"); const llvm::Function *Foo = IRDB.getFunctionDefinition("_Z3foov"); - const auto *FPtrCall = getNthInstruction(Main, 8); + const auto *FPtrCall = getNthInstruction(Main, 10); + const auto &Callees = ICFG.getCalleesOfCallAt(FPtrCall); ASSERT_EQ(Callees.size(), 1U); From 0514c7def6d8a6c36c0389ab24bb59de46c32aa0 Mon Sep 17 00:00:00 2001 From: mxHuber Date: Mon, 1 Jul 2024 14:56:16 +0200 Subject: [PATCH 35/78] trimmed trailing whitespace --- lib/PhasarLLVM/ControlFlow/Resolver/DTAResolver.cpp | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/lib/PhasarLLVM/ControlFlow/Resolver/DTAResolver.cpp b/lib/PhasarLLVM/ControlFlow/Resolver/DTAResolver.cpp index b6731637a..7863c024a 100644 --- a/lib/PhasarLLVM/ControlFlow/Resolver/DTAResolver.cpp +++ b/lib/PhasarLLVM/ControlFlow/Resolver/DTAResolver.cpp @@ -46,9 +46,7 @@ DTAResolver::DTAResolver(const LLVMProjectIRDB *IRDB, bool DTAResolver::heuristicAntiConstructorThisType( const llvm::BitCastInst *BitCast) { - llvm::report_fatal_error("Does not work with opaque pointers anymore"); - #if 0 // We check if the caller is a constructor, and if the this argument has the // same type as the source type of the bitcast. If it is the case, it returns @@ -72,10 +70,8 @@ bool DTAResolver::heuristicAntiConstructorThisType( bool DTAResolver::heuristicAntiConstructorVtablePos( const llvm::BitCastInst *BitCast) { - llvm::report_fatal_error("Does not work with opaque pointers anymore"); - -#if 0 +#if 0 // Better heuristic than the previous one, can handle the CRTP. Based on the // previous one. @@ -158,9 +154,7 @@ bool DTAResolver::heuristicAntiConstructorVtablePos( } void DTAResolver::otherInst(const llvm::Instruction *Inst) { - llvm::report_fatal_error("Does not work with opaque pointers anymore"); - #if 0 if (Inst->getType()->isOpaquePointerTy()) { /// XXX: We may want to get these information on a different way, e.g. by @@ -187,7 +181,6 @@ void DTAResolver::otherInst(const llvm::Instruction *Inst) { auto DTAResolver::resolveVirtualCall(const llvm::CallBase *CallSite) -> FunctionSetTy { llvm::report_fatal_error("Does not work with opaque pointers anymore"); - #if 0 FunctionSetTy PossibleCallTargets; From 2d8c9d8ee4ad13d090c1108930938b5ba7731f20 Mon Sep 17 00:00:00 2001 From: mxHuber Date: Wed, 10 Jul 2024 10:44:06 +0200 Subject: [PATCH 36/78] minor fixes --- .../PhasarLLVM/ControlFlow/LLVMBasedICFG.h | 5 ---- .../ControlFlow/Resolver/DTAResolver.h | 23 ++++++++----------- .../ControlFlow/Resolver/Resolver.h | 3 --- .../TypeHierarchy/DIBasedTypeHierarchy.h | 1 - lib/PhasarLLVM/ControlFlow/LLVMBasedICFG.cpp | 23 +++++++++---------- .../ControlFlow/LLVMVFTableProvider.cpp | 4 ++-- .../ControlFlow/Resolver/Resolver.cpp | 14 +---------- .../TypeHierarchy/DIBasedTypeHierarchy.cpp | 13 ----------- 8 files changed, 23 insertions(+), 63 deletions(-) diff --git a/include/phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h b/include/phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h index dd363f5c8..e513ea0c8 100644 --- a/include/phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h +++ b/include/phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h @@ -34,10 +34,6 @@ #include "llvm/IR/Value.h" #include "llvm/Support/raw_ostream.h" -#include "nlohmann/json.hpp" - -#include - namespace psr { class DIBasedTypeHierarchy; class LLVMProjectIRDB; @@ -174,7 +170,6 @@ class LLVMBasedICFG : public LLVMBasedCFG, public ICFGBase { CallGraph CG; LLVMProjectIRDB *IRDB = nullptr; LLVMVFTableProvider VTP; - std::map DITypeToValueType; }; extern template class ICFGBase; diff --git a/include/phasar/PhasarLLVM/ControlFlow/Resolver/DTAResolver.h b/include/phasar/PhasarLLVM/ControlFlow/Resolver/DTAResolver.h index 0c047c950..56d00a707 100644 --- a/include/phasar/PhasarLLVM/ControlFlow/Resolver/DTAResolver.h +++ b/include/phasar/PhasarLLVM/ControlFlow/Resolver/DTAResolver.h @@ -34,7 +34,8 @@ class BitCastInst; namespace psr { -class DTAResolver : public CHAResolver { +class [[deprecated("Does not work with opaque pointers anymore")]] DTAResolver + : public CHAResolver { public: using TypeGraph_t = CachedTypeGraph; @@ -45,7 +46,7 @@ class DTAResolver : public CHAResolver { * An heuristic that return true if the bitcast instruction is interesting to * take into the DTA relational graph */ - [[deprecated("Does not work with opaque pointers anymore")]] static bool + static bool heuristicAntiConstructorThisType(const llvm::BitCastInst *BitCast); /** @@ -53,25 +54,19 @@ class DTAResolver : public CHAResolver { * interesting to take into the DTA relational graph (use the presence or not * of vtable) */ - [[deprecated("Does not work with opaque pointers anymore")]] bool - heuristicAntiConstructorVtablePos(const llvm::BitCastInst *BitCast); + bool heuristicAntiConstructorVtablePos(const llvm::BitCastInst *BitCast); public: - [[deprecated("Does not work with opaque pointers anymore")]] DTAResolver( - const LLVMProjectIRDB *IRDB, const LLVMVFTableProvider *VTP, - const DIBasedTypeHierarchy *TH); + DTAResolver(const LLVMProjectIRDB *IRDB, const LLVMVFTableProvider *VTP, + const DIBasedTypeHierarchy *TH); ~DTAResolver() override = default; - [[deprecated("Does not work with opaque pointers anymore")]] FunctionSetTy - resolveVirtualCall(const llvm::CallBase *CallSite) override; + FunctionSetTy resolveVirtualCall(const llvm::CallBase *CallSite) override; - [[deprecated("Does not work with opaque pointers anymore")]] void - otherInst(const llvm::Instruction *Inst) override; + void otherInst(const llvm::Instruction *Inst) override; - [[nodiscard]] [[deprecated( - "Does not work with opaque pointers anymore")]] std::string - str() const override; + [[nodiscard]] std::string str() const override; }; } // namespace psr diff --git a/include/phasar/PhasarLLVM/ControlFlow/Resolver/Resolver.h b/include/phasar/PhasarLLVM/ControlFlow/Resolver/Resolver.h index 45cd13c2f..7442a4999 100644 --- a/include/phasar/PhasarLLVM/ControlFlow/Resolver/Resolver.h +++ b/include/phasar/PhasarLLVM/ControlFlow/Resolver/Resolver.h @@ -57,11 +57,8 @@ class Resolver { protected: const LLVMProjectIRDB *IRDB; const LLVMVFTableProvider *VTP; - std::map DITypeToType; - std::map TypeToDIType; Resolver(const LLVMProjectIRDB *IRDB); - void initializeTypeMap(); const llvm::Function * getNonPureVirtualVFTEntry(const llvm::DIType *T, unsigned Idx, diff --git a/include/phasar/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.h b/include/phasar/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.h index 9bb317803..aa260bab3 100644 --- a/include/phasar/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.h +++ b/include/phasar/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.h @@ -43,7 +43,6 @@ class DIBasedTypeHierarchy ~DIBasedTypeHierarchy() override = default; static bool isVTable(llvm::StringRef VarName); - static std::string removeStructOrClassPrefix(llvm::StringRef TypeName); static std::string removeVTablePrefix(llvm::StringRef VarName); [[nodiscard]] bool hasType(ClassType Type) const override { diff --git a/lib/PhasarLLVM/ControlFlow/LLVMBasedICFG.cpp b/lib/PhasarLLVM/ControlFlow/LLVMBasedICFG.cpp index 6ebd3af3d..0afffd715 100644 --- a/lib/PhasarLLVM/ControlFlow/LLVMBasedICFG.cpp +++ b/lib/PhasarLLVM/ControlFlow/LLVMBasedICFG.cpp @@ -20,7 +20,6 @@ #include "phasar/PhasarLLVM/Utils/LLVMBasedContainerConfig.h" #include "phasar/PhasarLLVM/Utils/LLVMShorthands.h" #include "phasar/Utils/Logger.h" -#include "phasar/Utils/MaybeUniquePtr.h" #include "phasar/Utils/PAMMMacros.h" #include "phasar/Utils/Soundness.h" @@ -178,8 +177,8 @@ bool LLVMBasedICFG::Builder::processFunction(const llvm::Function *F) { PossibleTargets.insert(CS->getCalledFunction()); PHASAR_LOG_LEVEL_CAT(DEBUG, "LLVMBasedICFG", - "Found static call-site: " - << " " << llvmIRToString(CS)); + "Found static call-site: " << " " + << llvmIRToString(CS)); } else { // still try to resolve the called function statically const llvm::Value *SV = CS->getCalledOperand()->stripPointerCasts(); @@ -195,9 +194,9 @@ bool LLVMBasedICFG::Builder::processFunction(const llvm::Function *F) { continue; } // the function call must be resolved dynamically - PHASAR_LOG_LEVEL_CAT(DEBUG, "LLVMBasedICFG", - "Found dynamic call-site: " - << " " << llvmIRToString(CS)); + PHASAR_LOG_LEVEL_CAT( + DEBUG, "LLVMBasedICFG", + "Found dynamic call-site: " << " " << llvmIRToString(CS)); IndirectCalls[CS] = 0; std::ignore = CGBuilder.addInstructionVertex(CS); @@ -400,8 +399,8 @@ bool LLVMBasedICFG::isPhasarGenerated(const llvm::Function &F) noexcept { return IRDB->getAllFunctions(); } -[[nodiscard]] auto LLVMBasedICFG::getFunctionImpl(llvm::StringRef Fun) const - -> f_t { +[[nodiscard]] auto +LLVMBasedICFG::getFunctionImpl(llvm::StringRef Fun) const -> f_t { return IRDB->getFunction(Fun); } @@ -414,8 +413,8 @@ bool LLVMBasedICFG::isPhasarGenerated(const llvm::Function &F) noexcept { return internalIsVirtualFunctionCall(Inst, VTP); } -[[nodiscard]] auto LLVMBasedICFG::allNonCallStartNodesImpl() const - -> std::vector { +[[nodiscard]] auto +LLVMBasedICFG::allNonCallStartNodesImpl() const -> std::vector { std::vector NonCallStartNodes; NonCallStartNodes.reserve(2 * IRDB->getNumFunctions()); for (const auto *Inst : IRDB->getAllInstructions()) { @@ -427,8 +426,8 @@ bool LLVMBasedICFG::isPhasarGenerated(const llvm::Function &F) noexcept { return NonCallStartNodes; } -[[nodiscard]] auto LLVMBasedICFG::getCallsFromWithinImpl(f_t Fun) const - -> llvm::SmallVector { +[[nodiscard]] auto +LLVMBasedICFG::getCallsFromWithinImpl(f_t Fun) const -> llvm::SmallVector { llvm::SmallVector CallSites; for (const auto &I : llvm::instructions(Fun)) { if (llvm::isa(I)) { diff --git a/lib/PhasarLLVM/ControlFlow/LLVMVFTableProvider.cpp b/lib/PhasarLLVM/ControlFlow/LLVMVFTableProvider.cpp index a96052a15..c3ab17624 100644 --- a/lib/PhasarLLVM/ControlFlow/LLVMVFTableProvider.cpp +++ b/lib/PhasarLLVM/ControlFlow/LLVMVFTableProvider.cpp @@ -6,11 +6,11 @@ #include "phasar/PhasarLLVM/Utils/LLVMIRToSrc.h" #include "phasar/Utils/Logger.h" +#include "llvm/ADT/StringRef.h" #include "llvm/BinaryFormat/Dwarf.h" #include "llvm/Demangle/Demangle.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DebugInfoMetadata.h" -#include "llvm/IR/DerivedTypes.h" #include "llvm/IR/Module.h" #include "llvm/Support/Casting.h" @@ -30,7 +30,7 @@ static std::vector getVirtualFunctions( const llvm::DIType *Type) { auto ClearName = getTypeName(Type); - if (ClearName.substr(0, 18) == "typeinfo name for ") { + if (llvm::StringRef(ClearName).startswith("typeinfo name for ")) { ClearName = ClearName.substr(18, ClearName.size() - 1); } diff --git a/lib/PhasarLLVM/ControlFlow/Resolver/Resolver.cpp b/lib/PhasarLLVM/ControlFlow/Resolver/Resolver.cpp index c651ec106..e807ef2fd 100644 --- a/lib/PhasarLLVM/ControlFlow/Resolver/Resolver.cpp +++ b/lib/PhasarLLVM/ControlFlow/Resolver/Resolver.cpp @@ -164,12 +164,11 @@ namespace psr { Resolver::Resolver(const LLVMProjectIRDB *IRDB) : IRDB(IRDB), VTP(nullptr) { assert(IRDB != nullptr); - initializeTypeMap(); } Resolver::Resolver(const LLVMProjectIRDB *IRDB, const LLVMVFTableProvider *VTP) : IRDB(IRDB), VTP(VTP) { - initializeTypeMap(); + assert(IRDB != nullptr); } const llvm::Function * @@ -252,15 +251,4 @@ std::unique_ptr Resolver::create(CallGraphAnalysisType Ty, "above switch"); } -void Resolver::initializeTypeMap() { - for (const auto *Instr : IRDB->getAllInstructions()) { - if (const auto *Val = llvm::dyn_cast(Instr)) { - if (const auto *DITy = getDILocalVariable(Val)) { - DITypeToType[DITy->getType()] = Val->getType(); - TypeToDIType[Val->getType()] = DITy->getType(); - } - } - } -} - } // namespace psr diff --git a/lib/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.cpp b/lib/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.cpp index 493dc456f..c0241ccd4 100644 --- a/lib/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.cpp +++ b/lib/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.cpp @@ -216,19 +216,6 @@ bool DIBasedTypeHierarchy::isVTable(llvm::StringRef VarName) { return llvm::StringRef(Demang).startswith(VTablePrefixDemang); } -std::string -DIBasedTypeHierarchy::removeStructOrClassPrefix(llvm::StringRef TypeName) { - if (TypeName.startswith(StructPrefix)) { - TypeName = TypeName.drop_front(StructPrefix.size()); - } else if (TypeName.startswith(ClassPrefix)) { - TypeName = TypeName.drop_front(ClassPrefix.size()); - } - if (TypeName.endswith(".base")) { - TypeName = TypeName.drop_back(llvm::StringRef(".base").size()); - } - return TypeName.str(); -} - std::string DIBasedTypeHierarchy::removeVTablePrefix(llvm::StringRef VarName) { if (VarName.startswith(VTablePrefixDemang)) { return VarName.drop_front(VTablePrefixDemang.size()).str(); From 446362527e46068e54e28f54e199164cbe68a251 Mon Sep 17 00:00:00 2001 From: mxHuber Date: Wed, 10 Jul 2024 12:30:20 +0200 Subject: [PATCH 37/78] readded TypeToDIType map for RTAResolver --- .../PhasarLLVM/ControlFlow/Resolver/RTAResolver.h | 1 + lib/PhasarLLVM/ControlFlow/Resolver/RTAResolver.cpp | 10 ++++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/include/phasar/PhasarLLVM/ControlFlow/Resolver/RTAResolver.h b/include/phasar/PhasarLLVM/ControlFlow/Resolver/RTAResolver.h index a17ceedc3..08953a53f 100644 --- a/include/phasar/PhasarLLVM/ControlFlow/Resolver/RTAResolver.h +++ b/include/phasar/PhasarLLVM/ControlFlow/Resolver/RTAResolver.h @@ -44,6 +44,7 @@ class RTAResolver : public CHAResolver { void resolveAllocatedStructTypes(); std::vector AllocatedStructTypes; + std::map TypeToDIType; }; } // namespace psr diff --git a/lib/PhasarLLVM/ControlFlow/Resolver/RTAResolver.cpp b/lib/PhasarLLVM/ControlFlow/Resolver/RTAResolver.cpp index 12120ac62..0a77b05c5 100644 --- a/lib/PhasarLLVM/ControlFlow/Resolver/RTAResolver.cpp +++ b/lib/PhasarLLVM/ControlFlow/Resolver/RTAResolver.cpp @@ -23,8 +23,6 @@ #include "phasar/Utils/Logger.h" #include "phasar/Utils/Utilities.h" -#include "llvm/ADT/StringSet.h" -#include "llvm/IR/Constants.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/Function.h" #include "llvm/IR/InstIterator.h" @@ -41,6 +39,14 @@ RTAResolver::RTAResolver(const LLVMProjectIRDB *IRDB, const DIBasedTypeHierarchy *TH) : CHAResolver(IRDB, VTP, TH) { resolveAllocatedStructTypes(); + + for (const auto *Instr : IRDB->getAllInstructions()) { + if (const auto *Val = llvm::dyn_cast(Instr)) { + if (const auto *DITy = getDILocalVariable(Val)) { + TypeToDIType[Val->getType()] = DITy->getType(); + } + } + } } auto RTAResolver::resolveVirtualCall(const llvm::CallBase *CallSite) From df7d1908cb264ffae26f331f04e401315ce79c8e Mon Sep 17 00:00:00 2001 From: mxHuber Date: Wed, 10 Jul 2024 12:37:19 +0200 Subject: [PATCH 38/78] pre-commit clang-format fix --- include/phasar/PhasarLLVM/ControlFlow/Resolver/DTAResolver.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/include/phasar/PhasarLLVM/ControlFlow/Resolver/DTAResolver.h b/include/phasar/PhasarLLVM/ControlFlow/Resolver/DTAResolver.h index 56d00a707..a93721c25 100644 --- a/include/phasar/PhasarLLVM/ControlFlow/Resolver/DTAResolver.h +++ b/include/phasar/PhasarLLVM/ControlFlow/Resolver/DTAResolver.h @@ -46,13 +46,14 @@ class [[deprecated("Does not work with opaque pointers anymore")]] DTAResolver * An heuristic that return true if the bitcast instruction is interesting to * take into the DTA relational graph */ - static bool - heuristicAntiConstructorThisType(const llvm::BitCastInst *BitCast); + static bool heuristicAntiConstructorThisType( + const llvm::BitCastInst *BitCast); /** * Another heuristic that return true if the bitcast instruction is * interesting to take into the DTA relational graph (use the presence or not * of vtable) + */ bool heuristicAntiConstructorVtablePos(const llvm::BitCastInst *BitCast); From ce2c6e8974ae2ddab842d4e8017fd597e7ff257a Mon Sep 17 00:00:00 2001 From: mxHuber Date: Wed, 10 Jul 2024 12:41:30 +0200 Subject: [PATCH 39/78] pre-commit clang-format llvmbasedicfg.cpp --- lib/PhasarLLVM/ControlFlow/LLVMBasedICFG.cpp | 24 ++++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/lib/PhasarLLVM/ControlFlow/LLVMBasedICFG.cpp b/lib/PhasarLLVM/ControlFlow/LLVMBasedICFG.cpp index 0afffd715..6deae92cb 100644 --- a/lib/PhasarLLVM/ControlFlow/LLVMBasedICFG.cpp +++ b/lib/PhasarLLVM/ControlFlow/LLVMBasedICFG.cpp @@ -105,7 +105,7 @@ void LLVMBasedICFG::Builder::initGlobalsAndWorkList(LLVMBasedICFG *ICFG, UserEntryPoints.end()); } // Note: Pre-allocate the call-graph builder *after* adding the - // CRuntimeGlobalCtorsDtorsModel + // CRuntimeGlobalCtorsDtorsModel. CGBuilder.reserve(IRDB->getNumFunctions()); } @@ -177,8 +177,8 @@ bool LLVMBasedICFG::Builder::processFunction(const llvm::Function *F) { PossibleTargets.insert(CS->getCalledFunction()); PHASAR_LOG_LEVEL_CAT(DEBUG, "LLVMBasedICFG", - "Found static call-site: " << " " - << llvmIRToString(CS)); + "Found static call-site: " + << " " << llvmIRToString(CS)); } else { // still try to resolve the called function statically const llvm::Value *SV = CS->getCalledOperand()->stripPointerCasts(); @@ -194,9 +194,9 @@ bool LLVMBasedICFG::Builder::processFunction(const llvm::Function *F) { continue; } // the function call must be resolved dynamically - PHASAR_LOG_LEVEL_CAT( - DEBUG, "LLVMBasedICFG", - "Found dynamic call-site: " << " " << llvmIRToString(CS)); + PHASAR_LOG_LEVEL_CAT(DEBUG, "LLVMBasedICFG", + "Found dynamic call-site: " + << " " << llvmIRToString(CS)); IndirectCalls[CS] = 0; std::ignore = CGBuilder.addInstructionVertex(CS); @@ -399,8 +399,8 @@ bool LLVMBasedICFG::isPhasarGenerated(const llvm::Function &F) noexcept { return IRDB->getAllFunctions(); } -[[nodiscard]] auto -LLVMBasedICFG::getFunctionImpl(llvm::StringRef Fun) const -> f_t { +[[nodiscard]] auto LLVMBasedICFG::getFunctionImpl(llvm::StringRef Fun) const + -> f_t { return IRDB->getFunction(Fun); } @@ -413,8 +413,8 @@ LLVMBasedICFG::getFunctionImpl(llvm::StringRef Fun) const -> f_t { return internalIsVirtualFunctionCall(Inst, VTP); } -[[nodiscard]] auto -LLVMBasedICFG::allNonCallStartNodesImpl() const -> std::vector { +[[nodiscard]] auto LLVMBasedICFG::allNonCallStartNodesImpl() const + -> std::vector { std::vector NonCallStartNodes; NonCallStartNodes.reserve(2 * IRDB->getNumFunctions()); for (const auto *Inst : IRDB->getAllInstructions()) { @@ -426,8 +426,8 @@ LLVMBasedICFG::allNonCallStartNodesImpl() const -> std::vector { return NonCallStartNodes; } -[[nodiscard]] auto -LLVMBasedICFG::getCallsFromWithinImpl(f_t Fun) const -> llvm::SmallVector { +[[nodiscard]] auto LLVMBasedICFG::getCallsFromWithinImpl(f_t Fun) const + -> llvm::SmallVector { llvm::SmallVector CallSites; for (const auto &I : llvm::instructions(Fun)) { if (llvm::isa(I)) { From 8a4d81251170e64093a2769ee1eac28a7b4f26f8 Mon Sep 17 00:00:00 2001 From: mxHuber Date: Wed, 10 Jul 2024 13:05:02 +0200 Subject: [PATCH 40/78] moved RTAResolver to DITypes --- .../ControlFlow/Resolver/RTAResolver.h | 7 +- .../ControlFlow/Resolver/RTAResolver.cpp | 93 +++++-------------- 2 files changed, 26 insertions(+), 74 deletions(-) diff --git a/include/phasar/PhasarLLVM/ControlFlow/Resolver/RTAResolver.h b/include/phasar/PhasarLLVM/ControlFlow/Resolver/RTAResolver.h index 08953a53f..498440668 100644 --- a/include/phasar/PhasarLLVM/ControlFlow/Resolver/RTAResolver.h +++ b/include/phasar/PhasarLLVM/ControlFlow/Resolver/RTAResolver.h @@ -19,6 +19,8 @@ #include "phasar/PhasarLLVM/ControlFlow/Resolver/CHAResolver.h" +#include "llvm/IR/DebugInfoMetadata.h" + #include namespace llvm { @@ -41,10 +43,9 @@ class RTAResolver : public CHAResolver { [[nodiscard]] std::string str() const override; private: - void resolveAllocatedStructTypes(); + void resolveAllocatedCompositeTypes(); - std::vector AllocatedStructTypes; - std::map TypeToDIType; + std::vector AllocatedCompositeTypes; }; } // namespace psr diff --git a/lib/PhasarLLVM/ControlFlow/Resolver/RTAResolver.cpp b/lib/PhasarLLVM/ControlFlow/Resolver/RTAResolver.cpp index 0a77b05c5..58ad46ff5 100644 --- a/lib/PhasarLLVM/ControlFlow/Resolver/RTAResolver.cpp +++ b/lib/PhasarLLVM/ControlFlow/Resolver/RTAResolver.cpp @@ -23,6 +23,7 @@ #include "phasar/Utils/Logger.h" #include "phasar/Utils/Utilities.h" +#include "llvm/IR/DebugInfoMetadata.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/Function.h" #include "llvm/IR/InstIterator.h" @@ -30,6 +31,7 @@ #include "llvm/IR/Instruction.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/Module.h" +#include "llvm/Support/Casting.h" using namespace std; using namespace psr; @@ -38,15 +40,7 @@ RTAResolver::RTAResolver(const LLVMProjectIRDB *IRDB, const LLVMVFTableProvider *VTP, const DIBasedTypeHierarchy *TH) : CHAResolver(IRDB, VTP, TH) { - resolveAllocatedStructTypes(); - - for (const auto *Instr : IRDB->getAllInstructions()) { - if (const auto *Val = llvm::dyn_cast(Instr)) { - if (const auto *DITy = getDILocalVariable(Val)) { - TypeToDIType[Val->getType()] = DITy->getType(); - } - } - } + resolveAllocatedCompositeTypes(); } auto RTAResolver::resolveVirtualCall(const llvm::CallBase *CallSite) @@ -78,17 +72,12 @@ auto RTAResolver::resolveVirtualCall(const llvm::CallBase *CallSite) // also insert all possible subtypes vtable entries auto EndIt = ReachableTypes.end(); - for (const auto *PossibleType : AllocatedStructTypes) { - if (const auto *PossibleTypeStruct = - llvm::dyn_cast(PossibleType)) { - if (const auto *Ty = llvm::dyn_cast(PossibleTypeStruct)) { - if (ReachableTypes.find(TypeToDIType[Ty]) != EndIt) { - const auto *Target = getNonPureVirtualVFTEntry(TypeToDIType[Ty], - VtableIndex, CallSite); - if (Target) { - PossibleCallTargets.insert(Target); - } - } + for (const auto *PossibleType : AllocatedCompositeTypes) { + if (ReachableTypes.find(PossibleType) != EndIt) { + const auto *Target = + getNonPureVirtualVFTEntry(PossibleType, VtableIndex, CallSite); + if (Target) { + PossibleCallTargets.insert(Target); } } } @@ -103,61 +92,23 @@ auto RTAResolver::resolveVirtualCall(const llvm::CallBase *CallSite) std::string RTAResolver::str() const { return "RTA"; } /// More or less copied from GeneralStatisticsAnalysis -void RTAResolver::resolveAllocatedStructTypes() { - if (!AllocatedStructTypes.empty()) { +void RTAResolver::resolveAllocatedCompositeTypes() { + if (!AllocatedCompositeTypes.empty()) { return; } - llvm::DenseSet AllocatedStructTypes; - - for (const auto *Fun : IRDB->getAllFunctions()) { - for (const auto &Inst : llvm::instructions(Fun)) { - if (const auto *Alloca = llvm::dyn_cast(&Inst)) { - if (const auto *StructTy = - llvm::dyn_cast(Alloca->getAllocatedType())) { - AllocatedStructTypes.insert(StructTy); - } - } else if (const auto *CallSite = llvm::dyn_cast(&Inst); - CallSite && CallSite->getCalledFunction()) { - // check if an instance of a user-defined type is allocated on the - // heap - - if (!isHeapAllocatingFunction(CallSite->getCalledFunction())) { - continue; - } - /// TODO: Does this iteration over the users make sense? - /// After LLVM 15 we will probably not be able to access the - /// PointerElementType anyway... - for (const auto *User : Inst.users()) { - const auto *Cast = llvm::dyn_cast(User); - if (!Cast || Cast->getDestTy()->isOpaquePointerTy() || - !Cast->getDestTy() - ->getNonOpaquePointerElementType() - ->isStructTy()) { - continue; - } - // finally check for ctor call - for (const auto *User : Cast->users()) { - if (const auto *CTor = llvm::dyn_cast(User)) { - // potential call to the structures ctor - if (CTor->getCalledFunction() && - getNthFunctionArgument(CTor->getCalledFunction(), 0) - ->getType() == Cast->getDestTy() && - !Cast->getDestTy()->isOpaquePointerTy()) { - if (const auto *StructTy = llvm::dyn_cast( - Cast->getDestTy()->getNonOpaquePointerElementType())) { - AllocatedStructTypes.insert(StructTy); - } - } - } - } - } - } + llvm::DebugInfoFinder DIF; + DIF.processModule(*IRDB->getModule()); + llvm::DenseSet AllocatedCompositeTypes; + + for (const auto *Ty : DIF.types()) { + if (const auto *CompTy = llvm::dyn_cast(Ty)) { + AllocatedCompositeTypes.insert(CompTy); } } - this->AllocatedStructTypes.reserve(AllocatedStructTypes.size()); - this->AllocatedStructTypes.insert(this->AllocatedStructTypes.end(), - AllocatedStructTypes.begin(), - AllocatedStructTypes.end()); + this->AllocatedCompositeTypes.reserve(AllocatedCompositeTypes.size()); + this->AllocatedCompositeTypes.insert(this->AllocatedCompositeTypes.end(), + AllocatedCompositeTypes.begin(), + AllocatedCompositeTypes.end()); } From fd11adaadadfce50a87d881ce8a9c767e49b7641 Mon Sep 17 00:00:00 2001 From: mxHuber Date: Sun, 4 Aug 2024 14:36:59 +0200 Subject: [PATCH 41/78] implemented review suggestions --- .../PhasarLLVM/ControlFlow/LLVMBasedICFG.h | 1 - .../ControlFlow/LLVMVFTableProvider.h | 2 - .../ControlFlow/Resolver/CHAResolver.h | 1 - .../ControlFlow/Resolver/RTAResolver.h | 4 +- .../ControlFlow/Resolver/Resolver.h | 5 +- .../PhasarLLVM/Domain/LLVMAnalysisDomain.h | 3 +- .../PhasarLLVM/TypeHierarchy/LLVMVFTable.h | 2 + .../ControlFlow/LLVMVFTableProvider.cpp | 20 +++----- .../ControlFlow/Resolver/CHAResolver.cpp | 1 + .../ControlFlow/Resolver/RTAResolver.cpp | 10 +--- .../ControlFlow/Resolver/Resolver.cpp | 51 ------------------- .../TypeHierarchy/DIBasedTypeHierarchy.cpp | 2 +- tools/example-tool/myphasartool.cpp | 2 + .../ControlFlow/LLVMBasedICFGExportTest.cpp | 8 +-- .../ControlFlow/LLVMBasedICFG_DTATest.cpp | 4 +- .../ControlFlow/LLVMBasedICFG_OTFTest.cpp | 1 + .../Problems/IDEGeneralizedLCATest.cpp | 8 +-- .../IDEInstInteractionAnalysisTest.cpp | 1 - utils/install-llvm-only.sh | 8 --- 19 files changed, 28 insertions(+), 106 deletions(-) delete mode 100644 utils/install-llvm-only.sh diff --git a/include/phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h b/include/phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h index e513ea0c8..ce87d2795 100644 --- a/include/phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h +++ b/include/phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h @@ -23,7 +23,6 @@ #include "phasar/PhasarLLVM/ControlFlow/LLVMBasedCFG.h" #include "phasar/PhasarLLVM/ControlFlow/LLVMVFTableProvider.h" #include "phasar/PhasarLLVM/Pointer/LLVMAliasInfo.h" -#include "phasar/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.h" #include "phasar/PhasarLLVM/Utils/LLVMBasedContainerConfig.h" #include "phasar/Utils/Soundness.h" diff --git a/include/phasar/PhasarLLVM/ControlFlow/LLVMVFTableProvider.h b/include/phasar/PhasarLLVM/ControlFlow/LLVMVFTableProvider.h index ce5d26b54..1fdc8100b 100644 --- a/include/phasar/PhasarLLVM/ControlFlow/LLVMVFTableProvider.h +++ b/include/phasar/PhasarLLVM/ControlFlow/LLVMVFTableProvider.h @@ -12,8 +12,6 @@ #include "phasar/PhasarLLVM/TypeHierarchy/LLVMVFTable.h" -#include "llvm/IR/DebugInfoMetadata.h" - #include namespace llvm { diff --git a/include/phasar/PhasarLLVM/ControlFlow/Resolver/CHAResolver.h b/include/phasar/PhasarLLVM/ControlFlow/Resolver/CHAResolver.h index 0b72ef94f..e38d12db4 100644 --- a/include/phasar/PhasarLLVM/ControlFlow/Resolver/CHAResolver.h +++ b/include/phasar/PhasarLLVM/ControlFlow/Resolver/CHAResolver.h @@ -18,7 +18,6 @@ #define PHASAR_PHASARLLVM_CONTROLFLOW_RESOLVER_CHARESOLVER_H_ #include "phasar/PhasarLLVM/ControlFlow/Resolver/Resolver.h" -#include "phasar/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.h" #include "phasar/Utils/MaybeUniquePtr.h" namespace llvm { diff --git a/include/phasar/PhasarLLVM/ControlFlow/Resolver/RTAResolver.h b/include/phasar/PhasarLLVM/ControlFlow/Resolver/RTAResolver.h index 498440668..c891f0d57 100644 --- a/include/phasar/PhasarLLVM/ControlFlow/Resolver/RTAResolver.h +++ b/include/phasar/PhasarLLVM/ControlFlow/Resolver/RTAResolver.h @@ -19,8 +19,6 @@ #include "phasar/PhasarLLVM/ControlFlow/Resolver/CHAResolver.h" -#include "llvm/IR/DebugInfoMetadata.h" - #include namespace llvm { @@ -28,9 +26,11 @@ class CallBase; class StructType; class Function; class StructType; +class DICompositeType; } // namespace llvm namespace psr { +class DIBasedTypeHierarchy; class RTAResolver : public CHAResolver { public: RTAResolver(const LLVMProjectIRDB *IRDB, const LLVMVFTableProvider *VTP, diff --git a/include/phasar/PhasarLLVM/ControlFlow/Resolver/Resolver.h b/include/phasar/PhasarLLVM/ControlFlow/Resolver/Resolver.h index 7442a4999..158385c3e 100644 --- a/include/phasar/PhasarLLVM/ControlFlow/Resolver/Resolver.h +++ b/include/phasar/PhasarLLVM/ControlFlow/Resolver/Resolver.h @@ -18,9 +18,9 @@ #define PHASAR_PHASARLLVM_CONTROLFLOW_RESOLVER_RESOLVER_H_ #include "phasar/PhasarLLVM/Pointer/LLVMAliasInfo.h" -#include "phasar/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.h" #include "llvm/ADT/DenseSet.h" +#include "llvm/IR/DerivedTypes.h" #include #include @@ -45,9 +45,6 @@ getVFTIndex(const llvm::CallBase *CallSite); [[nodiscard]] const llvm::DIType * getReceiverType(const llvm::CallBase *CallSite); -[[nodiscard]] const llvm::StructType * -getReceiverStructType(const llvm::CallBase *CallSite); - [[nodiscard]] std::string getReceiverTypeName(const llvm::CallBase *CallSite); [[nodiscard]] bool isConsistentCall(const llvm::CallBase *CallSite, diff --git a/include/phasar/PhasarLLVM/Domain/LLVMAnalysisDomain.h b/include/phasar/PhasarLLVM/Domain/LLVMAnalysisDomain.h index 3fd7fd584..755bbc923 100644 --- a/include/phasar/PhasarLLVM/Domain/LLVMAnalysisDomain.h +++ b/include/phasar/PhasarLLVM/Domain/LLVMAnalysisDomain.h @@ -12,13 +12,12 @@ #include "phasar/Domain/AnalysisDomain.h" -#include "llvm/IR/DebugInfoMetadata.h" - namespace llvm { class Value; class Instruction; class StructType; class Function; +class DIType; } // namespace llvm namespace psr { diff --git a/include/phasar/PhasarLLVM/TypeHierarchy/LLVMVFTable.h b/include/phasar/PhasarLLVM/TypeHierarchy/LLVMVFTable.h index 3ab40dc18..0386f83e7 100644 --- a/include/phasar/PhasarLLVM/TypeHierarchy/LLVMVFTable.h +++ b/include/phasar/PhasarLLVM/TypeHierarchy/LLVMVFTable.h @@ -22,6 +22,7 @@ class ConstantStruct; } // namespace llvm namespace psr { +class DIBasedTypeHierarchy; /** * @brief Represents a virtual method table. @@ -30,6 +31,7 @@ namespace psr { * virtual method table matters. */ class LLVMVFTable : public VFTable { + private: friend class DIBasedTypeHierarchy; std::vector VFT; diff --git a/lib/PhasarLLVM/ControlFlow/LLVMVFTableProvider.cpp b/lib/PhasarLLVM/ControlFlow/LLVMVFTableProvider.cpp index c3ab17624..43c6dab56 100644 --- a/lib/PhasarLLVM/ControlFlow/LLVMVFTableProvider.cpp +++ b/lib/PhasarLLVM/ControlFlow/LLVMVFTableProvider.cpp @@ -30,8 +30,9 @@ static std::vector getVirtualFunctions( const llvm::DIType *Type) { auto ClearName = getTypeName(Type); - if (llvm::StringRef(ClearName).startswith("typeinfo name for ")) { - ClearName = ClearName.substr(18, ClearName.size() - 1); + static constexpr llvm::StringLiteral TIPrefix = "typeinfo name for "; + if (llvm::StringRef(ClearName).startswith(TIPrefix)) { + ClearName = ClearName.substr(TIPrefix.size()); } auto It = ClearNameTVMap.find(ClearName); @@ -64,16 +65,11 @@ LLVMVFTableProvider::LLVMVFTableProvider(const llvm::Module &Mod) { llvm::DebugInfoFinder DIF; DIF.processModule(Mod); for (const auto *Ty : DIF.types()) { - if (const auto *DerivedTy = llvm::dyn_cast(Ty)) { - if (const auto *BaseTy = DerivedTy->getBaseType()) { - if (const auto *CompTy = - llvm::dyn_cast(BaseTy)) { - if (CompTy->getTag() == llvm::dwarf::DW_TAG_class_type || - CompTy->getTag() == llvm::dwarf::DW_TAG_structure_type) { - TypeVFTMap.try_emplace(CompTy, - getVirtualFunctions(ClearNameTVMap, CompTy)); - } - } + if (const auto *CompTy = llvm::dyn_cast(Ty)) { + if (CompTy->getTag() == llvm::dwarf::DW_TAG_class_type || + CompTy->getTag() == llvm::dwarf::DW_TAG_structure_type) { + TypeVFTMap.try_emplace(CompTy, + getVirtualFunctions(ClearNameTVMap, CompTy)); } } } diff --git a/lib/PhasarLLVM/ControlFlow/Resolver/CHAResolver.cpp b/lib/PhasarLLVM/ControlFlow/Resolver/CHAResolver.cpp index 7428f9fd8..89ebe3bc6 100644 --- a/lib/PhasarLLVM/ControlFlow/Resolver/CHAResolver.cpp +++ b/lib/PhasarLLVM/ControlFlow/Resolver/CHAResolver.cpp @@ -16,6 +16,7 @@ #include "phasar/PhasarLLVM/ControlFlow/Resolver/CHAResolver.h" +#include "phasar/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.h" #include "phasar/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.h" #include "phasar/PhasarLLVM/Utils/LLVMShorthands.h" #include "phasar/Utils/Logger.h" diff --git a/lib/PhasarLLVM/ControlFlow/Resolver/RTAResolver.cpp b/lib/PhasarLLVM/ControlFlow/Resolver/RTAResolver.cpp index 58ad46ff5..05342b05a 100644 --- a/lib/PhasarLLVM/ControlFlow/Resolver/RTAResolver.cpp +++ b/lib/PhasarLLVM/ControlFlow/Resolver/RTAResolver.cpp @@ -18,11 +18,11 @@ #include "phasar/PhasarLLVM/DB/LLVMProjectIRDB.h" #include "phasar/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.h" -#include "phasar/PhasarLLVM/Utils/LLVMIRToSrc.h" #include "phasar/PhasarLLVM/Utils/LLVMShorthands.h" #include "phasar/Utils/Logger.h" #include "phasar/Utils/Utilities.h" +#include "llvm/IR/DebugInfo.h" #include "llvm/IR/DebugInfoMetadata.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/Function.h" @@ -99,16 +99,10 @@ void RTAResolver::resolveAllocatedCompositeTypes() { llvm::DebugInfoFinder DIF; DIF.processModule(*IRDB->getModule()); - llvm::DenseSet AllocatedCompositeTypes; for (const auto *Ty : DIF.types()) { if (const auto *CompTy = llvm::dyn_cast(Ty)) { - AllocatedCompositeTypes.insert(CompTy); + AllocatedCompositeTypes.push_back(CompTy); } } - - this->AllocatedCompositeTypes.reserve(AllocatedCompositeTypes.size()); - this->AllocatedCompositeTypes.insert(this->AllocatedCompositeTypes.end(), - AllocatedCompositeTypes.begin(), - AllocatedCompositeTypes.end()); } diff --git a/lib/PhasarLLVM/ControlFlow/Resolver/Resolver.cpp b/lib/PhasarLLVM/ControlFlow/Resolver/Resolver.cpp index e807ef2fd..687d0b86e 100644 --- a/lib/PhasarLLVM/ControlFlow/Resolver/Resolver.cpp +++ b/lib/PhasarLLVM/ControlFlow/Resolver/Resolver.cpp @@ -83,57 +83,6 @@ const llvm::DIType *psr::getReceiverType(const llvm::CallBase *CallSite) { } } } - /* - if (Receiver->getType()->isOpaquePointerTy()) { - if (const auto *Load = llvm::dyn_cast(Receiver)) { - if (const auto *DerivedTy = llvm::dyn_cast( - getDILocalVariable(Load->getPointerOperand())->getType())) { - return DerivedTy->getBaseType(); - } - } - } - - if (!Receiver->getType()->isOpaquePointerTy()) { - if (const auto *ReceiverTy = llvm::dyn_cast( - Receiver->getType()->getNonOpaquePointerElementType())) { - if (const auto *ValueTy = llvm::dyn_cast(ReceiverTy)) { - if (const auto *DerivedTy = llvm::dyn_cast( - getDILocalVariable(TypeToDIType[ValueTy]))) { - return DerivedTy->getBaseType(); - } - } - } - } -*/ - return nullptr; -} - -const llvm::StructType * -psr::getReceiverStructType(const llvm::CallBase *CallSite) { - if (CallSite->arg_empty() || - (CallSite->hasStructRetAttr() && CallSite->arg_size() < 2)) { - return nullptr; - } - - const auto *Receiver = - CallSite->getArgOperand(unsigned(CallSite->hasStructRetAttr())); - - if (!Receiver->getType()->isPointerTy()) { - return nullptr; - } - - if (Receiver->getType()->isOpaquePointerTy()) { - llvm::errs() << "WARNING: The IR under analysis uses opaque pointers, " - "which are not supported by phasar yet!\n"; - return nullptr; - } - - if (!Receiver->getType()->isOpaquePointerTy()) { - if (const auto *ReceiverTy = llvm::dyn_cast( - Receiver->getType()->getNonOpaquePointerElementType())) { - return ReceiverTy; - } - } return nullptr; } diff --git a/lib/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.cpp b/lib/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.cpp index c0241ccd4..b3c60c310 100644 --- a/lib/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.cpp +++ b/lib/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.cpp @@ -208,7 +208,7 @@ auto DIBasedTypeHierarchy::subTypesOf(ClassType Ty) const noexcept } bool DIBasedTypeHierarchy::isVTable(llvm::StringRef VarName) { - if (VarName.startswith("_ZTV")) { + if (VarName.startswith(VTablePrefix)) { return true; } // In LLVM 16 demangle() takes a StringRef diff --git a/tools/example-tool/myphasartool.cpp b/tools/example-tool/myphasartool.cpp index 8080dabbe..8fe62e8d2 100644 --- a/tools/example-tool/myphasartool.cpp +++ b/tools/example-tool/myphasartool.cpp @@ -7,6 +7,8 @@ * Philipp Schubert and others *****************************************************************************/ +#include "phasar/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.h" + #include "phasar.h" #include diff --git a/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFGExportTest.cpp b/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFGExportTest.cpp index d8c05b849..4244a7c38 100644 --- a/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFGExportTest.cpp +++ b/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFGExportTest.cpp @@ -151,12 +151,6 @@ class LLVMBasedICFGExportTest : public ::testing::Test { const nlohmann::json &GroundTruth) { ASSERT_TRUE(ExportedICFG.is_array()); - // llvm::outs() << "JSONs: GroundTruth\n"; - // llvm::outs() << GroundTruth.dump() << "\n"; - // llvm::outs() << "\n\n------------------------------------------\n\n"; - // llvm::outs() << "JSONs: ExportedICFG\n"; - // llvm::outs() << ExportedICFG.dump() << "\n"; - EXPECT_EQ(GroundTruth.size(), ExportedICFG.size()); bool HasError = false; for (const auto >Json : GroundTruth) { @@ -178,7 +172,7 @@ class LLVMBasedICFGExportTest : public ::testing::Test { } if (HasError) { - // llvm::errs() << "Errorneous json: " << ExportedICFG.dump(4) << '\n'; + llvm::errs() << "Errorneous json: " << ExportedICFG.dump(4) << '\n'; } } diff --git a/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFG_DTATest.cpp b/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFG_DTATest.cpp index d3838d840..f4c080c30 100644 --- a/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFG_DTATest.cpp +++ b/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFG_DTATest.cpp @@ -3,6 +3,7 @@ #include "phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h" #include "phasar/PhasarLLVM/DB/LLVMProjectIRDB.h" #include "phasar/PhasarLLVM/Pointer/LLVMAliasSet.h" +#include "phasar/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.h" #include "phasar/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.h" #include "phasar/PhasarLLVM/Utils/LLVMShorthands.h" @@ -12,7 +13,7 @@ using namespace std; using namespace psr; TEST(LLVMBasedICFG_DTATest, VirtualCallSite_5) { -#if 0 + GTEST_SKIP(); LLVMProjectIRDB IRDB(unittest::PathToLLTestFiles + "call_graphs/virtual_call_5_cpp.ll"); DIBasedTypeHierarchy TH(IRDB); @@ -38,7 +39,6 @@ TEST(LLVMBasedICFG_DTATest, VirtualCallSite_5) { ASSERT_TRUE(llvm::is_contained(ICFG.getCallersOf(VFuncA), I)); ASSERT_TRUE(llvm::is_contained(ICFG.getCallersOf(VFuncB), I)); } -#endif } TEST(LLVMBasedICFG_DTATest, VirtualCallSite_6) { diff --git a/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFG_OTFTest.cpp b/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFG_OTFTest.cpp index 6509fd0be..bb6c8da5d 100644 --- a/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFG_OTFTest.cpp +++ b/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFG_OTFTest.cpp @@ -5,6 +5,7 @@ #include "phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h" #include "phasar/PhasarLLVM/DB/LLVMProjectIRDB.h" #include "phasar/PhasarLLVM/Pointer/LLVMAliasSet.h" +#include "phasar/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.h" #include "phasar/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.h" #include "phasar/PhasarLLVM/Utils/LLVMShorthands.h" diff --git a/unittests/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEGeneralizedLCATest.cpp b/unittests/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEGeneralizedLCATest.cpp index c0f91e102..b3381ff3d 100644 --- a/unittests/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEGeneralizedLCATest.cpp +++ b/unittests/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEGeneralizedLCATest.cpp @@ -129,11 +129,11 @@ TEST_F(IDEGeneralizedLCATest, StringTestCpp) { std::vector GroundTruth; const auto *LastMainInstruction = getLastInstructionOf(HA->getProjectIRDB().getFunction("main")); - GroundTruth.push_back({{EdgeValue("Hello, World")}, - 3, - std::stoi(getMetaDataID(LastMainInstruction))}); + GroundTruth.push_back( + {{EdgeValue("Hello, World")}, + 3, + (unsigned int)std::stoi(getMetaDataID(LastMainInstruction))}); compareResults(GroundTruth); - LCASolver->dumpResults(); } TEST_F(IDEGeneralizedLCATest, FloatDivisionTest) { diff --git a/unittests/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEInstInteractionAnalysisTest.cpp b/unittests/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEInstInteractionAnalysisTest.cpp index 02b9865a7..a1368dc25 100644 --- a/unittests/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEInstInteractionAnalysisTest.cpp +++ b/unittests/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEInstInteractionAnalysisTest.cpp @@ -367,7 +367,6 @@ TEST_F(IDEInstInteractionAnalysisTest, StructEquality_01) { TEST_F(IDEInstInteractionAnalysisTest, StructEquality_02) { initializeIR("struct_02_cpp.ll"); - IRDB->dump(); const auto *Main = IRDB->getFunction("main"); const auto *Inst = getNthInstruction(Main, 2); auto FlowFact = IDEIIAFlowFact::create(Inst); diff --git a/utils/install-llvm-only.sh b/utils/install-llvm-only.sh deleted file mode 100644 index fe0b2d177..000000000 --- a/utils/install-llvm-only.sh +++ /dev/null @@ -1,8 +0,0 @@ -NUM_THREADS=$(nproc) -LLVM_INSTALL_DIR="/usr/local/llvm-15" -LLVM_RELEASE=llvmorg-15.0.7 - -# installing LLVM -tmp_dir=$(mktemp -d "llvm-build.XXXXXXXX" --tmpdir) -./utils/install-llvm.sh "${NUM_THREADS}" "${tmp_dir}" ${LLVM_INSTALL_DIR} ${LLVM_RELEASE} -rm -rf "${tmp_dir}" From 9c7f378a04635ea2104056c5a5a10b3d3237bd39 Mon Sep 17 00:00:00 2001 From: Fabian Schiebel Date: Tue, 6 Aug 2024 19:02:57 +0200 Subject: [PATCH 42/78] Log error if trying to instantiate DTAResolver + minor --- include/phasar/PhasarLLVM/TypeHierarchy.h | 1 + lib/PhasarLLVM/ControlFlow/Resolver/Resolver.cpp | 5 ++++- tools/example-tool/myphasartool.cpp | 2 -- tools/phasar-cli/phasar-cli.cpp | 2 ++ unittests/PhasarLLVM/ControlFlow/LLVMBasedICFG_DTATest.cpp | 7 +++---- 5 files changed, 10 insertions(+), 7 deletions(-) diff --git a/include/phasar/PhasarLLVM/TypeHierarchy.h b/include/phasar/PhasarLLVM/TypeHierarchy.h index a8a9b4d12..7f9c9d607 100644 --- a/include/phasar/PhasarLLVM/TypeHierarchy.h +++ b/include/phasar/PhasarLLVM/TypeHierarchy.h @@ -10,6 +10,7 @@ #ifndef PHASAR_PHASARLLVM_TYPEHIERARCHY_H #define PHASAR_PHASARLLVM_TYPEHIERARCHY_H +#include "phasar/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.h" #include "phasar/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.h" #include "phasar/PhasarLLVM/TypeHierarchy/LLVMVFTable.h" diff --git a/lib/PhasarLLVM/ControlFlow/Resolver/Resolver.cpp b/lib/PhasarLLVM/ControlFlow/Resolver/Resolver.cpp index 687d0b86e..dda9fec28 100644 --- a/lib/PhasarLLVM/ControlFlow/Resolver/Resolver.cpp +++ b/lib/PhasarLLVM/ControlFlow/Resolver/Resolver.cpp @@ -185,7 +185,10 @@ std::unique_ptr Resolver::create(CallGraphAnalysisType Ty, return std::make_unique(IRDB, VTP, TH); case CallGraphAnalysisType::DTA: assert(TH != nullptr); - return std::make_unique(IRDB, VTP, TH); + PHASAR_LOG_LEVEL(ERROR, "Do not use the DTA resolver anymore. It relies on " + "the removed 'typed-pointers' feature of LLVM."); + std::exit(1); + // return std::make_unique(IRDB, VTP, TH); case CallGraphAnalysisType::VTA: llvm::report_fatal_error( "The VTA callgraph algorithm is not implemented yet"); diff --git a/tools/example-tool/myphasartool.cpp b/tools/example-tool/myphasartool.cpp index 8fe62e8d2..8080dabbe 100644 --- a/tools/example-tool/myphasartool.cpp +++ b/tools/example-tool/myphasartool.cpp @@ -7,8 +7,6 @@ * Philipp Schubert and others *****************************************************************************/ -#include "phasar/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.h" - #include "phasar.h" #include diff --git a/tools/phasar-cli/phasar-cli.cpp b/tools/phasar-cli/phasar-cli.cpp index 6781e8e4b..301e9c704 100644 --- a/tools/phasar-cli/phasar-cli.cpp +++ b/tools/phasar-cli/phasar-cli.cpp @@ -332,6 +332,8 @@ int main(int Argc, const char **Argv) { } if (LogOpt) { Logger::initializeStderrLogger(LogSeverityOpt); + } else if (!SilentOpt) { + Logger::initializeStderrLogger(SeverityLevel::ERROR); } for (const auto &LogCat : LogCategoriesOpt) { Logger::initializeStderrLogger(LogSeverityOpt, LogCat); diff --git a/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFG_DTATest.cpp b/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFG_DTATest.cpp index f4c080c30..f66e02430 100644 --- a/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFG_DTATest.cpp +++ b/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFG_DTATest.cpp @@ -10,10 +10,10 @@ #include "TestConfig.h" #include "gtest/gtest.h" -using namespace std; using namespace psr; + TEST(LLVMBasedICFG_DTATest, VirtualCallSite_5) { - GTEST_SKIP(); + GTEST_SKIP() << "Requires typed pointers!"; LLVMProjectIRDB IRDB(unittest::PathToLLTestFiles + "call_graphs/virtual_call_5_cpp.ll"); DIBasedTypeHierarchy TH(IRDB); @@ -42,7 +42,7 @@ TEST(LLVMBasedICFG_DTATest, VirtualCallSite_5) { } TEST(LLVMBasedICFG_DTATest, VirtualCallSite_6) { -#if 0 + GTEST_SKIP() << "Requires typed pointers!"; LLVMProjectIRDB IRDB(unittest::PathToLLTestFiles + "call_graphs/virtual_call_6_cpp.ll"); DIBasedTypeHierarchy TH(IRDB); @@ -59,7 +59,6 @@ TEST(LLVMBasedICFG_DTATest, VirtualCallSite_6) { const auto &Callers = ICFG.getCallersOf(VFuncA); ASSERT_EQ(Callers.size(), 1U); ASSERT_TRUE(llvm::is_contained(Callers, I)); -#endif } int main(int Argc, char **Argv) { From 022b426a2cff068a0acda55bbbe69fffb792c1fb Mon Sep 17 00:00:00 2001 From: Fabian Schiebel Date: Tue, 6 Aug 2024 19:11:34 +0200 Subject: [PATCH 43/78] Add breaking changes --- BreakingChanges.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/BreakingChanges.md b/BreakingChanges.md index 597f54a97..2afe3d276 100644 --- a/BreakingChanges.md +++ b/BreakingChanges.md @@ -2,6 +2,8 @@ ## development HEAD +- The `DTAResolver` and the cli option `--call-graph-analysis=dta` do not work anymore (due to opaque pointers) and will be removed for the next release. Please use the `OTF` or `RTA` resolver instead. +- The default type-hierarchy implementation has been changed from `LLVMTypeHierarchy` to `DIBasedTypeHierarchy`. This also requires all affected analyses to be performed on LLVM IR that contains debug information. - The API of the `TypeHierarchy` interface (and thus the `LLVMTypeHierarchy` and `DIBasedTypeHierarchy` as well) has changed: - No handling of the super-type relation (only sub-types) - No VTable handling anymore -- has been out-sourced into `LLVMVFTableProvider` From b4783b9978173e55969f909ac1d6220e83ba97d3 Mon Sep 17 00:00:00 2001 From: Fabian Schiebel Date: Fri, 9 Aug 2024 18:12:40 +0200 Subject: [PATCH 44/78] Also compare gep type in IIA EqualGEPDescriptor --- .../DataFlow/IfdsIde/Problems/IDEInstInteractionAnalysis.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEInstInteractionAnalysis.cpp b/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEInstInteractionAnalysis.cpp index a8898c9e9..2952fc354 100644 --- a/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEInstInteractionAnalysis.cpp +++ b/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEInstInteractionAnalysis.cpp @@ -109,7 +109,8 @@ bool IDEIIAFlowFact::operator==(const IDEIIAFlowFact &Other) const { } auto EqualGEPDescriptor = [](const llvm::GetElementPtrInst *Lhs, const llvm::GetElementPtrInst *Rhs) { - return llvm::equal(Lhs->indices(), Rhs->indices()); + return Lhs->getSourceElementType() == Rhs->getSourceElementType() && + llvm::equal(Lhs->indices(), Rhs->indices()); }; for (unsigned Idx = 0; Idx < FieldDesc.size(); ++Idx) { if (!EqualGEPDescriptor(FieldDesc[Idx], Other.FieldDesc[Idx])) { From a7aa1b948cbff9b1765ef1c7080a1ade5c913661 Mon Sep 17 00:00:00 2001 From: Fabian Schiebel Date: Fri, 27 Sep 2024 10:06:19 +0200 Subject: [PATCH 45/78] Expose getDILocation() --- include/phasar/PhasarLLVM/Utils/LLVMIRToSrc.h | 2 ++ lib/PhasarLLVM/Utils/LLVMIRToSrc.cpp | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/include/phasar/PhasarLLVM/Utils/LLVMIRToSrc.h b/include/phasar/PhasarLLVM/Utils/LLVMIRToSrc.h index 9432e9c92..36bd2d66e 100644 --- a/include/phasar/PhasarLLVM/Utils/LLVMIRToSrc.h +++ b/include/phasar/PhasarLLVM/Utils/LLVMIRToSrc.h @@ -31,9 +31,11 @@ class Value; class GlobalVariable; class Module; class DIFile; +class DILocation; } // namespace llvm namespace psr { +[[nodiscard]] llvm::DILocation *getDILocation(const llvm::Value *V); [[nodiscard]] std::string getVarNameFromIR(const llvm::Value *V); diff --git a/lib/PhasarLLVM/Utils/LLVMIRToSrc.cpp b/lib/PhasarLLVM/Utils/LLVMIRToSrc.cpp index 01dd07603..2f86236b2 100644 --- a/lib/PhasarLLVM/Utils/LLVMIRToSrc.cpp +++ b/lib/PhasarLLVM/Utils/LLVMIRToSrc.cpp @@ -87,7 +87,7 @@ static llvm::DISubprogram *getDISubprogram(const llvm::Value *V) { return nullptr; } -static llvm::DILocation *getDILocation(const llvm::Value *V) { +llvm::DILocation *psr::getDILocation(const llvm::Value *V) { // Arguments and Instruction such as AllocaInst if (auto *DbgIntr = getDbgVarIntrinsic(V)) { if (auto *MN = DbgIntr->getMetadata(llvm::LLVMContext::MD_dbg)) { From 20a2d87b8c5a42b20db98a2f8c0a9eb57f3d7b62 Mon Sep 17 00:00:00 2001 From: Fabian Schiebel Date: Fri, 27 Sep 2024 13:42:20 +0200 Subject: [PATCH 46/78] expose getSrcCodeFromIR for DebugLocation + minor --- include/phasar/PhasarLLVM/Utils/LLVMIRToSrc.h | 53 ++++++++++--------- lib/PhasarLLVM/Utils/LLVMIRToSrc.cpp | 37 ++++++++----- 2 files changed, 50 insertions(+), 40 deletions(-) diff --git a/include/phasar/PhasarLLVM/Utils/LLVMIRToSrc.h b/include/phasar/PhasarLLVM/Utils/LLVMIRToSrc.h index 36bd2d66e..cdc71e4a0 100644 --- a/include/phasar/PhasarLLVM/Utils/LLVMIRToSrc.h +++ b/include/phasar/PhasarLLVM/Utils/LLVMIRToSrc.h @@ -35,6 +35,32 @@ class DILocation; } // namespace llvm namespace psr { +struct DebugLocation { + unsigned Line{}; + unsigned Column{}; + const llvm::DIFile *File{}; +}; + +struct SourceCodeInfo { + std::string SourceCodeLine; + std::string SourceCodeFilename; + std::string SourceCodeFunctionName; + unsigned Line = 0; + unsigned Column = 0; + + [[nodiscard]] bool empty() const noexcept; + + [[nodiscard]] bool operator==(const SourceCodeInfo &Other) const noexcept; + [[nodiscard]] inline bool + operator!=(const SourceCodeInfo &Other) const noexcept { + return !(*this == Other); + } + + /// Similar to operator==, but takes different SourceCodeFileName locations + /// into account + [[nodiscard]] bool equivalentWith(const SourceCodeInfo &Other) const; +}; + [[nodiscard]] llvm::DILocation *getDILocation(const llvm::Value *V); [[nodiscard]] std::string getVarNameFromIR(const llvm::Value *V); @@ -57,29 +83,10 @@ getLineAndColFromIR(const llvm::Value *V); [[nodiscard]] std::string getSrcCodeFromIR(const llvm::Value *V, bool Trim = true); +[[nodiscard]] std::string getSrcCodeFromIR(DebugLocation Loc, bool Trim = true); [[nodiscard]] std::string getModuleIDFromIR(const llvm::Value *V); -struct SourceCodeInfo { - std::string SourceCodeLine; - std::string SourceCodeFilename; - std::string SourceCodeFunctionName; - unsigned Line = 0; - unsigned Column = 0; - - [[nodiscard]] bool empty() const noexcept; - - [[nodiscard]] bool operator==(const SourceCodeInfo &Other) const noexcept; - [[nodiscard]] inline bool - operator!=(const SourceCodeInfo &Other) const noexcept { - return !(*this == Other); - } - - /// Similar to operator==, but takes different SourceCodeFileName locations - /// into account - [[nodiscard]] bool equivalentWith(const SourceCodeInfo &Other) const; -}; - /// Used from the JSON library internally to implicitly convert between json and /// SourceCodeInfo void from_json(const nlohmann::json &J, SourceCodeInfo &Info); @@ -89,12 +96,6 @@ void to_json(nlohmann::json &J, const SourceCodeInfo &Info); [[nodiscard]] SourceCodeInfo getSrcCodeInfoFromIR(const llvm::Value *V); -struct DebugLocation { - unsigned Line{}; - unsigned Column{}; - const llvm::DIFile *File{}; -}; - [[nodiscard]] std::optional getDebugLocation(const llvm::Value *V); diff --git a/lib/PhasarLLVM/Utils/LLVMIRToSrc.cpp b/lib/PhasarLLVM/Utils/LLVMIRToSrc.cpp index 2f86236b2..fb02800bf 100644 --- a/lib/PhasarLLVM/Utils/LLVMIRToSrc.cpp +++ b/lib/PhasarLLVM/Utils/LLVMIRToSrc.cpp @@ -20,6 +20,7 @@ #include "llvm/IR/Metadata.h" #include "llvm/IR/Module.h" #include "llvm/IR/Value.h" +#include "llvm/Support/FileSystem.h" #include "llvm/Support/Path.h" #include @@ -242,23 +243,31 @@ std::pair psr::getLineAndColFromIR(const llvm::Value *V) { } std::string psr::getSrcCodeFromIR(const llvm::Value *V, bool Trim) { - unsigned int LineNr = getLineFromIR(V); - if (LineNr > 0) { - std::filesystem::path Path(getFilePathFromIR(V)); - if (std::filesystem::exists(Path) && !std::filesystem::is_directory(Path)) { - std::ifstream Ifs(Path.string(), std::ios::binary); - if (Ifs.is_open()) { - Ifs.seekg(std::ios::beg); - std::string SrcLine; - for (unsigned int I = 0; I < LineNr - 1; ++I) { - Ifs.ignore(std::numeric_limits::max(), '\n'); - } - std::getline(Ifs, SrcLine); - return Trim ? llvm::StringRef(SrcLine).trim().str() : SrcLine; + if (auto Loc = getDebugLocation(V)) { + return getSrcCodeFromIR(*Loc, Trim); + } + return {}; +} + +std::string psr::getSrcCodeFromIR(DebugLocation Loc, bool Trim) { + if (Loc.Line == 0) { + return {}; + } + auto Path = getFilePathFromIR(Loc.File); + + if (llvm::sys::fs::exists(Path) && !llvm::sys::fs::is_directory(Path)) { + std::ifstream Ifs(Path, std::ios::binary); + if (Ifs.is_open()) { + Ifs.seekg(std::ios::beg); + std::string SrcLine; + for (unsigned int I = 0; I < Loc.Line - 1; ++I) { + Ifs.ignore(std::numeric_limits::max(), '\n'); } + std::getline(Ifs, SrcLine); + return Trim ? llvm::StringRef(SrcLine).trim().str() : SrcLine; } } - return ""; + return {}; } std::string psr::getModuleIDFromIR(const llvm::Value *V) { From 7829bcbf6b61e76de161005795d834f028efd25b Mon Sep 17 00:00:00 2001 From: Fabian Schiebel Date: Fri, 4 Oct 2024 14:33:11 +0200 Subject: [PATCH 47/78] Remove some unused includes --- .../DataFlow/IfdsIde/IDETabulationProblem.h | 6 ------ .../DataFlow/IfdsIde/IFDSTabulationProblem.h | 1 - .../PathSensitivityManagerBase.h | 2 +- .../DataFlow/IfdsIde/LLVMFlowFunctions.h | 2 -- .../IfdsIde/Problems/IDETypeStateAnalysis.h | 6 ------ include/phasar/Pointer/AliasInfoBase.h | 5 ++--- include/phasar/Utils/BitVectorSet.h | 5 +++++ include/phasar/Utils/ByRef.h | 2 +- include/phasar/Utils/DebugOutput.h | 2 -- include/phasar/Utils/GraphTraits.h | 6 ++---- include/phasar/Utils/IotaIterator.h | 1 - include/phasar/Utils/JoinLattice.h | 2 +- include/phasar/Utils/Macros.h | 19 +++++++++++++++++++ include/phasar/Utils/PAMM.h | 2 -- include/phasar/Utils/TypeTraits.h | 4 ++-- include/phasar/Utils/Utilities.h | 8 -------- .../Problems/IDELinearConstantAnalysis.cpp | 1 - .../IfdsIde/InteractiveIDESolverTest.cpp | 4 ---- 18 files changed, 33 insertions(+), 45 deletions(-) create mode 100644 include/phasar/Utils/Macros.h diff --git a/include/phasar/DataFlow/IfdsIde/IDETabulationProblem.h b/include/phasar/DataFlow/IfdsIde/IDETabulationProblem.h index 5d3dc71f6..27d1ba767 100644 --- a/include/phasar/DataFlow/IfdsIde/IDETabulationProblem.h +++ b/include/phasar/DataFlow/IfdsIde/IDETabulationProblem.h @@ -10,7 +10,6 @@ #ifndef PHASAR_DATAFLOW_IFDSIDE_IDETABULATIONPROBLEM_H_ #define PHASAR_DATAFLOW_IFDSIDE_IDETABULATIONPROBLEM_H_ -#include "phasar/ControlFlow/ICFGBase.h" #include "phasar/DB/ProjectIRDBBase.h" #include "phasar/DataFlow/IfdsIde/EdgeFunctionUtils.h" #include "phasar/DataFlow/IfdsIde/EdgeFunctions.h" @@ -21,15 +20,10 @@ #include "phasar/DataFlow/IfdsIde/SolverResults.h" #include "phasar/Utils/JoinLattice.h" #include "phasar/Utils/NullAnalysisPrinter.h" -#include "phasar/Utils/Printer.h" #include "phasar/Utils/SemiRing.h" #include "phasar/Utils/Soundness.h" -#include "llvm/ADT/StringRef.h" - #include -#include -#include #include #include #include diff --git a/include/phasar/DataFlow/IfdsIde/IFDSTabulationProblem.h b/include/phasar/DataFlow/IfdsIde/IFDSTabulationProblem.h index e669a26a9..cbafa68c3 100644 --- a/include/phasar/DataFlow/IfdsIde/IFDSTabulationProblem.h +++ b/include/phasar/DataFlow/IfdsIde/IFDSTabulationProblem.h @@ -13,7 +13,6 @@ #include "phasar/DataFlow/IfdsIde/EdgeFunctionUtils.h" #include "phasar/DataFlow/IfdsIde/IDETabulationProblem.h" #include "phasar/Domain/AnalysisDomain.h" -#include "phasar/Domain/BinaryDomain.h" #include #include diff --git a/include/phasar/DataFlow/PathSensitivity/PathSensitivityManagerBase.h b/include/phasar/DataFlow/PathSensitivity/PathSensitivityManagerBase.h index e1195bb57..3a58bae1e 100644 --- a/include/phasar/DataFlow/PathSensitivity/PathSensitivityManagerBase.h +++ b/include/phasar/DataFlow/PathSensitivity/PathSensitivityManagerBase.h @@ -14,8 +14,8 @@ #include "phasar/Utils/Logger.h" #include "phasar/Utils/Utilities.h" +#include "llvm/ADT/BitVector.h" #include "llvm/ADT/DenseSet.h" -#include "llvm/ADT/IntEqClasses.h" #include "llvm/ADT/SmallVector.h" namespace llvm { diff --git a/include/phasar/PhasarLLVM/DataFlow/IfdsIde/LLVMFlowFunctions.h b/include/phasar/PhasarLLVM/DataFlow/IfdsIde/LLVMFlowFunctions.h index e994671bb..cf568e283 100644 --- a/include/phasar/PhasarLLVM/DataFlow/IfdsIde/LLVMFlowFunctions.h +++ b/include/phasar/PhasarLLVM/DataFlow/IfdsIde/LLVMFlowFunctions.h @@ -13,7 +13,6 @@ #include "phasar/DataFlow/IfdsIde/FlowFunctions.h" #include "phasar/PhasarLLVM/DataFlow/IfdsIde/LLVMZeroValue.h" #include "phasar/PhasarLLVM/Utils/LLVMShorthands.h" -#include "phasar/Utils/TypeTraits.h" #include "llvm/ADT/PointerIntPair.h" #include "llvm/IR/Constant.h" @@ -30,7 +29,6 @@ #include #include #include -#include namespace psr { diff --git a/include/phasar/PhasarLLVM/DataFlow/IfdsIde/Problems/IDETypeStateAnalysis.h b/include/phasar/PhasarLLVM/DataFlow/IfdsIde/Problems/IDETypeStateAnalysis.h index be868e560..6054b5691 100644 --- a/include/phasar/PhasarLLVM/DataFlow/IfdsIde/Problems/IDETypeStateAnalysis.h +++ b/include/phasar/PhasarLLVM/DataFlow/IfdsIde/Problems/IDETypeStateAnalysis.h @@ -15,25 +15,19 @@ #include "phasar/DataFlow/IfdsIde/FlowFunctions.h" #include "phasar/DataFlow/IfdsIde/IDETabulationProblem.h" #include "phasar/PhasarLLVM/ControlFlow/LLVMBasedCFG.h" -#include "phasar/PhasarLLVM/DataFlow/IfdsIde/LLVMFlowFunctions.h" #include "phasar/PhasarLLVM/DataFlow/IfdsIde/LLVMZeroValue.h" #include "phasar/PhasarLLVM/Domain/LLVMAnalysisDomain.h" #include "phasar/PhasarLLVM/Pointer/LLVMAliasInfo.h" -#include "phasar/PhasarLLVM/Utils/DataFlowAnalysisType.h" -#include "phasar/Utils/ByRef.h" #include "phasar/Utils/JoinLattice.h" #include "phasar/Utils/Logger.h" #include "phasar/Utils/Printer.h" -#include "phasar/Utils/TypeTraits.h" #include "llvm/ADT/StringRef.h" #include "llvm/Demangle/Demangle.h" #include "llvm/IR/Function.h" -#include "llvm/IR/Instruction.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/Value.h" -#include #include #include #include diff --git a/include/phasar/Pointer/AliasInfoBase.h b/include/phasar/Pointer/AliasInfoBase.h index 039a212ed..24d7b5f10 100644 --- a/include/phasar/Pointer/AliasInfoBase.h +++ b/include/phasar/Pointer/AliasInfoBase.h @@ -11,12 +11,11 @@ #define PHASAR_POINTER_ALIASINFOBASE_H #include "phasar/Pointer/AliasInfoTraits.h" -#include "phasar/Utils/TypeTraits.h" +#include "phasar/Utils/Macros.h" -#include "llvm/ADT/DenseSet.h" #include "llvm/Support/raw_ostream.h" -#include "nlohmann/json.hpp" +#include "nlohmann/json_fwd.hpp" #include #include diff --git a/include/phasar/Utils/BitVectorSet.h b/include/phasar/Utils/BitVectorSet.h index 308245c82..0bf9b7ba0 100644 --- a/include/phasar/Utils/BitVectorSet.h +++ b/include/phasar/Utils/BitVectorSet.h @@ -366,6 +366,11 @@ template class BitVectorSet { } }; +// Overloads with the other intersectWith functions from Utilities.h +template +void intersectWith(BitVectorSet &Dest, const BitVectorSet &Src) { + Dest.setIntersectWith(Src); +} } // namespace psr #endif diff --git a/include/phasar/Utils/ByRef.h b/include/phasar/Utils/ByRef.h index f98bd9eaa..e36d7a036 100644 --- a/include/phasar/Utils/ByRef.h +++ b/include/phasar/Utils/ByRef.h @@ -10,7 +10,7 @@ #ifndef PHASAR_UTILS_BYREF_H #define PHASAR_UTILS_BYREF_H -#include "phasar/Utils/TypeTraits.h" +#include "phasar/Utils/Macros.h" #include diff --git a/include/phasar/Utils/DebugOutput.h b/include/phasar/Utils/DebugOutput.h index e904ef531..03f6098b3 100644 --- a/include/phasar/Utils/DebugOutput.h +++ b/include/phasar/Utils/DebugOutput.h @@ -10,9 +10,7 @@ #define PHASAR_UTILS_DEBUGOUTPUT_H #include "phasar/PhasarLLVM/Utils/LLVMShorthands.h" -#include "phasar/Utils/TypeTraits.h" -#include "llvm/ADT/SmallBitVector.h" #include "llvm/IR/Type.h" #include "llvm/Support/raw_os_ostream.h" #include "llvm/Support/raw_ostream.h" diff --git a/include/phasar/Utils/GraphTraits.h b/include/phasar/Utils/GraphTraits.h index 76915be0f..cdd3b410e 100644 --- a/include/phasar/Utils/GraphTraits.h +++ b/include/phasar/Utils/GraphTraits.h @@ -10,17 +10,15 @@ #ifndef PHASAR_UTILS_GRAPHTRAITS_H #define PHASAR_UTILS_GRAPHTRAITS_H -#include "phasar/Utils/TypeTraits.h" #include "phasar/Utils/Utilities.h" -#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/None.h" -#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringRef.h" -#include "llvm/ADT/identity.h" #include "llvm/Support/raw_ostream.h" +#if __cplusplus >= 202002L #include +#endif #include #include #include diff --git a/include/phasar/Utils/IotaIterator.h b/include/phasar/Utils/IotaIterator.h index c45a8efd0..9b5516271 100644 --- a/include/phasar/Utils/IotaIterator.h +++ b/include/phasar/Utils/IotaIterator.h @@ -16,7 +16,6 @@ #include #include -#include #include namespace psr { diff --git a/include/phasar/Utils/JoinLattice.h b/include/phasar/Utils/JoinLattice.h index 203027cf2..bfb0f0b02 100644 --- a/include/phasar/Utils/JoinLattice.h +++ b/include/phasar/Utils/JoinLattice.h @@ -17,7 +17,7 @@ #ifndef PHASAR_UTILS_JOINLATTICE_H #define PHASAR_UTILS_JOINLATTICE_H -#include "phasar/Utils/TypeTraits.h" +#include "phasar/Utils/Macros.h" #include #include diff --git a/include/phasar/Utils/Macros.h b/include/phasar/Utils/Macros.h new file mode 100644 index 000000000..5e072ad56 --- /dev/null +++ b/include/phasar/Utils/Macros.h @@ -0,0 +1,19 @@ +/****************************************************************************** + * Copyright (c) 2024 Fabian Schiebel. + * All rights reserved. This program and the accompanying materials are made + * available under the terms of LICENSE.txt. + * + * Contributors: + * Fabian Schiebel and others + *****************************************************************************/ + +#ifndef PHASAR_UTILS_MACROS_H +#define PHASAR_UTILS_MACROS_H + +#if __cplusplus < 202002L +#define PSR_CONCEPT static constexpr bool +#else +#define PSR_CONCEPT concept +#endif + +#endif // PHASAR_UTILS_MACROS_H diff --git a/include/phasar/Utils/PAMM.h b/include/phasar/Utils/PAMM.h index 50f8f215c..00f4bb3c7 100644 --- a/include/phasar/Utils/PAMM.h +++ b/include/phasar/Utils/PAMM.h @@ -17,8 +17,6 @@ #ifndef PHASAR_UTILS_PAMM_H_ #define PHASAR_UTILS_PAMM_H_ -#include "phasar/Utils/TypeTraits.h" - #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" diff --git a/include/phasar/Utils/TypeTraits.h b/include/phasar/Utils/TypeTraits.h index 2c6d771c7..25bd6198a 100644 --- a/include/phasar/Utils/TypeTraits.h +++ b/include/phasar/Utils/TypeTraits.h @@ -10,6 +10,8 @@ #ifndef PHASAR_UTILS_TYPETRAITS_H #define PHASAR_UTILS_TYPETRAITS_H +#include "phasar/Utils/Macros.h" + #include "llvm/ADT/STLExtras.h" #include "llvm/Support/raw_ostream.h" @@ -23,10 +25,8 @@ namespace psr { #if __cplusplus < 202002L -#define PSR_CONCEPT static constexpr bool template struct type_identity { using type = T; }; #else -#define PSR_CONCEPT concept template using type_identity = std::type_identity; #endif diff --git a/include/phasar/Utils/Utilities.h b/include/phasar/Utils/Utilities.h index 6be344536..fc1f1c533 100644 --- a/include/phasar/Utils/Utilities.h +++ b/include/phasar/Utils/Utilities.h @@ -10,11 +10,8 @@ #ifndef PHASAR_UTILS_UTILITIES_H_ #define PHASAR_UTILS_UTILITIES_H_ -#include "phasar/Utils/BitVectorSet.h" #include "phasar/Utils/TypeTraits.h" -#include "llvm/ADT/Hashing.h" -#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/raw_ostream.h" @@ -153,11 +150,6 @@ intersectWith(ContainerTy &Dest, const OtherContainerTy &Src) { } } -template -void intersectWith(BitVectorSet &Dest, const BitVectorSet &Src) { - Dest.setIntersectWith(Src); -} - llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const std::vector &Bits); diff --git a/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/IDELinearConstantAnalysis.cpp b/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/IDELinearConstantAnalysis.cpp index 1836e070f..86b72a47d 100644 --- a/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/IDELinearConstantAnalysis.cpp +++ b/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/IDELinearConstantAnalysis.cpp @@ -22,7 +22,6 @@ #include "phasar/PhasarLLVM/Utils/LLVMIRToSrc.h" #include "phasar/PhasarLLVM/Utils/LLVMShorthands.h" #include "phasar/Utils/Logger.h" -#include "phasar/Utils/TypeTraits.h" #include "phasar/Utils/Utilities.h" #include "llvm/ADT/Hashing.h" diff --git a/unittests/PhasarLLVM/DataFlow/IfdsIde/InteractiveIDESolverTest.cpp b/unittests/PhasarLLVM/DataFlow/IfdsIde/InteractiveIDESolverTest.cpp index 6ff07a20f..0848925e4 100644 --- a/unittests/PhasarLLVM/DataFlow/IfdsIde/InteractiveIDESolverTest.cpp +++ b/unittests/PhasarLLVM/DataFlow/IfdsIde/InteractiveIDESolverTest.cpp @@ -4,14 +4,10 @@ #include "phasar/PhasarLLVM/DataFlow/IfdsIde/Problems/IDELinearConstantAnalysis.h" #include "phasar/PhasarLLVM/HelperAnalyses.h" #include "phasar/PhasarLLVM/SimpleAnalysisConstructor.h" -#include "phasar/Utils/TypeTraits.h" #include "TestConfig.h" #include "gtest/gtest.h" -#include -#include - using namespace psr; /* ============== TEST FIXTURE ============== */ From 4800fd0c709d131f75b3c9bcb8c4d8301bb2cf64 Mon Sep 17 00:00:00 2001 From: Fabian Schiebel Date: Fri, 4 Oct 2024 14:34:11 +0200 Subject: [PATCH 48/78] Make TaintConfigData compatible with C++20 --- include/phasar/PhasarLLVM/TaintConfig/TaintConfigData.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/phasar/PhasarLLVM/TaintConfig/TaintConfigData.h b/include/phasar/PhasarLLVM/TaintConfig/TaintConfigData.h index 3e255c2fc..c9ddc240c 100644 --- a/include/phasar/PhasarLLVM/TaintConfig/TaintConfigData.h +++ b/include/phasar/PhasarLLVM/TaintConfig/TaintConfigData.h @@ -18,7 +18,9 @@ namespace psr { enum class TaintCategory; struct FunctionData { +#if __cplusplus < 202002L FunctionData() noexcept = default; +#endif std::string Name; TaintCategory ReturnCat{}; @@ -29,7 +31,9 @@ struct FunctionData { }; struct VariableData { +#if __cplusplus < 202002L VariableData() noexcept = default; +#endif size_t Line{}; std::string Name; From 24fc54ed4d18e4fff8e0d62a5adb66a67e72d70e Mon Sep 17 00:00:00 2001 From: Fabian Schiebel Date: Fri, 4 Oct 2024 18:03:54 +0200 Subject: [PATCH 49/78] Compatibility with opaque pointers --- cmake/phasar_macros.cmake | 13 ++++++++++++- include/phasar/PhasarLLVM/DB/LLVMProjectIRDB.h | 7 ++++--- lib/PhasarLLVM/DB/LLVMProjectIRDB.cpp | 14 ++++++++++---- 3 files changed, 26 insertions(+), 8 deletions(-) diff --git a/cmake/phasar_macros.cmake b/cmake/phasar_macros.cmake index 2ce5cd45f..e44a61e00 100644 --- a/cmake/phasar_macros.cmake +++ b/cmake/phasar_macros.cmake @@ -125,10 +125,21 @@ function(generate_ll_file) endif() if(GEN_LL_MEM2REG) + if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") + get_filename_component(COMPILER_PATH_STR ${CMAKE_CXX_COMPILER} DIRECTORY) + find_program(OPT_TOOL opt HINTS ${COMPILER_PATH_STR}) + else() + find_program(OPT_TOOL opt) + endif() + + if(NOT OPT_TOOL) + set(OPT_TOOL opt) + endif() + 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 -opaque-pointers=0 ${test_code_ll_file} -o ${test_code_ll_file} + COMMAND ${CMAKE_CXX_COMPILER_LAUNCHER} ${OPT_TOOL} -mem2reg -S -opaque-pointers=0 ${test_code_ll_file} -o ${test_code_ll_file} COMMENT ${GEN_CMD_COMMENT} DEPENDS ${GEN_LL_FILE} VERBATIM diff --git a/include/phasar/PhasarLLVM/DB/LLVMProjectIRDB.h b/include/phasar/PhasarLLVM/DB/LLVMProjectIRDB.h index 47df476ad..677b26639 100644 --- a/include/phasar/PhasarLLVM/DB/LLVMProjectIRDB.h +++ b/include/phasar/PhasarLLVM/DB/LLVMProjectIRDB.h @@ -18,7 +18,6 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringRef.h" -#include "llvm/ADT/iterator_range.h" #include "llvm/IR/Instruction.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Module.h" @@ -44,7 +43,8 @@ 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); + explicit LLVMProjectIRDB(const llvm::Twine &IRFileName, + bool EnableOpaquePointers = LLVM_VERSION_MAJOR > 14); /// Initializes the new ProjectIRDB with the given IR Module _without_ taking /// ownership. The module is optionally being preprocessed. /// @@ -58,7 +58,8 @@ 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); + explicit LLVMProjectIRDB(llvm::MemoryBufferRef Buf, + bool EnableOpaquePointers = LLVM_VERSION_MAJOR > 14); LLVMProjectIRDB(const LLVMProjectIRDB &) = delete; LLVMProjectIRDB &operator=(LLVMProjectIRDB &) = delete; diff --git a/lib/PhasarLLVM/DB/LLVMProjectIRDB.cpp b/lib/PhasarLLVM/DB/LLVMProjectIRDB.cpp index d4632d49f..0d81ef828 100644 --- a/lib/PhasarLLVM/DB/LLVMProjectIRDB.cpp +++ b/lib/PhasarLLVM/DB/LLVMProjectIRDB.cpp @@ -61,8 +61,11 @@ LLVMProjectIRDB::getParsedIRModuleOrNull(const llvm::Twine &IRFileName, return getParsedIRModuleOrNull(*FileOrErr.get(), Ctx); } -LLVMProjectIRDB::LLVMProjectIRDB(const llvm::Twine &IRFileName) { - +LLVMProjectIRDB::LLVMProjectIRDB(const llvm::Twine &IRFileName, + bool EnableOpaquePointers) { + if (EnableOpaquePointers) { + Ctx.enableOpaquePointers(); + } auto M = getParsedIRModuleOrNull(IRFileName, Ctx); if (!M) { @@ -155,8 +158,11 @@ LLVMProjectIRDB::LLVMProjectIRDB(std::unique_ptr Mod, } } -LLVMProjectIRDB::LLVMProjectIRDB(llvm::MemoryBufferRef Buf) { - llvm::SMDiagnostic Diag; +LLVMProjectIRDB::LLVMProjectIRDB(llvm::MemoryBufferRef Buf, + bool EnableOpaquePointers) { + if (EnableOpaquePointers) { + Ctx.enableOpaquePointers(); + } auto M = getParsedIRModuleOrNull(Buf, Ctx); if (!M) { return; From 628d768e61b9bcf4f73b6aff5aba72917b8e3233 Mon Sep 17 00:00:00 2001 From: Fabian Schiebel Date: Sat, 5 Oct 2024 17:22:52 +0200 Subject: [PATCH 50/78] Allow setting the LLVM version from higher-level projects --- CMakeLists.txt | 7 +++++++ cmake/add_llvm.cmake | 2 +- lib/PhasarLLVM/DB/LLVMProjectIRDB.cpp | 23 +++++++++++++++++------ 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9743e3ad8..7d792dd2e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,6 +8,10 @@ set(CMAKE_POLICY_DEFAULT_CMP0069 NEW) cmake_policy(SET CMP0077 NEW) set(CMAKE_POLICY_DEFAULT_CMP0077 NEW) +# Allow overwriting cache variables of external projects from this CMakeLists file +cmake_policy(SET CMP0126 NEW) +set(CMAKE_POLICY_DEFAULT_CMP0126 NEW) + # Allow portable use of CMAKE_VISIBILITY_INLINES_HIDDEN not only for shared libraries cmake_policy(SET CMP0063 NEW) set(CMAKE_POLICY_DEFAULT_CMP0063 NEW) @@ -303,6 +307,9 @@ endif() 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) # LLVM +if (NOT PHASAR_LLVM_VERSION) + set(PHASAR_LLVM_VERSION 14) +endif() include(add_llvm) add_llvm() diff --git a/cmake/add_llvm.cmake b/cmake/add_llvm.cmake index 7cf3ceb94..a2c47b8ee 100644 --- a/cmake/add_llvm.cmake +++ b/cmake/add_llvm.cmake @@ -2,7 +2,7 @@ macro(add_llvm) if (NOT PHASAR_IN_TREE) # Only search for LLVM if we build out of tree - find_package(LLVM 14 REQUIRED CONFIG) + find_package(LLVM ${PHASAR_LLVM_VERSION} REQUIRED CONFIG) find_library(LLVM_LIBRARY NAMES LLVM PATHS ${LLVM_LIBRARY_DIRS} NO_DEFAULT_PATH) if(USE_LLVM_FAT_LIB AND ${LLVM_LIBRARY} STREQUAL "LLVM_LIBRARY-NOTFOUND") diff --git a/lib/PhasarLLVM/DB/LLVMProjectIRDB.cpp b/lib/PhasarLLVM/DB/LLVMProjectIRDB.cpp index 0d81ef828..2bb171e1b 100644 --- a/lib/PhasarLLVM/DB/LLVMProjectIRDB.cpp +++ b/lib/PhasarLLVM/DB/LLVMProjectIRDB.cpp @@ -20,6 +20,21 @@ namespace psr { +static void setOpaquePointersForCtx(llvm::LLVMContext &Ctx, bool Enable) { +#if LLVM_VERSION_MAJOR >= 15 && LLVM_VERSION_MAJOR < 17 + if (!Enable) { + Ctx.setOpaquePointers(false); + } +#elif LLVM_VERSION_MAJOR < 15 + if (Enable) { + Ctx.enableOpaquePointers(); + } +#else // LLVM_VERSION_MAJOR >= 17 +#error \ + "Non-opaque pointers are not supported anymore. Refactor PhASAR to remove typed pointer support." +#endif +} + std::unique_ptr LLVMProjectIRDB::getParsedIRModuleOrNull(llvm::MemoryBufferRef IRFileContent, llvm::LLVMContext &Ctx) noexcept { @@ -63,9 +78,7 @@ LLVMProjectIRDB::getParsedIRModuleOrNull(const llvm::Twine &IRFileName, LLVMProjectIRDB::LLVMProjectIRDB(const llvm::Twine &IRFileName, bool EnableOpaquePointers) { - if (EnableOpaquePointers) { - Ctx.enableOpaquePointers(); - } + setOpaquePointersForCtx(Ctx, EnableOpaquePointers); auto M = getParsedIRModuleOrNull(IRFileName, Ctx); if (!M) { @@ -160,9 +173,7 @@ LLVMProjectIRDB::LLVMProjectIRDB(std::unique_ptr Mod, LLVMProjectIRDB::LLVMProjectIRDB(llvm::MemoryBufferRef Buf, bool EnableOpaquePointers) { - if (EnableOpaquePointers) { - Ctx.enableOpaquePointers(); - } + setOpaquePointersForCtx(Ctx, EnableOpaquePointers); auto M = getParsedIRModuleOrNull(Buf, Ctx); if (!M) { return; From 2c04104ff749caeca72a55459668361d20824555 Mon Sep 17 00:00:00 2001 From: Fabian Schiebel Date: Sun, 6 Oct 2024 13:24:11 +0200 Subject: [PATCH 51/78] Getting rid of UB in CHAResolver --- include/phasar/PhasarLLVM/ControlFlow/Resolver/CHAResolver.h | 4 +++- lib/PhasarLLVM/ControlFlow/Resolver/CHAResolver.cpp | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/include/phasar/PhasarLLVM/ControlFlow/Resolver/CHAResolver.h b/include/phasar/PhasarLLVM/ControlFlow/Resolver/CHAResolver.h index 2bc202e0a..ca5c16552 100644 --- a/include/phasar/PhasarLLVM/ControlFlow/Resolver/CHAResolver.h +++ b/include/phasar/PhasarLLVM/ControlFlow/Resolver/CHAResolver.h @@ -32,7 +32,9 @@ class CHAResolver : public Resolver { CHAResolver(const LLVMProjectIRDB *IRDB, const LLVMVFTableProvider *VTP, const LLVMTypeHierarchy *TH); - ~CHAResolver() override = default; + // Deleting an incomplete type (LLVMTypeHierarchy) is UB, so instantiate the + // dtor in CHAResolver.cpp + ~CHAResolver() override; FunctionSetTy resolveVirtualCall(const llvm::CallBase *CallSite) override; diff --git a/lib/PhasarLLVM/ControlFlow/Resolver/CHAResolver.cpp b/lib/PhasarLLVM/ControlFlow/Resolver/CHAResolver.cpp index 6b2c144a5..fc2e22b5d 100644 --- a/lib/PhasarLLVM/ControlFlow/Resolver/CHAResolver.cpp +++ b/lib/PhasarLLVM/ControlFlow/Resolver/CHAResolver.cpp @@ -40,6 +40,8 @@ CHAResolver::CHAResolver(const LLVMProjectIRDB *IRDB, } } +CHAResolver::~CHAResolver() = default; + auto CHAResolver::resolveVirtualCall(const llvm::CallBase *CallSite) -> FunctionSetTy { PHASAR_LOG_LEVEL(DEBUG, "Call virtual function: "); From 825da2a9367d2f93e7b2f68eaa851d69fe838131 Mon Sep 17 00:00:00 2001 From: Fabian Schiebel Date: Mon, 7 Oct 2024 20:05:46 +0200 Subject: [PATCH 52/78] Start adding more sophisticated type extraction (WIP) --- .../ControlFlow/Resolver/Resolver.cpp | 12 +- lib/PhasarLLVM/Utils/LLVMIRToSrc.cpp | 121 +++++++++++++++++- 2 files changed, 126 insertions(+), 7 deletions(-) diff --git a/lib/PhasarLLVM/ControlFlow/Resolver/Resolver.cpp b/lib/PhasarLLVM/ControlFlow/Resolver/Resolver.cpp index dda9fec28..a18e62109 100644 --- a/lib/PhasarLLVM/ControlFlow/Resolver/Resolver.cpp +++ b/lib/PhasarLLVM/ControlFlow/Resolver/Resolver.cpp @@ -75,13 +75,13 @@ const llvm::DIType *psr::getReceiverType(const llvm::CallBase *CallSite) { return nullptr; } - if (const auto *Load = llvm::dyn_cast(Receiver)) { - if (const auto *DITy = getDILocalVariable(Load->getPointerOperand())) { - if (const auto *DerivedTy = - llvm::dyn_cast(DITy->getType())) { - return DerivedTy->getBaseType(); - } + if (const auto *DITy = getVarTypeFromIR(Receiver)) { + while (const auto *DerivedTy = + llvm::dyn_cast_if_present(DITy)) { + // get rid of the pointer + DITy = DerivedTy->getBaseType(); } + return DITy; } return nullptr; diff --git a/lib/PhasarLLVM/Utils/LLVMIRToSrc.cpp b/lib/PhasarLLVM/Utils/LLVMIRToSrc.cpp index e1a2fefe1..b0d4a4af7 100644 --- a/lib/PhasarLLVM/Utils/LLVMIRToSrc.cpp +++ b/lib/PhasarLLVM/Utils/LLVMIRToSrc.cpp @@ -9,18 +9,27 @@ #include "phasar/PhasarLLVM/Utils/LLVMIRToSrc.h" +#include "phasar/PhasarLLVM/Utils/LLVMShorthands.h" + +#include "llvm/ADT/APInt.h" #include "llvm/ADT/SmallString.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" #include "llvm/Demangle/Demangle.h" +#include "llvm/IR/Constants.h" +#include "llvm/IR/DebugInfoMetadata.h" #include "llvm/IR/DebugLoc.h" #include "llvm/IR/Instruction.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/Metadata.h" #include "llvm/IR/Module.h" +#include "llvm/IR/Operator.h" #include "llvm/IR/Value.h" +#include "llvm/Support/Casting.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/Path.h" +#include "llvm/Support/raw_ostream.h" #include #include @@ -111,16 +120,126 @@ std::string psr::getVarNameFromIR(const llvm::Value *V) { return ""; } -llvm::DIType *psr::getVarTypeFromIR(const llvm::Value *V) { +static llvm::DIType *getVarTypeFromIRImpl(const llvm::Value *V) { if (auto *LocVar = getDILocalVariable(V)) { return LocVar->getType(); } if (auto *GlobVar = getDIGlobalVariable(V)) { return GlobVar->getType(); } + // TODO: Calls with known return types return nullptr; } +static llvm::DIType *getVarTypeFromIRRec(const llvm::Value *V, size_t Depth, + bool Log) { + static constexpr size_t DepthLimit = 10; + + V = V->stripPointerCastsAndAliases(); + if (Log) { + llvm::errs() << "[getVarTypeFromIRRec]: " << llvmIRToString(V) << " // " + << Depth << '\n'; + } + + if (auto *VarTy = getVarTypeFromIRImpl(V)) { + if (Log) { + llvm::errs() << "> Return VarTy " << *VarTy << '\n'; + } + return VarTy; + } + + // TODO: More + if (const auto *Load = llvm::dyn_cast(V)) { + const auto *Base = Load->getPointerOperand()->stripPointerCastsAndAliases(); + uint64_t Offset = 0; + if (const auto *Gep = llvm::dyn_cast(Base)) { + // Look for gep ptr, 0, N; where N is a constant + + if (Log) { + llvm::errs() << "> Gep " << *Gep << '\n'; + } + + if (Gep->getNumIndices() != 2) { + return nullptr; + } + const auto *FirstIdx = + llvm::dyn_cast(Gep->indices().begin()->get()); + if (!FirstIdx || FirstIdx->getZExtValue() != 0) { + return nullptr; + } + + const auto *SecondIdx = llvm::dyn_cast( + std::next(Gep->indices().begin())->get()); + if (!SecondIdx) { + return nullptr; + } + + Offset = SecondIdx->getZExtValue(); + Base = Gep->getPointerOperand(); + + if (Log) { + llvm::errs() << "> Gep is well-formed; idx: " << Offset << '\n'; + } + } + + // TODO: Get rid of the recursion + if (Depth >= DepthLimit) { + llvm::errs() << "Reach depth-limit\n"; + return nullptr; + } + auto *BaseTy = getVarTypeFromIRRec(Base, Depth + 1, Log); + if (!BaseTy) { + return nullptr; + } + const auto *DerivedTy = llvm::dyn_cast(BaseTy); + auto *StructTy = DerivedTy ? DerivedTy->getBaseType() : BaseTy; + + if (Offset == 0 && DerivedTy) { + if (Log) { + llvm::errs() << "> Return StructTy "; + if (StructTy) { + llvm::errs() << *StructTy; + } + + llvm::errs() << '\n'; + } + return StructTy; + } + + if (Log) { + llvm::errs() << "> Field-access at offset " << Offset << '\n'; + } + + if (const auto *CompositeTy = + llvm::dyn_cast(StructTy)) { + if (Offset > CompositeTy->getElements().size()) { + if (Log) { + llvm::errs() << "> Out-of-bounds (" << Offset << " > " + << CompositeTy->getElements().size() << '\n'; + } + return nullptr; + } + auto Elems = CompositeTy->getElements(); + if (Log) { + llvm::errs() << "> Accessing array at [" << Offset << "] for " + << *CompositeTy << '\n'; + } + if (auto *ElemTy = llvm::dyn_cast(Elems[Offset])) { + if (Log) { + llvm::errs() << "> Return ElemTy\n"; + } + return ElemTy; + } + } + } + + return nullptr; +} + +llvm::DIType *psr::getVarTypeFromIR(const llvm::Value *V) { + return getVarTypeFromIRRec(V, 0, getMetaDataID(V) == "743197"); +} + std::string psr::getFunctionNameFromIR(const llvm::Value *V) { // We can return unmangled function names w/o checking debug info if (const auto *F = llvm::dyn_cast(V)) { From 8efd2f1891868c0c87b58924a823e32489c971c4 Mon Sep 17 00:00:00 2001 From: Fabian Schiebel Date: Tue, 8 Oct 2024 10:05:07 +0200 Subject: [PATCH 53/78] Handle function calls in getVarTypeFromIR --- lib/PhasarLLVM/Utils/LLVMIRToSrc.cpp | 204 ++++++++++++++++----------- 1 file changed, 119 insertions(+), 85 deletions(-) diff --git a/lib/PhasarLLVM/Utils/LLVMIRToSrc.cpp b/lib/PhasarLLVM/Utils/LLVMIRToSrc.cpp index b0d4a4af7..528ec65eb 100644 --- a/lib/PhasarLLVM/Utils/LLVMIRToSrc.cpp +++ b/lib/PhasarLLVM/Utils/LLVMIRToSrc.cpp @@ -19,6 +19,8 @@ #include "llvm/IR/Constants.h" #include "llvm/IR/DebugInfoMetadata.h" #include "llvm/IR/DebugLoc.h" +#include "llvm/IR/Function.h" +#include "llvm/IR/InstrTypes.h" #include "llvm/IR/Instruction.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/IntrinsicInst.h" @@ -127,117 +129,149 @@ static llvm::DIType *getVarTypeFromIRImpl(const llvm::Value *V) { if (auto *GlobVar = getDIGlobalVariable(V)) { return GlobVar->getType(); } - // TODO: Calls with known return types + if (const auto *Call = llvm::dyn_cast(V)) { + if (const auto *Callee = llvm::dyn_cast( + Call->getCalledOperand()->stripPointerCastsAndAliases())) { + if (auto *DICallee = Callee->getSubprogram()) { + auto Types = DICallee->getType()->getTypeArray(); + if (Types.size()) { + return Types[0]; + } + } + } + } return nullptr; } -static llvm::DIType *getVarTypeFromIRRec(const llvm::Value *V, size_t Depth, - bool Log) { - static constexpr size_t DepthLimit = 10; - - V = V->stripPointerCastsAndAliases(); - if (Log) { - llvm::errs() << "[getVarTypeFromIRRec]: " << llvmIRToString(V) << " // " - << Depth << '\n'; - } +static const llvm::GEPOperator *getStructGep(const llvm::Value *V) { + if (const auto *Gep = llvm::dyn_cast(V)) { + if (Gep->getNumIndices() != 2) { + return nullptr; + } + const auto *FirstIdx = + llvm::dyn_cast(Gep->indices().begin()->get()); + if (!FirstIdx || FirstIdx->getZExtValue() != 0) { + return nullptr; + } - if (auto *VarTy = getVarTypeFromIRImpl(V)) { - if (Log) { - llvm::errs() << "> Return VarTy " << *VarTy << '\n'; + const auto *SecondIdx = llvm::dyn_cast( + std::next(Gep->indices().begin())->get()); + if (!SecondIdx) { + return nullptr; } - return VarTy; + return Gep; } - // TODO: More - if (const auto *Load = llvm::dyn_cast(V)) { - const auto *Base = Load->getPointerOperand()->stripPointerCastsAndAliases(); - uint64_t Offset = 0; - if (const auto *Gep = llvm::dyn_cast(Base)) { - // Look for gep ptr, 0, N; where N is a constant + return nullptr; +} - if (Log) { - llvm::errs() << "> Gep " << *Gep << '\n'; - } +#define LOG(...) \ + if (Log) \ + llvm::errs() << __VA_ARGS__ - if (Gep->getNumIndices() != 2) { - return nullptr; - } - const auto *FirstIdx = - llvm::dyn_cast(Gep->indices().begin()->get()); - if (!FirstIdx || FirstIdx->getZExtValue() != 0) { - return nullptr; - } +static std::pair +getOffsetAndBase(const llvm::Value *V, bool Log) { + const auto *Base = V->stripPointerCastsAndAliases(); + uint64_t Offset = 0; + if (const auto *Gep = getStructGep(Base)) { + // Look for gep ptr, 0, N; where N is a constant - const auto *SecondIdx = llvm::dyn_cast( - std::next(Gep->indices().begin())->get()); - if (!SecondIdx) { - return nullptr; - } + LOG("> Gep " << *Gep << '\n'); - Offset = SecondIdx->getZExtValue(); - Base = Gep->getPointerOperand(); + const auto *SecondIdx = + llvm::cast(std::next(Gep->indices().begin())->get()); - if (Log) { - llvm::errs() << "> Gep is well-formed; idx: " << Offset << '\n'; + Offset = SecondIdx->getZExtValue(); + Base = Gep->getPointerOperand(); + + LOG("> Gep is well-formed; idx: " << Offset << '\n'); + } + return {Base, Offset}; +} + +static llvm::DIType *getStructElementType(llvm::DIType *BaseTy, size_t Offset, + bool Log) { + const auto *DerivedTy = llvm::dyn_cast(BaseTy); + auto *StructTy = DerivedTy ? DerivedTy->getBaseType() : BaseTy; + + if (Offset == 0 && DerivedTy) { + if (Log) { + llvm::errs() << "> Return StructTy "; + if (StructTy) { + llvm::errs() << *StructTy; } - } - // TODO: Get rid of the recursion - if (Depth >= DepthLimit) { - llvm::errs() << "Reach depth-limit\n"; - return nullptr; + llvm::errs() << '\n'; } - auto *BaseTy = getVarTypeFromIRRec(Base, Depth + 1, Log); - if (!BaseTy) { + return StructTy; + } + + LOG("> Field-access at offset " << Offset << '\n'); + + if (const auto *CompositeTy = + llvm::dyn_cast(StructTy)) { + if (Offset > CompositeTy->getElements().size()) { + LOG("> Out-of-bounds (" << Offset << " > " + << CompositeTy->getElements().size() << '\n'); + return nullptr; } - const auto *DerivedTy = llvm::dyn_cast(BaseTy); - auto *StructTy = DerivedTy ? DerivedTy->getBaseType() : BaseTy; - - if (Offset == 0 && DerivedTy) { - if (Log) { - llvm::errs() << "> Return StructTy "; - if (StructTy) { - llvm::errs() << *StructTy; - } + auto Elems = CompositeTy->getElements(); - llvm::errs() << '\n'; - } - return StructTy; - } + LOG("> Accessing array at [" << Offset << "] for " << *CompositeTy << '\n'); - if (Log) { - llvm::errs() << "> Field-access at offset " << Offset << '\n'; + if (auto *ElemTy = llvm::dyn_cast(Elems[Offset])) { + LOG("> Return ElemTy\n"); + return ElemTy; } + } + return nullptr; +} - if (const auto *CompositeTy = - llvm::dyn_cast(StructTy)) { - if (Offset > CompositeTy->getElements().size()) { - if (Log) { - llvm::errs() << "> Out-of-bounds (" << Offset << " > " - << CompositeTy->getElements().size() << '\n'; - } - return nullptr; - } - auto Elems = CompositeTy->getElements(); - if (Log) { - llvm::errs() << "> Accessing array at [" << Offset << "] for " - << *CompositeTy << '\n'; - } - if (auto *ElemTy = llvm::dyn_cast(Elems[Offset])) { - if (Log) { - llvm::errs() << "> Return ElemTy\n"; - } - return ElemTy; - } +static llvm::DIType *getVarTypeFromIRRec(const llvm::Value *V, size_t Depth, + bool Log) { + static constexpr size_t DepthLimit = 10; + + V = V->stripPointerCastsAndAliases(); + + LOG("[getVarTypeFromIRRec]: " << llvmIRToString(V) << " // " << Depth + << '\n'); + + if (auto *VarTy = getVarTypeFromIRImpl(V)) { + LOG("> Return VarTy " << *VarTy << '\n'); + return VarTy; + } + + auto InternalGetOffsetAndBase = + [Log](const llvm::Value *V) -> std::pair { + if (const auto *Load = llvm::dyn_cast(V)) { + return getOffsetAndBase(Load->getPointerOperand(), Log); } + if (const auto *Gep = llvm::dyn_cast(V)) { + return getOffsetAndBase(Gep->getPointerOperand(), Log); + } + return {}; + }; + + auto [Base, Offset] = InternalGetOffsetAndBase(V); + if (!Base) { + return nullptr; } - return nullptr; + // TODO: Get rid of the recursion + if (Depth >= DepthLimit) { + llvm::errs() << "Reach depth-limit\n"; + return nullptr; + } + auto *BaseTy = getVarTypeFromIRRec(Base, Depth + 1, Log); + if (!BaseTy) { + return nullptr; + } + return getStructElementType(BaseTy, Offset, Log); } - +#undef LOG llvm::DIType *psr::getVarTypeFromIR(const llvm::Value *V) { - return getVarTypeFromIRRec(V, 0, getMetaDataID(V) == "743197"); + return getVarTypeFromIRRec(V, 0, /*getMetaDataID(V) == "629303"*/ false); } std::string psr::getFunctionNameFromIR(const llvm::Value *V) { From afe65bb827d5daf8f2c130bec90de82467b49e75 Mon Sep 17 00:00:00 2001 From: Fabian Schiebel Date: Tue, 8 Oct 2024 12:19:36 +0200 Subject: [PATCH 54/78] better fallback handling for getDebugLocation, etc --- lib/PhasarLLVM/Utils/LLVMIRToSrc.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/lib/PhasarLLVM/Utils/LLVMIRToSrc.cpp b/lib/PhasarLLVM/Utils/LLVMIRToSrc.cpp index 528ec65eb..550e022bb 100644 --- a/lib/PhasarLLVM/Utils/LLVMIRToSrc.cpp +++ b/lib/PhasarLLVM/Utils/LLVMIRToSrc.cpp @@ -350,6 +350,9 @@ const llvm::DIFile *psr::getDIFileFromIR(const llvm::Value *V) { } else if (I->getMetadata(llvm::LLVMContext::MD_dbg)) { return I->getDebugLoc()->getFile(); } + if (const auto *DIFun = I->getFunction()->getSubprogram()) { + return DIFun->getFile(); + } } return nullptr; } @@ -395,6 +398,11 @@ std::pair psr::getLineAndColFromIR(const llvm::Value *V) { if (auto *DILoc = getDILocation(V)) { return {DILoc->getLine(), DILoc->getColumn()}; } + if (const auto *I = llvm::dyn_cast(V)) { + if (const auto *DIFun = I->getFunction()->getSubprogram()) { + return {DIFun->getLine(), 0}; + } + } if (auto *DISubpr = getDISubprogram(V)) { // Function return {DISubpr->getLine(), 0}; } @@ -510,6 +518,11 @@ std::optional psr::getDebugLocation(const llvm::Value *V) { return DebugLocation{DILoc->getLine(), DILoc->getColumn(), DILoc->getFile()}; } + if (const auto *I = llvm::dyn_cast(V)) { + if (const auto *DIFun = I->getFunction()->getSubprogram()) { + return DebugLocation{DIFun->getLine(), 0, DIFun->getFile()}; + } + } if (auto *DISubpr = getDISubprogram(V)) { // Function return DebugLocation{DISubpr->getLine(), 0, DISubpr->getFile()}; } From b939dbcba4ac3d377f3299949a4c1cd7416ddd59 Mon Sep 17 00:00:00 2001 From: Fabian Schiebel Date: Tue, 22 Oct 2024 09:08:20 +0200 Subject: [PATCH 55/78] Better IntraMonoSolver dump --- .../DataFlow/Mono/Solver/IntraMonoSolver.h | 38 ++++++++++++++++--- 1 file changed, 33 insertions(+), 5 deletions(-) diff --git a/include/phasar/DataFlow/Mono/Solver/IntraMonoSolver.h b/include/phasar/DataFlow/Mono/Solver/IntraMonoSolver.h index ac46b9068..f93ade8df 100644 --- a/include/phasar/DataFlow/Mono/Solver/IntraMonoSolver.h +++ b/include/phasar/DataFlow/Mono/Solver/IntraMonoSolver.h @@ -18,7 +18,8 @@ #define PHASAR_DATAFLOW_MONO_SOLVER_INTRAMONOSOLVER_H #include "phasar/DataFlow/Mono/IntraMonoProblem.h" -#include "phasar/Utils/BitVectorSet.h" +#include "phasar/Utils/DefaultValue.h" +#include "phasar/Utils/Utilities.h" #include #include @@ -109,12 +110,39 @@ template class IntraMonoSolver { } } - mono_container_t getResultsAt(n_t Stmt) { return Analysis[Stmt]; } + [[nodiscard]] const mono_container_t &getResultsAt(n_t Stmt) const { + auto It = Analysis.find(Stmt); + if (It != Analysis.end()) { + return It->second; + } + return getDefaultValue(); + } virtual void dumpResults(llvm::raw_ostream &OS = llvm::outs()) { - OS << "Intra-Monotone solver results:\n" - "------------------------------\n"; - for (auto &[Node, FlowFacts] : this->Analysis) { + OS << "\n***************************************************************\n" + << "* Raw IntraMonoSolver results *\n" + << "***************************************************************\n"; + + if (Analysis.empty()) { + OS << "No results computed!" << '\n'; + return; + } + + std::vector> Cells; + Cells.reserve(Analysis.size()); + Cells.insert(Cells.end(), Analysis.begin(), Analysis.end()); + + std::sort(Cells.begin(), Cells.end(), [](const auto &Lhs, const auto &Rhs) { + if constexpr (std::is_same_v) { + return StringIDLess{}(getMetaDataID(Lhs.first), + getMetaDataID(Rhs.first)); + } else { + // If non-LLVM IR is used + return Lhs.first < Rhs.first; + } + }); + + for (const auto &[Node, FlowFacts] : Cells) { OS << "Instruction:\n" << NToString(Node); OS << "\nFacts:\n"; if (FlowFacts.empty()) { From 535c114f1bf5fb0a63b2a423567e45a48db06dca Mon Sep 17 00:00:00 2001 From: Fabian Schiebel Date: Tue, 22 Oct 2024 09:09:41 +0200 Subject: [PATCH 56/78] minor --- include/phasar/DataFlow/Mono/Solver/IntraMonoSolver.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/phasar/DataFlow/Mono/Solver/IntraMonoSolver.h b/include/phasar/DataFlow/Mono/Solver/IntraMonoSolver.h index f93ade8df..c05b24c0e 100644 --- a/include/phasar/DataFlow/Mono/Solver/IntraMonoSolver.h +++ b/include/phasar/DataFlow/Mono/Solver/IntraMonoSolver.h @@ -18,6 +18,7 @@ #define PHASAR_DATAFLOW_MONO_SOLVER_INTRAMONOSOLVER_H #include "phasar/DataFlow/Mono/IntraMonoProblem.h" +#include "phasar/PhasarLLVM/Utils/LLVMShorthands.h" #include "phasar/Utils/DefaultValue.h" #include "phasar/Utils/Utilities.h" From 8d0542059c19e36331dad5af272d7adbd1caf938 Mon Sep 17 00:00:00 2001 From: Fabian Schiebel Date: Tue, 22 Oct 2024 09:12:48 +0200 Subject: [PATCH 57/78] improve intra mono dump --- include/phasar/DataFlow/Mono/Solver/IntraMonoSolver.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/phasar/DataFlow/Mono/Solver/IntraMonoSolver.h b/include/phasar/DataFlow/Mono/Solver/IntraMonoSolver.h index c05b24c0e..d1b45f332 100644 --- a/include/phasar/DataFlow/Mono/Solver/IntraMonoSolver.h +++ b/include/phasar/DataFlow/Mono/Solver/IntraMonoSolver.h @@ -144,14 +144,14 @@ template class IntraMonoSolver { }); for (const auto &[Node, FlowFacts] : Cells) { - OS << "Instruction:\n" << NToString(Node); - OS << "\nFacts:\n"; + OS << "Instruction:\n " << NToString(Node); + OS << "\nFacts: "; if (FlowFacts.empty()) { - OS << "\tEMPTY\n"; + OS << "EMPTY\n"; } else { IMProblem.printContainer(OS, FlowFacts); } - OS << "\n\n"; + OS << "\n"; } } From 4a75feea485c5de8e4f04ae44d516ea1522b6b38 Mon Sep 17 00:00:00 2001 From: Fabian Schiebel Date: Tue, 22 Oct 2024 09:17:43 +0200 Subject: [PATCH 58/78] minor --- include/phasar/DataFlow/Mono/Solver/IntraMonoSolver.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/phasar/DataFlow/Mono/Solver/IntraMonoSolver.h b/include/phasar/DataFlow/Mono/Solver/IntraMonoSolver.h index d1b45f332..739b6fa30 100644 --- a/include/phasar/DataFlow/Mono/Solver/IntraMonoSolver.h +++ b/include/phasar/DataFlow/Mono/Solver/IntraMonoSolver.h @@ -144,7 +144,7 @@ template class IntraMonoSolver { }); for (const auto &[Node, FlowFacts] : Cells) { - OS << "Instruction:\n " << NToString(Node); + OS << "Instruction: " << NToString(Node); OS << "\nFacts: "; if (FlowFacts.empty()) { OS << "EMPTY\n"; From 58138d29d35b4854437be927009ba810cd56d6c2 Mon Sep 17 00:00:00 2001 From: Fabian Schiebel Date: Sat, 26 Oct 2024 17:04:50 +0200 Subject: [PATCH 59/78] expose getNonPureVirtualVFTEntry as namespace-scope function + fix build with LLVM 14 --- .../ControlFlow/Resolver/Resolver.h | 22 +++++++++- .../ControlFlow/Resolver/Resolver.cpp | 43 ++++++++++--------- 2 files changed, 44 insertions(+), 21 deletions(-) diff --git a/include/phasar/PhasarLLVM/ControlFlow/Resolver/Resolver.h b/include/phasar/PhasarLLVM/ControlFlow/Resolver/Resolver.h index 93faa54a7..598bb39b3 100644 --- a/include/phasar/PhasarLLVM/ControlFlow/Resolver/Resolver.h +++ b/include/phasar/PhasarLLVM/ControlFlow/Resolver/Resolver.h @@ -39,14 +39,29 @@ class LLVMVFTableProvider; class DIBasedTypeHierarchy; enum class CallGraphAnalysisType; +/// Assuming that `CallSite` is a virtual call through a vtable, retrieves the +/// index in the vtable of the virtual function called. [[nodiscard]] std::optional getVFTIndex(const llvm::CallBase *CallSite); +/// Assuming that `CallSite` is a vall to a non-static member function, +/// retrieves the type of the receiver. Returns nullptr, if the receiver-type +/// could not be extracted [[nodiscard]] const llvm::DIType * getReceiverType(const llvm::CallBase *CallSite); +/// Assuming that `CallSite` is a virtual call, where `Idx` is retrieved through +/// `getVFTIndex()` and `T` through `getReceiverType()` +[[nodiscard]] const llvm::Function * +getNonPureVirtualVFTEntry(const llvm::DIType *T, unsigned Idx, + const llvm::CallBase *CallSite, + const psr::LLVMVFTableProvider &VTP); + [[nodiscard]] std::string getReceiverTypeName(const llvm::CallBase *CallSite); +/// Checks whether the signature of `DestFun` matches the required withature of +/// `CallSite`, such that `DestFun` qualifies as callee-candidate, if `CallSite` +/// is an indirect/virtual call. [[nodiscard]] bool isConsistentCall(const llvm::CallBase *CallSite, const llvm::Function *DestFun); @@ -59,7 +74,12 @@ class Resolver { const llvm::Function * getNonPureVirtualVFTEntry(const llvm::DIType *T, unsigned Idx, - const llvm::CallBase *CallSite); + const llvm::CallBase *CallSite) { + if (!VTP) { + return nullptr; + } + return psr::getNonPureVirtualVFTEntry(T, Idx, CallSite, *VTP); + } public: using FunctionSetTy = llvm::SmallDenseSet; diff --git a/lib/PhasarLLVM/ControlFlow/Resolver/Resolver.cpp b/lib/PhasarLLVM/ControlFlow/Resolver/Resolver.cpp index a18e62109..8e2fca071 100644 --- a/lib/PhasarLLVM/ControlFlow/Resolver/Resolver.cpp +++ b/lib/PhasarLLVM/ControlFlow/Resolver/Resolver.cpp @@ -77,7 +77,12 @@ const llvm::DIType *psr::getReceiverType(const llvm::CallBase *CallSite) { if (const auto *DITy = getVarTypeFromIR(Receiver)) { while (const auto *DerivedTy = - llvm::dyn_cast_if_present(DITy)) { +#if LLVM_VERSION_MAJOR >= 15 + llvm::dyn_cast_if_present +#else + llvm::dyn_cast_or_null +#endif + (DITy)) { // get rid of the pointer DITy = DerivedTy->getBaseType(); } @@ -87,6 +92,23 @@ const llvm::DIType *psr::getReceiverType(const llvm::CallBase *CallSite) { return nullptr; } +const llvm::Function * +psr::getNonPureVirtualVFTEntry(const llvm::DIType *T, unsigned Idx, + const llvm::CallBase *CallSite, + const LLVMVFTableProvider &VTP) { + + if (const auto *VT = VTP.getVFTableOrNull(T)) { + const auto *Target = VT->getFunction(Idx); + if (Target && + Target->getName() != DIBasedTypeHierarchy::PureVirtualCallName && + isConsistentCall(CallSite, Target)) { + return Target; + } + } + + return nullptr; +} + std::string psr::getReceiverTypeName(const llvm::CallBase *CallSite) { const auto *RT = getReceiverType(CallSite); if (RT) { @@ -120,25 +142,6 @@ Resolver::Resolver(const LLVMProjectIRDB *IRDB, const LLVMVFTableProvider *VTP) assert(IRDB != nullptr); } -const llvm::Function * -Resolver::getNonPureVirtualVFTEntry(const llvm::DIType *T, unsigned Idx, - const llvm::CallBase *CallSite) { - if (!VTP) { - return nullptr; - } - - if (const auto *VT = VTP->getVFTableOrNull(T)) { - const auto *Target = VT->getFunction(Idx); - if (Target && - Target->getName() != DIBasedTypeHierarchy::PureVirtualCallName && - isConsistentCall(CallSite, Target)) { - return Target; - } - } - - return nullptr; -} - void Resolver::preCall(const llvm::Instruction *Inst) {} void Resolver::handlePossibleTargets(const llvm::CallBase *CallSite, From 69600fdbb2fdcfc2e666fbd160681f2b2ff342f8 Mon Sep 17 00:00:00 2001 From: Fabian Schiebel Date: Sun, 24 Nov 2024 11:46:33 +0100 Subject: [PATCH 60/78] Fix RTA resolver --- .../ControlFlow/Resolver/RTAResolver.cpp | 53 ++++++++++++++++--- 1 file changed, 47 insertions(+), 6 deletions(-) diff --git a/lib/PhasarLLVM/ControlFlow/Resolver/RTAResolver.cpp b/lib/PhasarLLVM/ControlFlow/Resolver/RTAResolver.cpp index 05342b05a..05ef7f040 100644 --- a/lib/PhasarLLVM/ControlFlow/Resolver/RTAResolver.cpp +++ b/lib/PhasarLLVM/ControlFlow/Resolver/RTAResolver.cpp @@ -18,6 +18,7 @@ #include "phasar/PhasarLLVM/DB/LLVMProjectIRDB.h" #include "phasar/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.h" +#include "phasar/PhasarLLVM/Utils/LLVMIRToSrc.h" #include "phasar/PhasarLLVM/Utils/LLVMShorthands.h" #include "phasar/Utils/Logger.h" #include "phasar/Utils/Utilities.h" @@ -91,18 +92,58 @@ auto RTAResolver::resolveVirtualCall(const llvm::CallBase *CallSite) std::string RTAResolver::str() const { return "RTA"; } -/// More or less copied from GeneralStatisticsAnalysis +static const llvm::DICompositeType * +isCompositeStructType(const llvm::DIType *Ty) { + if (const auto *CompTy = llvm:: +#if LLVM_VERSION_MAJOR >= 15 + dyn_cast_if_present +#else + dyn_cast_or_null +#endif + (Ty); + CompTy && (CompTy->getTag() == llvm::dwarf::DW_TAG_structure_type || + CompTy->getTag() == llvm::dwarf::DW_TAG_class_type)) { + + return CompTy; + } + + return nullptr; +} + void RTAResolver::resolveAllocatedCompositeTypes() { if (!AllocatedCompositeTypes.empty()) { return; } - llvm::DebugInfoFinder DIF; - DIF.processModule(*IRDB->getModule()); + llvm::DenseSet AllocatedTypes; - for (const auto *Ty : DIF.types()) { - if (const auto *CompTy = llvm::dyn_cast(Ty)) { - AllocatedCompositeTypes.push_back(CompTy); + for (const auto *Inst : IRDB->getAllInstructions()) { + if (const auto *Alloca = llvm::dyn_cast(Inst)) { + if (const auto *Ty = isCompositeStructType(getVarTypeFromIR(Alloca))) { + AllocatedTypes.insert(Ty); + } + } else if (const auto *Call = llvm::dyn_cast(Inst)) { + if (const auto *Callee = llvm::dyn_cast( + Call->getCalledOperand()->stripPointerCastsAndAliases())) { + if (psr::isHeapAllocatingFunction(Callee)) { + const auto *MDNode = Call->getMetadata("heapallocsite"); + if (const auto *CompTy = llvm:: +#if LLVM_VERSION_MAJOR >= 15 + dyn_cast_if_present +#else + dyn_cast_or_null +#endif + (MDNode); + isCompositeStructType(CompTy)) { + + AllocatedTypes.insert(CompTy); + } + } + } } } + + AllocatedCompositeTypes.reserve(AllocatedTypes.size()); + AllocatedCompositeTypes.insert(AllocatedCompositeTypes.end(), + AllocatedTypes.begin(), AllocatedTypes.end()); } From e65d4f15754697dec8e9b6b89e6b9dbafe3d2226 Mon Sep 17 00:00:00 2001 From: Fabian Schiebel Date: Sun, 24 Nov 2024 11:49:27 +0100 Subject: [PATCH 61/78] Add missing include --- lib/PhasarLLVM/ControlFlow/Resolver/RTAResolver.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/lib/PhasarLLVM/ControlFlow/Resolver/RTAResolver.cpp b/lib/PhasarLLVM/ControlFlow/Resolver/RTAResolver.cpp index 05ef7f040..b13c95337 100644 --- a/lib/PhasarLLVM/ControlFlow/Resolver/RTAResolver.cpp +++ b/lib/PhasarLLVM/ControlFlow/Resolver/RTAResolver.cpp @@ -21,17 +21,13 @@ #include "phasar/PhasarLLVM/Utils/LLVMIRToSrc.h" #include "phasar/PhasarLLVM/Utils/LLVMShorthands.h" #include "phasar/Utils/Logger.h" -#include "phasar/Utils/Utilities.h" -#include "llvm/IR/DebugInfo.h" +#include "llvm/BinaryFormat/Dwarf.h" #include "llvm/IR/DebugInfoMetadata.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/Function.h" -#include "llvm/IR/InstIterator.h" #include "llvm/IR/InstrTypes.h" -#include "llvm/IR/Instruction.h" #include "llvm/IR/Instructions.h" -#include "llvm/IR/Module.h" #include "llvm/Support/Casting.h" using namespace std; From 61a76e2bb7d4d1fa3a33cdddf51857613cabd6c3 Mon Sep 17 00:00:00 2001 From: Fabian Schiebel Date: Sun, 24 Nov 2024 18:39:56 +0100 Subject: [PATCH 62/78] Fix solveIFDSProblem + cherry-pick fix of DIBasedTypeHierarchy::buildTypeGraph --- include/phasar/DataFlow/IfdsIde/Solver/IFDSSolver.h | 3 +-- lib/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.cpp | 7 ++++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/include/phasar/DataFlow/IfdsIde/Solver/IFDSSolver.h b/include/phasar/DataFlow/IfdsIde/Solver/IFDSSolver.h index 3a5f20d8f..041f8c933 100644 --- a/include/phasar/DataFlow/IfdsIde/Solver/IFDSSolver.h +++ b/include/phasar/DataFlow/IfdsIde/Solver/IFDSSolver.h @@ -108,8 +108,7 @@ using IFDSSolver_P = IFDSSolver OwningSolverResults + typename AnalysisDomainTy::d_t, BinaryDomain> solveIFDSProblem(IFDSTabulationProblem &Problem, const typename AnalysisDomainTy::i_t &ICF) { IFDSSolver Solver(Problem, &ICF); diff --git a/lib/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.cpp b/lib/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.cpp index b3c60c310..f79c4d036 100644 --- a/lib/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.cpp +++ b/lib/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.cpp @@ -103,7 +103,12 @@ buildTypeGraph(llvm::ArrayRef VertexTypes, if (const auto *Inheritenace = llvm::dyn_cast(Fld); Inheritenace && Inheritenace->getTag() == llvm::dwarf::DW_TAG_inheritance) { - auto BaseIdx = TypeToVertex.lookup(Inheritenace->getBaseType()); + const auto *Base = Inheritenace->getBaseType(); + while (Base->getTag() == llvm::dwarf::DW_TAG_typedef) { + Base = llvm::cast(Base)->getBaseType(); + } + + auto BaseIdx = TypeToVertex.lookup(Base); assert(BaseIdx != 0 || VertexTypes[0] == Inheritenace->getBaseType()); TG.DerivedTypesOf[BaseIdx].push_back(DerivedIdx); From 0841e38756f5b066f458f84ca11cf0233f3420b2 Mon Sep 17 00:00:00 2001 From: Fabian Schiebel Date: Sat, 25 Jan 2025 12:17:03 +0100 Subject: [PATCH 63/78] dump functions from debugger --- include/phasar/PhasarLLVM/Utils/LLVMShorthands.h | 1 + lib/PhasarLLVM/Utils/LLVMShorthands.cpp | 7 ++++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/include/phasar/PhasarLLVM/Utils/LLVMShorthands.h b/include/phasar/PhasarLLVM/Utils/LLVMShorthands.h index b0d8bccf9..332d70452 100644 --- a/include/phasar/PhasarLLVM/Utils/LLVMShorthands.h +++ b/include/phasar/PhasarLLVM/Utils/LLVMShorthands.h @@ -91,6 +91,7 @@ std::string llvmIRToShortString(const llvm::Value *V); LLVM_DUMP_METHOD void dumpIRValue(const llvm::Value *V); LLVM_DUMP_METHOD void dumpIRValue(const llvm::Instruction *V); +LLVM_DUMP_METHOD void dumpIRValue(const llvm::Function *V); /** * @brief Returns all LLVM Global Values that are used in the given LLVM diff --git a/lib/PhasarLLVM/Utils/LLVMShorthands.cpp b/lib/PhasarLLVM/Utils/LLVMShorthands.cpp index 99f809513..9871d19e4 100644 --- a/lib/PhasarLLVM/Utils/LLVMShorthands.cpp +++ b/lib/PhasarLLVM/Utils/LLVMShorthands.cpp @@ -201,7 +201,9 @@ std::string psr::llvmIRToShortString(const llvm::Value *V) { I && !I->getType()->isVoidTy()) { V->printAsOperand(RSO, true, getModuleSlotTrackerFor(V)); } else if (const auto *F = llvm::dyn_cast(V)) { - RSO << F->getName(); + RSO << "fun @" << F->getName(); + } else if (const auto *Glob = llvm::dyn_cast(V)) { + RSO << "glob @" << Glob->getName(); } else { V->print(RSO, getModuleSlotTrackerFor(V)); } @@ -233,6 +235,9 @@ void psr::dumpIRValue(const llvm::Value *V) { void psr::dumpIRValue(const llvm::Instruction *V) { llvm::outs() << llvmIRToString(V) << '\n'; } +void psr::dumpIRValue(const llvm::Function *V) { + llvm::outs() << llvmIRToString(V) << '\n'; +} std::vector psr::globalValuesUsedinFunction(const llvm::Function *F) { From 55b6dd276b8f6ce026ae18cb7e364066b2517c78 Mon Sep 17 00:00:00 2001 From: Fabian Schiebel Date: Tue, 4 Feb 2025 15:49:26 +0100 Subject: [PATCH 64/78] Remove unused-variable warning in release mode for CallGraph.h --- include/phasar/ControlFlow/CallGraph.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/include/phasar/ControlFlow/CallGraph.h b/include/phasar/ControlFlow/CallGraph.h index d73a1b578..74d5fe7af 100644 --- a/include/phasar/ControlFlow/CallGraph.h +++ b/include/phasar/ControlFlow/CallGraph.h @@ -201,8 +201,7 @@ template class CallGraphBuilder { [[nodiscard]] FunctionVertexTy *addFunctionVertex(f_t Fun) { auto [It, Inserted] = CG.CallersOf.try_emplace(std::move(Fun), nullptr); if (Inserted) { - auto Cap = CG.FunVertexOwner.capacity(); - assert(CG.FunVertexOwner.size() < Cap && + assert(CG.FunVertexOwner.size() < CG.FunVertexOwner.capacity() && "Trying to add more than MaxNumFunctions Function Vertices"); It->second = &CG.FunVertexOwner.emplace_back(); } From f26005fe9181ef3dec129d4372a5039d295e2bfc Mon Sep 17 00:00:00 2001 From: Fabian Schiebel Date: Fri, 28 Mar 2025 14:39:37 +0100 Subject: [PATCH 65/78] minor fix in CHA and RTA resolvers --- lib/PhasarLLVM/ControlFlow/Resolver/CHAResolver.cpp | 2 +- lib/PhasarLLVM/ControlFlow/Resolver/RTAResolver.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/PhasarLLVM/ControlFlow/Resolver/CHAResolver.cpp b/lib/PhasarLLVM/ControlFlow/Resolver/CHAResolver.cpp index ba464cd0a..15dcdf0e1 100644 --- a/lib/PhasarLLVM/ControlFlow/Resolver/CHAResolver.cpp +++ b/lib/PhasarLLVM/ControlFlow/Resolver/CHAResolver.cpp @@ -76,7 +76,7 @@ auto CHAResolver::resolveVirtualCall(const llvm::CallBase *CallSite) for (const auto &FallbackTy : FallbackTys) { const auto *Target = getNonPureVirtualVFTEntry(FallbackTy, VtableIndex, CallSite); - if (Target) { + if (Target && psr::isConsistentCall(CallSite, Target)) { PossibleCallees.insert(Target); } } diff --git a/lib/PhasarLLVM/ControlFlow/Resolver/RTAResolver.cpp b/lib/PhasarLLVM/ControlFlow/Resolver/RTAResolver.cpp index cb7e011b6..05b9e006d 100644 --- a/lib/PhasarLLVM/ControlFlow/Resolver/RTAResolver.cpp +++ b/lib/PhasarLLVM/ControlFlow/Resolver/RTAResolver.cpp @@ -75,7 +75,7 @@ auto RTAResolver::resolveVirtualCall(const llvm::CallBase *CallSite) if (ReachableTypes.find(PossibleType) != EndIt) { const auto *Target = getNonPureVirtualVFTEntry(PossibleType, VtableIndex, CallSite); - if (Target) { + if (Target && psr::isConsistentCall(CallSite, Target)) { PossibleCallTargets.insert(Target); } } From 6c89c994d970c840ef7ce64e92982cbac742968c Mon Sep 17 00:00:00 2001 From: Fabian Schiebel Date: Sun, 6 Apr 2025 18:33:46 +0200 Subject: [PATCH 66/78] Some cleanup --- .../phasar/PhasarLLVM/ControlFlow/Resolver/CHAResolver.h | 2 -- .../phasar/PhasarLLVM/ControlFlow/Resolver/OTFResolver.h | 2 -- .../phasar/PhasarLLVM/ControlFlow/Resolver/RTAResolver.h | 2 -- include/phasar/PhasarLLVM/ControlFlow/Resolver/Resolver.h | 8 +++----- include/phasar/PhasarLLVM/Utils/LLVMIRToSrc.h | 1 + lib/PhasarLLVM/ControlFlow/LLVMBasedICFG.cpp | 1 - lib/PhasarLLVM/Utils/LLVMIRToSrc.cpp | 1 - 7 files changed, 4 insertions(+), 13 deletions(-) diff --git a/include/phasar/PhasarLLVM/ControlFlow/Resolver/CHAResolver.h b/include/phasar/PhasarLLVM/ControlFlow/Resolver/CHAResolver.h index 82a58ee95..818a59de8 100644 --- a/include/phasar/PhasarLLVM/ControlFlow/Resolver/CHAResolver.h +++ b/include/phasar/PhasarLLVM/ControlFlow/Resolver/CHAResolver.h @@ -37,8 +37,6 @@ class CHAResolver : public Resolver { FunctionSetTy resolveVirtualCall(const llvm::CallBase *CallSite) override; - [[nodiscard]] bool isIndependent() const noexcept override { return true; } - [[nodiscard]] std::string str() const override; [[nodiscard]] bool diff --git a/include/phasar/PhasarLLVM/ControlFlow/Resolver/OTFResolver.h b/include/phasar/PhasarLLVM/ControlFlow/Resolver/OTFResolver.h index 47cba1f09..3bbdc83f5 100644 --- a/include/phasar/PhasarLLVM/ControlFlow/Resolver/OTFResolver.h +++ b/include/phasar/PhasarLLVM/ControlFlow/Resolver/OTFResolver.h @@ -57,8 +57,6 @@ class OTFResolver : public Resolver { getActualFormalPointerPairs(const llvm::CallBase *CallSite, const llvm::Function *CalleeTarget); - [[nodiscard]] bool isIndependent() const noexcept override { return false; } - [[nodiscard]] std::string str() const override; [[nodiscard]] bool diff --git a/include/phasar/PhasarLLVM/ControlFlow/Resolver/RTAResolver.h b/include/phasar/PhasarLLVM/ControlFlow/Resolver/RTAResolver.h index 718906ee5..f4371c608 100644 --- a/include/phasar/PhasarLLVM/ControlFlow/Resolver/RTAResolver.h +++ b/include/phasar/PhasarLLVM/ControlFlow/Resolver/RTAResolver.h @@ -37,8 +37,6 @@ class RTAResolver : public CHAResolver { FunctionSetTy resolveVirtualCall(const llvm::CallBase *CallSite) override; - [[nodiscard]] bool isIndependent() const noexcept override { return true; } - [[nodiscard]] std::string str() const override; [[nodiscard]] bool diff --git a/include/phasar/PhasarLLVM/ControlFlow/Resolver/Resolver.h b/include/phasar/PhasarLLVM/ControlFlow/Resolver/Resolver.h index b237d9403..52570d4db 100644 --- a/include/phasar/PhasarLLVM/ControlFlow/Resolver/Resolver.h +++ b/include/phasar/PhasarLLVM/ControlFlow/Resolver/Resolver.h @@ -107,14 +107,12 @@ class Resolver { virtual void otherInst(const llvm::Instruction *Inst); + [[nodiscard]] virtual std::string str() const = 0; + /// Whether the ICFG needs to reconsider all dynamic call-sites once there /// have been changes through handlePossibleTargets(). /// - /// Make true for performance (may be less sound then) - [[nodiscard]] virtual bool isIndependent() const noexcept { return false; } - - [[nodiscard]] virtual std::string str() const = 0; - + /// Make false for performance (may be less sound then) [[nodiscard]] virtual bool mutatesHelperAnalysisInformation() const noexcept { // Conservatively returns true. Override if possible return true; diff --git a/include/phasar/PhasarLLVM/Utils/LLVMIRToSrc.h b/include/phasar/PhasarLLVM/Utils/LLVMIRToSrc.h index b46fd95c0..f9d3d91d7 100644 --- a/include/phasar/PhasarLLVM/Utils/LLVMIRToSrc.h +++ b/include/phasar/PhasarLLVM/Utils/LLVMIRToSrc.h @@ -38,6 +38,7 @@ class DILocation; } // namespace llvm namespace psr { + struct DebugLocation { unsigned Line{}; unsigned Column{}; diff --git a/lib/PhasarLLVM/ControlFlow/LLVMBasedICFG.cpp b/lib/PhasarLLVM/ControlFlow/LLVMBasedICFG.cpp index 7d6bd38fd..addd88c95 100644 --- a/lib/PhasarLLVM/ControlFlow/LLVMBasedICFG.cpp +++ b/lib/PhasarLLVM/ControlFlow/LLVMBasedICFG.cpp @@ -27,7 +27,6 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/IR/Function.h" #include "llvm/IR/Instruction.h" -#include "llvm/Support/Casting.h" #include "llvm/Support/ErrorHandling.h" #include diff --git a/lib/PhasarLLVM/Utils/LLVMIRToSrc.cpp b/lib/PhasarLLVM/Utils/LLVMIRToSrc.cpp index 4bca0f380..ac36114d3 100644 --- a/lib/PhasarLLVM/Utils/LLVMIRToSrc.cpp +++ b/lib/PhasarLLVM/Utils/LLVMIRToSrc.cpp @@ -31,7 +31,6 @@ #include "llvm/Support/Casting.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/Path.h" -#include "llvm/Support/raw_ostream.h" #include #include From 96b710fac2c3bed2776b2cad60ad49c2bdf71b37 Mon Sep 17 00:00:00 2001 From: Fabian Schiebel Date: Mon, 7 Apr 2025 11:25:34 +0200 Subject: [PATCH 67/78] Add ome additional robustness to LLVMIRToSrc --- .../ControlFlow/Resolver/Resolver.cpp | 2 +- lib/PhasarLLVM/Utils/LLVMIRToSrc.cpp | 30 +++++++++++++++---- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/lib/PhasarLLVM/ControlFlow/Resolver/Resolver.cpp b/lib/PhasarLLVM/ControlFlow/Resolver/Resolver.cpp index 58a659b72..7153b557f 100644 --- a/lib/PhasarLLVM/ControlFlow/Resolver/Resolver.cpp +++ b/lib/PhasarLLVM/ControlFlow/Resolver/Resolver.cpp @@ -62,7 +62,7 @@ std::optional psr::getVFTIndex(const llvm::CallBase *CallSite) { } const llvm::DIType *psr::getReceiverType(const llvm::CallBase *CallSite) { - if (CallSite->arg_empty() || + if (!CallSite || CallSite->arg_empty() || (CallSite->hasStructRetAttr() && CallSite->arg_size() < 2)) { return nullptr; } diff --git a/lib/PhasarLLVM/Utils/LLVMIRToSrc.cpp b/lib/PhasarLLVM/Utils/LLVMIRToSrc.cpp index ac36114d3..a25e31ff5 100644 --- a/lib/PhasarLLVM/Utils/LLVMIRToSrc.cpp +++ b/lib/PhasarLLVM/Utils/LLVMIRToSrc.cpp @@ -29,6 +29,7 @@ #include "llvm/IR/Operator.h" #include "llvm/IR/Value.h" #include "llvm/Support/Casting.h" +#include "llvm/Support/Compiler.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/Path.h" @@ -180,8 +181,23 @@ getOffsetAndBase(const llvm::Value *V) { return {Base, Offset}; } +namespace t2 { +LLVM_DUMP_METHOD extern void dumpDIType(const llvm::DIType *Ty) { + if (!Ty) { + llvm::errs() << "\n"; + } + + Ty->print(llvm::errs()); +} +LLVM_DUMP_METHOD extern void dumpDIType(const llvm::DIDerivedType *Ty) { + dumpDIType(static_cast(Ty)); +} + +} // namespace t2 + static llvm::DIType *getStructElementType(llvm::DIType *BaseTy, size_t Offset) { - const auto *DerivedTy = llvm::dyn_cast(BaseTy); + const auto *DerivedTy = + llvm::dyn_cast_if_present(BaseTy); auto *StructTy = DerivedTy ? DerivedTy->getBaseType() : BaseTy; if (Offset == 0 && DerivedTy) { @@ -189,13 +205,13 @@ static llvm::DIType *getStructElementType(llvm::DIType *BaseTy, size_t Offset) { } if (const auto *CompositeTy = - llvm::dyn_cast(StructTy)) { - if (Offset > CompositeTy->getElements().size()) { + llvm::dyn_cast_if_present(StructTy)) { + auto Elems = CompositeTy->getElements(); + if (!Elems || Offset >= Elems.size()) { return nullptr; } - auto Elems = CompositeTy->getElements(); - if (auto *ElemTy = llvm::dyn_cast(Elems[Offset])) { + if (auto *ElemTy = llvm::dyn_cast_if_present(Elems[Offset])) { return ElemTy; } } @@ -239,6 +255,10 @@ static llvm::DIType *getVarTypeFromIRRec(const llvm::Value *V, size_t Depth) { } llvm::DIType *psr::getVarTypeFromIR(const llvm::Value *V) { + if (!V) { + return nullptr; + } + return getVarTypeFromIRRec(V, 0); } From 4949284b95b93e8efc5c1190c795fd2f7922e0af Mon Sep 17 00:00:00 2001 From: Fabian Schiebel Date: Tue, 29 Apr 2025 16:51:50 +0200 Subject: [PATCH 68/78] Fix AllBottom::compose + make FilteredLLVMAliasSet a bit more robust --- .../DataFlow/IfdsIde/EdgeFunctionUtils.h | 213 ++++++++++-------- .../Pointer/FilteredLLVMAliasSet.cpp | 21 +- 2 files changed, 129 insertions(+), 105 deletions(-) diff --git a/include/phasar/DataFlow/IfdsIde/EdgeFunctionUtils.h b/include/phasar/DataFlow/IfdsIde/EdgeFunctionUtils.h index bfbc9d233..72c4aa1a3 100644 --- a/include/phasar/DataFlow/IfdsIde/EdgeFunctionUtils.h +++ b/include/phasar/DataFlow/IfdsIde/EdgeFunctionUtils.h @@ -40,13 +40,67 @@ template struct EdgeIdentity final { const EdgeFunction &OtherFunction); }; +template struct ConstantEdgeFunction { + using l_t = L; + using JLattice = JoinLatticeTraits; + using value_type = typename NonTopBotValue::type; + + [[nodiscard]] l_t computeTarget(ByConstRef /*Source*/) const + noexcept(std::is_nothrow_constructible_v) { + static_assert(IsEdgeFunction); + return Value; + } + + template >> + [[nodiscard]] static EdgeFunction + compose(EdgeFunctionRef This, + const EdgeFunction &SecondFunction); + + template >> + [[nodiscard]] static EdgeFunction + join(EdgeFunctionRef This, + const EdgeFunction &OtherFunction); + + [[nodiscard]] constexpr bool isConstant() const noexcept { return true; } + + // -- constant data member + + value_type Value{}; +}; + +template >>> +[[nodiscard]] bool operator==(ConstantEdgeFunction LHS, + ConstantEdgeFunction RHS) noexcept { + return LHS.Value == RHS.Value; +} + +template >>> +[[nodiscard]] bool operator==(const ConstantEdgeFunction &LHS, + const ConstantEdgeFunction &RHS) noexcept { + return LHS.Value == RHS.Value; +} + +template +[[nodiscard]] llvm::raw_ostream & +operator<<(llvm::raw_ostream &OS, ByConstRef> Id) { + OS << "ConstantEF"; + if constexpr (is_llvm_printable_v< + typename ConstantEdgeFunction::value_type>) { + OS << '[' << Id.Value << ']'; + } + return OS; +} + template struct AllBottom final { using l_t = L; using JLattice = JoinLatticeTraits; [[no_unique_address]] std::conditional_t, EmptyType, - l_t> - BottomValue; + l_t> BottomValue; [[nodiscard]] l_t computeTarget(ByConstRef /*Source*/) const noexcept { static_assert(std::is_trivially_copyable_v); @@ -61,7 +115,25 @@ template struct AllBottom final { [[nodiscard]] static EdgeFunction compose(EdgeFunctionRef This, const EdgeFunction &SecondFunction) { - return SecondFunction.isConstant() ? SecondFunction : This; + if (SecondFunction.isConstant()) { + return SecondFunction; + } + + if constexpr (HasJoinLatticeTraits) { + auto ConstVal = SecondFunction.computeTarget(JLattice::bottom()); + if (ConstVal == JLattice::bottom()) { + return This; + } + + return ConstantEdgeFunction{ + NonTopBotValue::unwrap(std::move(ConstVal))}; + } else { + // Note: This used to be the default behavior, but it appears to be too + // restrictive + return This; + } + + // return SecondFunction.isConstant() ? SecondFunction : This; } [[nodiscard]] static EdgeFunction @@ -85,8 +157,7 @@ template struct AllTop final { using JLattice = JoinLatticeTraits; [[no_unique_address]] std::conditional_t, EmptyType, - l_t> - TopValue; + l_t> TopValue; [[nodiscard]] l_t computeTarget(ByConstRef /*Source*/) const noexcept { static_assert(std::is_trivially_copyable_v); @@ -149,97 +220,6 @@ defaultComposeOrNull(const EdgeFunction &This, return nullptr; } -template struct ConstantEdgeFunction { - using l_t = L; - using JLattice = JoinLatticeTraits; - using value_type = typename NonTopBotValue::type; - - [[nodiscard]] l_t computeTarget(ByConstRef /*Source*/) const - noexcept(std::is_nothrow_constructible_v) { - static_assert(IsEdgeFunction); - return Value; - } - - template >> - [[nodiscard]] static EdgeFunction - compose(EdgeFunctionRef This, - const EdgeFunction &SecondFunction) { - if (auto Default = defaultComposeOrNull(This, SecondFunction)) { - return Default; - } - - auto ConstVal = SecondFunction.computeTarget(This->Value); - if constexpr (!EdgeFunctionBase::IsSOOCandidate) { - if (ConstVal == This->Value) { - return This; - } - } - - if constexpr (AreEqualityComparable) { - if (JLattice::bottom() == ConstVal) { - return AllBottom{}; - } - } else { - if (l_t(JLattice::bottom()) == ConstVal) { - return AllBottom{}; - } - } - - if constexpr (AreEqualityComparable) { - if (JLattice::top() == ConstVal) { - /// TODO: Can this ever happen? - return AllTop{}; - } - } else { - if (l_t(JLattice::top()) == ConstVal) { - /// TODO: Can this ever happen? - return AllTop{}; - } - } - - return ConstantEdgeFunction{ - NonTopBotValue::unwrap(std::move(ConstVal))}; - } - - template >> - [[nodiscard]] static EdgeFunction - join(EdgeFunctionRef This, - const EdgeFunction &OtherFunction); - - [[nodiscard]] constexpr bool isConstant() const noexcept { return true; } - - // -- constant data member - - value_type Value{}; -}; - -template >>> -[[nodiscard]] bool operator==(ConstantEdgeFunction LHS, - ConstantEdgeFunction RHS) noexcept { - return LHS.Value == RHS.Value; -} - -template >>> -[[nodiscard]] bool operator==(const ConstantEdgeFunction &LHS, - const ConstantEdgeFunction &RHS) noexcept { - return LHS.Value == RHS.Value; -} - -template -[[nodiscard]] llvm::raw_ostream & -operator<<(llvm::raw_ostream &OS, ByConstRef> Id) { - OS << "ConstantEF"; - if constexpr (is_llvm_printable_v< - typename ConstantEdgeFunction::value_type>) { - OS << '[' << Id.Value << ']'; - } - return OS; -} - template struct EdgeFunctionComposer { using l_t = L; @@ -461,6 +441,47 @@ EdgeFunction EdgeIdentity::join(EdgeFunctionRef This, return OtherFunction.joinWith(This); } +template +template +EdgeFunction +ConstantEdgeFunction::compose(EdgeFunctionRef This, + const EdgeFunction &SecondFunction) { + if (auto Default = defaultComposeOrNull(This, SecondFunction)) { + return Default; + } + + auto ConstVal = SecondFunction.computeTarget(This->Value); + if constexpr (!EdgeFunctionBase::IsSOOCandidate) { + if (ConstVal == This->Value) { + return This; + } + } + + if constexpr (AreEqualityComparable) { + if (JLattice::bottom() == ConstVal) { + return AllBottom{}; + } + } else { + if (L(JLattice::bottom()) == ConstVal) { + return AllBottom{}; + } + } + + if constexpr (AreEqualityComparable) { + if (JLattice::top() == ConstVal) { + /// TODO: Can this ever happen? + return AllTop{}; + } + } else { + if (L(JLattice::top()) == ConstVal) { + /// TODO: Can this ever happen? + return AllTop{}; + } + } + + return ConstantEdgeFunction{NonTopBotValue::unwrap(std::move(ConstVal))}; +} + template template EdgeFunction diff --git a/lib/PhasarLLVM/Pointer/FilteredLLVMAliasSet.cpp b/lib/PhasarLLVM/Pointer/FilteredLLVMAliasSet.cpp index 1eac91310..cea041cbd 100644 --- a/lib/PhasarLLVM/Pointer/FilteredLLVMAliasSet.cpp +++ b/lib/PhasarLLVM/Pointer/FilteredLLVMAliasSet.cpp @@ -145,9 +145,8 @@ AliasResult FilteredLLVMAliasSet::alias(const llvm::Value *V1, return alias(V1, V2, I->getFunction()); } -auto FilteredLLVMAliasSet::getAliasSet(const llvm::Value *V, - const llvm::Function *Fun) - -> AliasSetPtrTy { +auto FilteredLLVMAliasSet::getAliasSet( + const llvm::Value *V, const llvm::Function *Fun) -> AliasSetPtrTy { if (!isInterestingPointer(V)) { return AS->getEmptyAliasSet(); } @@ -162,23 +161,22 @@ auto FilteredLLVMAliasSet::getAliasSet(const llvm::Value *V, return Entry; } -auto FilteredLLVMAliasSet::getAliasSet(const llvm::Value *V, - const llvm::Instruction *I) - -> AliasSetPtrTy { +auto FilteredLLVMAliasSet::getAliasSet( + const llvm::Value *V, const llvm::Instruction *I) -> AliasSetPtrTy { const auto *Fun = I ? I->getFunction() : nullptr; return getAliasSet(V, Fun); } auto FilteredLLVMAliasSet::getReachableAllocationSites( - const llvm::Value *V, bool IntraProcOnly, const llvm::Instruction *I) - -> AllocationSiteSetPtrTy { + const llvm::Value *V, bool IntraProcOnly, + const llvm::Instruction *I) -> AllocationSiteSetPtrTy { // if V is not a (interesting) pointer we can return an empty set if (!isInterestingPointer(V)) { return &getDefaultValue(); } - const auto *Fun = I->getFunction(); + const auto *Fun = I ? I->getFunction() : nullptr; auto &AllocSites = ReachableAllocationSitesMap[ReachableAllocationSitesKey{ {Fun, IntraProcOnly}, V}]; if (AllocSites) { @@ -220,6 +218,11 @@ auto FilteredLLVMAliasSet::getReachableAllocationSites( bool FilteredLLVMAliasSet::isInReachableAllocationSites( const llvm::Value *V, const llvm::Value *PotentialValue, bool IntraProcOnly, const llvm::Instruction *I) { + + if (I == V) { + return true; + } + // if V is not a (interesting) pointer we can return an empty set if (!isInterestingPointer(V)) { return false; From 4bbe19ff0ccea7e37b5a8e5c47f977c66a13c33d Mon Sep 17 00:00:00 2001 From: Fabian Schiebel Date: Mon, 5 May 2025 10:30:31 +0200 Subject: [PATCH 69/78] Make getAllExitPoints more flexible + minor --- include/phasar/PhasarLLVM/Utils/LLVMShorthands.h | 5 +++-- include/phasar/Utils/Utilities.h | 3 ++- lib/PhasarLLVM/Utils/LLVMShorthands.cpp | 9 +++++---- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/include/phasar/PhasarLLVM/Utils/LLVMShorthands.h b/include/phasar/PhasarLLVM/Utils/LLVMShorthands.h index 332d70452..bbcd660b0 100644 --- a/include/phasar/PhasarLLVM/Utils/LLVMShorthands.h +++ b/include/phasar/PhasarLLVM/Utils/LLVMShorthands.h @@ -181,10 +181,11 @@ const llvm::StoreInst *getNthStoreInstruction(const llvm::Function *F, unsigned StoNo); llvm::SmallVector -getAllExitPoints(const llvm::Function *F); +getAllExitPoints(const llvm::Function *F, bool IncludeResume = true); void appendAllExitPoints( const llvm::Function *F, - llvm::SmallVectorImpl &ExitPoints); + llvm::SmallVectorImpl &ExitPoints, + bool IncludeResume = true); /** * @brief Returns the LLVM Module to which the given LLVM Value belongs to. diff --git a/include/phasar/Utils/Utilities.h b/include/phasar/Utils/Utilities.h index f2c7504c7..d4924548a 100644 --- a/include/phasar/Utils/Utilities.h +++ b/include/phasar/Utils/Utilities.h @@ -249,7 +249,8 @@ auto remove_by_index(Container &Cont, const Indices &Idx) { /// See https://en.cppreference.com/w/cpp/utility/forward_like template -[[nodiscard]] constexpr auto &&forward_like(U &&X) noexcept { // NOLINT +[[nodiscard]] LLVM_ATTRIBUTE_ALWAYS_INLINE constexpr auto && +forward_like(U &&X) noexcept { // NOLINT // NOLINTNEXTLINE constexpr bool is_adding_const = std::is_const_v>; if constexpr (std::is_lvalue_reference_v) { diff --git a/lib/PhasarLLVM/Utils/LLVMShorthands.cpp b/lib/PhasarLLVM/Utils/LLVMShorthands.cpp index 9871d19e4..160b6efa2 100644 --- a/lib/PhasarLLVM/Utils/LLVMShorthands.cpp +++ b/lib/PhasarLLVM/Utils/LLVMShorthands.cpp @@ -317,15 +317,16 @@ const llvm::Instruction *psr::getNthInstruction(const llvm::Function *F, } llvm::SmallVector -psr::getAllExitPoints(const llvm::Function *F) { +psr::getAllExitPoints(const llvm::Function *F, bool IncludeResume) { llvm::SmallVector Ret; - appendAllExitPoints(F, Ret); + appendAllExitPoints(F, Ret, IncludeResume); return Ret; } void psr::appendAllExitPoints( const llvm::Function *F, - llvm::SmallVectorImpl &ExitPoints) { + llvm::SmallVectorImpl &ExitPoints, + bool IncludeResume) { if (!F) { return; } @@ -335,7 +336,7 @@ void psr::appendAllExitPoints( assert(Term && "Invalid IR: Each BasicBlock must have a terminator " "instruction at the end"); if (llvm::isa(Term) || - llvm::isa(Term)) { + (IncludeResume && llvm::isa(Term))) { ExitPoints.push_back(Term); } } From c95cc638b6abe38d44a252bf4d1fc05d6ecd797b Mon Sep 17 00:00:00 2001 From: Fabian Schiebel Date: Wed, 7 May 2025 10:17:39 +0200 Subject: [PATCH 70/78] Handle atexit() in GlobalCtorsDtorsModel (not only __cxa_atexit()) --- .../ControlFlow/GlobalCtorsDtorsModel.cpp | 64 +++++++++++++------ 1 file changed, 44 insertions(+), 20 deletions(-) diff --git a/lib/PhasarLLVM/ControlFlow/GlobalCtorsDtorsModel.cpp b/lib/PhasarLLVM/ControlFlow/GlobalCtorsDtorsModel.cpp index e6a53249b..cffe27cb8 100644 --- a/lib/PhasarLLVM/ControlFlow/GlobalCtorsDtorsModel.cpp +++ b/lib/PhasarLLVM/ControlFlow/GlobalCtorsDtorsModel.cpp @@ -15,6 +15,8 @@ #include "phasar/Utils/Logger.h" #include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/IR/DerivedTypes.h" #include "llvm/IR/IRBuilder.h" #include @@ -61,6 +63,33 @@ collectGlobalDtors(const llvm::Module &Mod) { return Ret; } +static llvm::SmallVector +collectRegisteredDtorsAtExit(const llvm::Module &Mod) { + llvm::SmallVector Ret; + + auto *AtExitFn = Mod.getFunction("atexit"); + if (!AtExitFn) { + return Ret; + } + + for (auto *User : AtExitFn->users()) { + auto *Call = llvm::dyn_cast(User); + if (!Call) { + continue; + } + + auto *DtorOp = llvm::dyn_cast_or_null( + Call->getArgOperand(0)->stripPointerCastsAndAliases()); + if (!DtorOp) { + continue; + } + + Ret.push_back(DtorOp); + } + + return Ret; +} + static llvm::SmallVector, 4> collectRegisteredDtorsForModule(const llvm::Module &Mod) { // NOLINTNEXTLINE @@ -72,16 +101,6 @@ collectRegisteredDtorsForModule(const llvm::Module &Mod) { return RegisteredDtors; } - auto getConstantBitcastArgument = // NOLINT - [](llvm::Value *V) -> llvm::Value * { - auto *CE = llvm::dyn_cast(V); - if (!CE) { - return V; - } - - return CE->getOperand(0); - }; - for (auto *User : CxaAtExitFn->users()) { auto *Call = llvm::dyn_cast(User); if (!Call) { @@ -89,8 +108,8 @@ collectRegisteredDtorsForModule(const llvm::Module &Mod) { } auto *DtorOp = llvm::dyn_cast_or_null( - getConstantBitcastArgument(Call->getArgOperand(0))); - auto *DtorArgOp = getConstantBitcastArgument(Call->getArgOperand(1)); + Call->getArgOperand(0)->stripPointerCastsAndAliases()); + auto *DtorArgOp = Call->getArgOperand(1)->stripPointerCastsAndAliases(); if (!DtorOp || !DtorArgOp) { continue; @@ -122,8 +141,9 @@ static std::string getReducedModuleName(const llvm::Module &M) { static llvm::Function *createDtorCallerForModule( llvm::Module &Mod, - const llvm::SmallVectorImpl> - &RegisteredDtors) { + llvm::ArrayRef> + RegisteredDtors, + llvm::ArrayRef RegisteredDtorsAtExit) { auto *PhasarDtorCaller = llvm::cast( Mod.getOrInsertFunction((GlobalCtorsDtorsModel::DtorsCallerName + @@ -137,12 +157,14 @@ static llvm::Function *createDtorCallerForModule( llvm::IRBuilder<> IRB(BB); - for (auto It = RegisteredDtors.rbegin(), End = RegisteredDtors.rend(); - It != End; ++It) { - auto FunCallee = It->first; + for (auto FunCallee : llvm::reverse(RegisteredDtorsAtExit)) { + IRB.CreateCall(FunCallee, {}); + } + + for (auto [FunCallee, Arg] : llvm::reverse(RegisteredDtors)) { assert(FunCallee.getFunctionType()->getNumParams() == 1); auto *ExpectedArgType = FunCallee.getFunctionType()->getParamType(0); - auto *Arg = It->second; + if (Arg->getType() != ExpectedArgType) { if (!Arg->getType()->canLosslesslyBitCastTo(ExpectedArgType)) { PHASAR_LOG_LEVEL( @@ -171,8 +193,9 @@ static llvm::Function *createDtorCallerForModule( "Collect Registered Dtors for Module " << Mod.getName()); auto RegisteredDtors = collectRegisteredDtorsForModule(Mod); + auto RegisteredDtorsAtExit = collectRegisteredDtorsAtExit(Mod); - if (RegisteredDtors.empty()) { + if (RegisteredDtors.empty() && RegisteredDtorsAtExit.empty()) { return nullptr; } @@ -180,7 +203,8 @@ static llvm::Function *createDtorCallerForModule( "> Found " << RegisteredDtors.size() << " Registered Dtors"); - auto *RegisteredDtorCaller = createDtorCallerForModule(Mod, RegisteredDtors); + auto *RegisteredDtorCaller = + createDtorCallerForModule(Mod, RegisteredDtors, RegisteredDtorsAtExit); // auto It = GlobalDtors.emplace(0, RegisteredDtorCaller); // GlobalDtorFn.try_emplace(RegisteredDtorCaller, it); From 52c15ff972027a63495b8366d9e4607152637634 Mon Sep 17 00:00:00 2001 From: Fabian Schiebel Date: Sun, 25 May 2025 12:49:48 +0200 Subject: [PATCH 71/78] minor fix in FilteredLLVMAliasSet::isInReachableAllocationSites --- lib/PhasarLLVM/Pointer/FilteredLLVMAliasSet.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/lib/PhasarLLVM/Pointer/FilteredLLVMAliasSet.cpp b/lib/PhasarLLVM/Pointer/FilteredLLVMAliasSet.cpp index 222fb42e5..f6ed829e8 100644 --- a/lib/PhasarLLVM/Pointer/FilteredLLVMAliasSet.cpp +++ b/lib/PhasarLLVM/Pointer/FilteredLLVMAliasSet.cpp @@ -147,8 +147,9 @@ AliasResult FilteredLLVMAliasSet::alias(const llvm::Value *V1, return alias(V1, V2, I->getFunction()); } -auto FilteredLLVMAliasSet::getAliasSet( - const llvm::Value *V, const llvm::Function *Fun) -> AliasSetPtrTy { +auto FilteredLLVMAliasSet::getAliasSet(const llvm::Value *V, + const llvm::Function *Fun) + -> AliasSetPtrTy { if (!isInterestingPointer(V)) { return AS->getEmptyAliasSet(); } @@ -163,15 +164,16 @@ auto FilteredLLVMAliasSet::getAliasSet( return Entry; } -auto FilteredLLVMAliasSet::getAliasSet( - const llvm::Value *V, const llvm::Instruction *I) -> AliasSetPtrTy { +auto FilteredLLVMAliasSet::getAliasSet(const llvm::Value *V, + const llvm::Instruction *I) + -> AliasSetPtrTy { const auto *Fun = I ? I->getFunction() : nullptr; return getAliasSet(V, Fun); } auto FilteredLLVMAliasSet::getReachableAllocationSites( - const llvm::Value *V, bool IntraProcOnly, - const llvm::Instruction *I) -> AllocationSiteSetPtrTy { + const llvm::Value *V, bool IntraProcOnly, const llvm::Instruction *I) + -> AllocationSiteSetPtrTy { // if V is not a (interesting) pointer we can return an empty set if (!isInterestingPointer(V)) { @@ -221,7 +223,7 @@ bool FilteredLLVMAliasSet::isInReachableAllocationSites( const llvm::Value *V, const llvm::Value *PotentialValue, bool IntraProcOnly, const llvm::Instruction *I) { - if (I == V) { + if (PotentialValue == V) { return true; } From 18c848a2775dd711207633ef3d048087d15636ef Mon Sep 17 00:00:00 2001 From: Fabian Schiebel Date: Sun, 25 May 2025 19:40:17 +0200 Subject: [PATCH 72/78] pre-commit --- include/phasar/Utils/Utilities.h | 4 +++- lib/PhasarLLVM/ControlFlow/LLVMBasedCallGraphBuilder.cpp | 8 ++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/include/phasar/Utils/Utilities.h b/include/phasar/Utils/Utilities.h index d4924548a..f4c77cc13 100644 --- a/include/phasar/Utils/Utilities.h +++ b/include/phasar/Utils/Utilities.h @@ -169,7 +169,9 @@ template class scope_exit { // NOLINT template scope_exit(Fn) -> scope_exit; // Copied from "https://en.cppreference.com/w/cpp/utility/variant/visit" -template struct Overloaded : Ts... { using Ts::operator()...; }; +template struct Overloaded : Ts... { + using Ts::operator()...; +}; // explicit deduction guide (not needed as of C++20) template Overloaded(Ts...) -> Overloaded; diff --git a/lib/PhasarLLVM/ControlFlow/LLVMBasedCallGraphBuilder.cpp b/lib/PhasarLLVM/ControlFlow/LLVMBasedCallGraphBuilder.cpp index 692d1ea7a..e3f65c00e 100644 --- a/lib/PhasarLLVM/ControlFlow/LLVMBasedCallGraphBuilder.cpp +++ b/lib/PhasarLLVM/ControlFlow/LLVMBasedCallGraphBuilder.cpp @@ -111,8 +111,8 @@ static bool fillPossibleTargets( PossibleTargets.insert(StaticCallee); PHASAR_LOG_LEVEL_CAT(DEBUG, "LLVMBasedICFG", - "Found static call-site: " - << " " << llvmIRToString(CS)); + "Found static call-site: " << " " + << llvmIRToString(CS)); return true; } @@ -122,8 +122,8 @@ static bool fillPossibleTargets( // the function call must be resolved dynamically PHASAR_LOG_LEVEL_CAT(DEBUG, "LLVMBasedICFG", - "Found dynamic call-site: " - << " " << llvmIRToString(CS)); + "Found dynamic call-site: " << " " + << llvmIRToString(CS)); PossibleTargets = Res.resolveIndirectCall(CS); From 3076b13c45dfad614261d6b866edbedbe2969362 Mon Sep 17 00:00:00 2001 From: Fabian Schiebel <52407375+fabianbs96@users.noreply.github.com> Date: Sat, 31 May 2025 15:13:36 +0200 Subject: [PATCH 73/78] pre-commit --- include/phasar/Utils/Utilities.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/phasar/Utils/Utilities.h b/include/phasar/Utils/Utilities.h index 71222ae05..a4265d36f 100644 --- a/include/phasar/Utils/Utilities.h +++ b/include/phasar/Utils/Utilities.h @@ -168,7 +168,6 @@ template class scope_exit { // NOLINT template scope_exit(Fn) -> scope_exit; - // Copied from template struct Overloaded : Ts... { using Ts::operator()...; From e6bd1e5b579070480ccfad6eec309a35aefeb671 Mon Sep 17 00:00:00 2001 From: Fabian Schiebel Date: Sat, 31 May 2025 15:15:57 +0200 Subject: [PATCH 74/78] Fix name --- include/phasar/PhasarLLVM/ControlFlow/SparseLLVMBasedICFG.h | 2 +- include/phasar/PhasarLLVM/ControlFlow/SparseLLVMBasedICFGView.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/phasar/PhasarLLVM/ControlFlow/SparseLLVMBasedICFG.h b/include/phasar/PhasarLLVM/ControlFlow/SparseLLVMBasedICFG.h index df946ae27..d9a1d9a93 100644 --- a/include/phasar/PhasarLLVM/ControlFlow/SparseLLVMBasedICFG.h +++ b/include/phasar/PhasarLLVM/ControlFlow/SparseLLVMBasedICFG.h @@ -24,7 +24,7 @@ struct SVFGCache; /// Conforms to the ICFGBase CRTP interface. /// /// Use this in the IDESolver or IFDSSolver to profit from the SparseIFDS or -/// SparseIDE optimization after Karakays et al. "Symbol-Specific Sparsification +/// SparseIDE optimization after Karakaya et al. "Symbol-Specific Sparsification /// of Interprocedural Distributive Environment Problems" /// class SparseLLVMBasedICFG diff --git a/include/phasar/PhasarLLVM/ControlFlow/SparseLLVMBasedICFGView.h b/include/phasar/PhasarLLVM/ControlFlow/SparseLLVMBasedICFGView.h index 7fbbb65a5..b5587939d 100644 --- a/include/phasar/PhasarLLVM/ControlFlow/SparseLLVMBasedICFGView.h +++ b/include/phasar/PhasarLLVM/ControlFlow/SparseLLVMBasedICFGView.h @@ -34,7 +34,7 @@ struct CFGTraits : CFGTraits {}; /// It still owns the sparse value-flow graphs. /// /// Use this in the IDESolver or IFDSSolver to profit from the SparseIFDS or -/// SparseIDE optimization after Karakays et al. "Symbol-Specific Sparsification +/// SparseIDE optimization after Karakaya et al. "Symbol-Specific Sparsification /// of Interprocedural Distributive Environment Problems" /// class SparseLLVMBasedICFGView From 93573940b587207757301a313259886d5fbfa2f8 Mon Sep 17 00:00:00 2001 From: Fabian Schiebel Date: Sat, 7 Jun 2025 19:42:28 +0200 Subject: [PATCH 75/78] Fix new CastInfo for EdgeFunction --- include/phasar/DataFlow/IfdsIde/EdgeFunction.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/include/phasar/DataFlow/IfdsIde/EdgeFunction.h b/include/phasar/DataFlow/IfdsIde/EdgeFunction.h index ca6c0ad70..0559e17af 100644 --- a/include/phasar/DataFlow/IfdsIde/EdgeFunction.h +++ b/include/phasar/DataFlow/IfdsIde/EdgeFunction.h @@ -827,8 +827,7 @@ template struct DenseMapInfo> { // LLVM is currently overhauling its casting system. Use the new variant once // possible! -// Note: The new variant (With CastInfo) is not tested yet! -#if LLVM_MAJOR < 15 +#if LLVM_VERSION_MAJOR < 15 template struct isa_impl_cl> { @@ -876,7 +875,7 @@ cast_or_null(const psr::EdgeFunction &EF) noexcept { // NOLINT template struct CastIsPossible> { static inline bool isPossible(const psr::EdgeFunction &EF) noexcept { - return EF->template isa(); + return EF.template isa(); } }; From 97c391378d846874da114aee2e28eb043a9dd2cd Mon Sep 17 00:00:00 2001 From: Fabian Schiebel Date: Sat, 7 Jun 2025 20:47:41 +0200 Subject: [PATCH 76/78] Make LLVMProjectIRDB movable and add static function load() that returns an ErrorOr --- .../phasar/PhasarLLVM/DB/LLVMProjectIRDB.h | 21 +++- include/phasar/Utils/Macros.h | 8 ++ lib/PhasarLLVM/DB/LLVMProjectIRDB.cpp | 96 +++++++++++++++++-- 3 files changed, 117 insertions(+), 8 deletions(-) diff --git a/include/phasar/PhasarLLVM/DB/LLVMProjectIRDB.h b/include/phasar/PhasarLLVM/DB/LLVMProjectIRDB.h index 0b970fcfe..6d334273f 100644 --- a/include/phasar/PhasarLLVM/DB/LLVMProjectIRDB.h +++ b/include/phasar/PhasarLLVM/DB/LLVMProjectIRDB.h @@ -21,6 +21,7 @@ #include "llvm/IR/Instruction.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Module.h" +#include "llvm/Support/ErrorOr.h" #include "llvm/Support/MemoryBufferRef.h" #include "llvm/Support/raw_ostream.h" @@ -56,6 +57,14 @@ class LLVMProjectIRDB : public ProjectIRDBBase { /// ownership of it. The module is optionally being preprocessed. explicit LLVMProjectIRDB(std::unique_ptr Mod, bool DoPreprocessing = true); + /// Initializes the new ProjectIRDB with the given IR Module and takes + /// ownership of it. The module is optionally being preprocessed. Takes the + /// given LLVMContext and binds its lifetime to the lifetime of the + /// constructed ProjectIRDB + explicit LLVMProjectIRDB(std::unique_ptr Mod, + std::unique_ptr Ctx, + bool DoPreprocessing = true); + /// 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. @@ -63,7 +72,10 @@ class LLVMProjectIRDB : public ProjectIRDBBase { bool EnableOpaquePointers = LLVM_VERSION_MAJOR > 14); LLVMProjectIRDB(const LLVMProjectIRDB &) = delete; - LLVMProjectIRDB &operator=(LLVMProjectIRDB &) = delete; + LLVMProjectIRDB &operator=(const LLVMProjectIRDB &) = delete; + + LLVMProjectIRDB(LLVMProjectIRDB &&) noexcept = default; + LLVMProjectIRDB &operator=(LLVMProjectIRDB &&) noexcept = default; ~LLVMProjectIRDB(); @@ -74,6 +86,10 @@ class LLVMProjectIRDB : public ProjectIRDBBase { getParsedIRModuleOrNull(llvm::MemoryBufferRef IRFileContent, llvm::LLVMContext &Ctx) noexcept; + [[nodiscard]] static llvm::ErrorOr + load(const llvm::Twine &IRFileName, + bool EnableOpaquePointers = LLVM_VERSION_MAJOR > 14); + /// Also use the const overload using ProjectIRDBBase::getFunction; /// Non-const overload @@ -163,7 +179,8 @@ class LLVMProjectIRDB : public ProjectIRDBBase { /// the preprocessing as well void preprocessModule(llvm::Module *NonConstMod); - llvm::LLVMContext Ctx; + // LLVMContext is not movable, so wrap it into a unique_ptr + std::unique_ptr Ctx; MaybeUniquePtr Mod = nullptr; size_t IdOffset = 0; llvm::SmallVector IdToInst; diff --git a/include/phasar/Utils/Macros.h b/include/phasar/Utils/Macros.h index 9620018de..a5c104a4a 100644 --- a/include/phasar/Utils/Macros.h +++ b/include/phasar/Utils/Macros.h @@ -18,4 +18,12 @@ #define PSR_CONCEPT concept #endif +#if __cpp_constinit >= 201907L +#define PSR_CONSTINIT constinit +#elif __clang__ +#define PSR_CONSTINIT [[clang::require_constant_initialization]] +#else +#define PSR_CONSTINIT +#endif + #endif // PHASAR_UTILS_MACROS_H diff --git a/lib/PhasarLLVM/DB/LLVMProjectIRDB.cpp b/lib/PhasarLLVM/DB/LLVMProjectIRDB.cpp index 2bb171e1b..d27aadbca 100644 --- a/lib/PhasarLLVM/DB/LLVMProjectIRDB.cpp +++ b/lib/PhasarLLVM/DB/LLVMProjectIRDB.cpp @@ -3,20 +3,25 @@ #include "phasar/Config/Configuration.h" #include "phasar/PhasarLLVM/Utils/LLVMShorthands.h" #include "phasar/Utils/Logger.h" +#include "phasar/Utils/Macros.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringRef.h" #include "llvm/IR/AssemblyAnnotationWriter.h" #include "llvm/IR/GlobalVariable.h" #include "llvm/IR/InstIterator.h" +#include "llvm/IR/LLVMContext.h" #include "llvm/IR/Verifier.h" #include "llvm/IRReader/IRReader.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/Errc.h" #include "llvm/Support/FormattedStream.h" #include "llvm/Support/MemoryBufferRef.h" #include "llvm/Support/SourceMgr.h" #include +#include +#include namespace psr { @@ -35,6 +40,45 @@ static void setOpaquePointersForCtx(llvm::LLVMContext &Ctx, bool Enable) { #endif } +namespace { +enum class IRDBParsingError { + CouldNotParse = 1, + CouldNotVerify = 2, +}; + +class IRDBParsingErrorCategory : public std::error_category { + [[nodiscard]] const char *name() const noexcept override { + return "IRDBParsingError"; + } + + [[nodiscard]] std::string message(int Value) const override { + switch (IRDBParsingError(Value)) { + case IRDBParsingError::CouldNotParse: + return "Could not parse LLVM IR"; + case IRDBParsingError::CouldNotVerify: + return "Parsed LLVM IR could not be verified"; + default: + ""; + } + } +}; + +PSR_CONSTINIT IRDBParsingErrorCategory IRDBParsingErrorCat{}; + +std::error_code make_error_code(IRDBParsingError Err) noexcept { + // TODO + return {int(Err), IRDBParsingErrorCat}; +} +} // namespace + +} // namespace psr + +namespace std { +template <> struct is_error_code_enum : true_type {}; +} // namespace std + +namespace psr { + std::unique_ptr LLVMProjectIRDB::getParsedIRModuleOrNull(llvm::MemoryBufferRef IRFileContent, llvm::LLVMContext &Ctx) noexcept { @@ -76,10 +120,42 @@ LLVMProjectIRDB::getParsedIRModuleOrNull(const llvm::Twine &IRFileName, return getParsedIRModuleOrNull(*FileOrErr.get(), Ctx); } +llvm::ErrorOr +LLVMProjectIRDB::load(const llvm::Twine &IRFileName, + bool EnableOpaquePointers) { + auto FileOrErr = + llvm::MemoryBuffer::getFileOrSTDIN(IRFileName, /*IsText=*/true); + if (!FileOrErr) { + return FileOrErr.getError(); + } + + auto Ctx = std::make_unique(); + + llvm::SMDiagnostic Diag; + std::unique_ptr M = llvm::parseIR(**FileOrErr, Diag, *Ctx); + bool BrokenDebugInfo = false; + if (M == nullptr) { + Diag.print(nullptr, llvm::errs()); + return IRDBParsingError::CouldNotParse; + } + + if (llvm::verifyModule(*M, &llvm::errs(), &BrokenDebugInfo)) { + PHASAR_LOG_LEVEL(ERROR, FileOrErr.get()->getBufferIdentifier() + << " could not be parsed correctly!"); + return IRDBParsingError::CouldNotVerify; + } + if (BrokenDebugInfo) { + PHASAR_LOG_LEVEL(WARNING, "Debug info is broken!"); + } + + return LLVMProjectIRDB(std::move(M), std::move(Ctx), EnableOpaquePointers); +} + LLVMProjectIRDB::LLVMProjectIRDB(const llvm::Twine &IRFileName, - bool EnableOpaquePointers) { - setOpaquePointersForCtx(Ctx, EnableOpaquePointers); - auto M = getParsedIRModuleOrNull(IRFileName, Ctx); + bool EnableOpaquePointers) + : Ctx(new llvm::LLVMContext()) { + setOpaquePointersForCtx(*Ctx, EnableOpaquePointers); + auto M = getParsedIRModuleOrNull(IRFileName, *Ctx); if (!M) { return; @@ -171,10 +247,18 @@ LLVMProjectIRDB::LLVMProjectIRDB(std::unique_ptr Mod, } } +LLVMProjectIRDB::LLVMProjectIRDB(std::unique_ptr Mod, + std::unique_ptr Ctx, + bool DoPreprocessing) + : LLVMProjectIRDB(std::move(Mod), DoPreprocessing) { + this->Ctx = std::move(Ctx); +} + LLVMProjectIRDB::LLVMProjectIRDB(llvm::MemoryBufferRef Buf, - bool EnableOpaquePointers) { - setOpaquePointersForCtx(Ctx, EnableOpaquePointers); - auto M = getParsedIRModuleOrNull(Buf, Ctx); + bool EnableOpaquePointers) + : Ctx(new llvm::LLVMContext()) { + setOpaquePointersForCtx(*Ctx, EnableOpaquePointers); + auto M = getParsedIRModuleOrNull(Buf, *Ctx); if (!M) { return; } From 7a88fa9aa44e9a9f95429112b4dd63541f7cf187 Mon Sep 17 00:00:00 2001 From: Fabian Schiebel Date: Sun, 13 Jul 2025 17:42:24 +0200 Subject: [PATCH 77/78] Add function to find the va-list alloca to reduce code duplication --- .../DataFlow/IfdsIde/LLVMFlowFunctions.h | 44 +++-------------- .../Problems/IDEExtendedTaintAnalysis.h | 2 - .../phasar/PhasarLLVM/Utils/LLVMShorthands.h | 6 +++ .../ControlFlow/Resolver/OTFResolver.cpp | 18 +------ .../Problems/IDEExtendedTaintAnalysis.cpp | 25 +--------- .../MapFactsToCalleeFlowFunction.cpp | 28 +++-------- .../MapFactsToCallerFlowFunction.cpp | 20 ++------ .../IfdsIde/Problems/IDETypeStateAnalysis.cpp | 20 +------- lib/PhasarLLVM/Utils/LLVMShorthands.cpp | 48 +++++++++++++++++-- 9 files changed, 69 insertions(+), 142 deletions(-) diff --git a/include/phasar/PhasarLLVM/DataFlow/IfdsIde/LLVMFlowFunctions.h b/include/phasar/PhasarLLVM/DataFlow/IfdsIde/LLVMFlowFunctions.h index cf568e283..83fc7252e 100644 --- a/include/phasar/PhasarLLVM/DataFlow/IfdsIde/LLVMFlowFunctions.h +++ b/include/phasar/PhasarLLVM/DataFlow/IfdsIde/LLVMFlowFunctions.h @@ -193,26 +193,8 @@ mapFactsToCallee(const llvm::CallBase *CallSite, const llvm::Function *DestFun, std::any_of( ArgIt, ArgEnd, std::bind(std::ref(PropArg), std::placeholders::_1, Source))) { - // Over-approximate by trying to add the - // alloca [1 x %struct.__va_list_tag], align 16 - // to the results - // find the allocated %struct.__va_list_tag and generate it - - for (const auto &BB : *DestFun) { - for (const auto &I : BB) { - if (const auto *Alloc = llvm::dyn_cast(&I)) { - if (Alloc->getAllocatedType()->isArrayTy() && - Alloc->getAllocatedType()->getArrayNumElements() > 0 && - Alloc->getAllocatedType() - ->getArrayElementType() - ->isStructTy() && - Alloc->getAllocatedType() - ->getArrayElementType() - ->getStructName() == "struct.__va_list_tag") { - Res.insert(std::invoke(FactConstructor, Alloc)); - } - } - } + if (const auto *VaListAlloca = getVaListTagOrNull(*DestFun)) { + Res.insert(std::invoke(FactConstructor, VaListAlloca)); } } @@ -306,24 +288,10 @@ FlowFunctionPtrType mapFactsToCaller( } if (ArgIt != ArgEnd) { - // Over-approximate by trying to add the - // alloca [1 x %struct.__va_list_tag], align 16 - // to the results - // find the allocated %struct.__va_list_tag and generate it - - for (const auto &I : llvm::instructions(DestFun)) { - if (const auto *Alloc = llvm::dyn_cast(&I)) { - const auto *AllocTy = Alloc->getAllocatedType(); - if (AllocTy->isArrayTy() && AllocTy->getArrayNumElements() > 0 && - AllocTy->getArrayElementType()->isStructTy() && - AllocTy->getArrayElementType()->getStructName() == - "struct.__va_list_tag") { - if (std::invoke(PropArg, Alloc, Source)) { - std::transform(ArgIt, ArgEnd, std::inserter(Res, Res.end()), - FactConstructor); - break; - } - } + if (const auto *VaListAlloca = getVaListTagOrNull(*DestFun)) { + if (std::invoke(PropArg, VaListAlloca, Source)) { + std::transform(ArgIt, ArgEnd, std::inserter(Res, Res.end()), + FactConstructor); } } } diff --git a/include/phasar/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEExtendedTaintAnalysis.h b/include/phasar/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEExtendedTaintAnalysis.h index bad969a70..fa1efd880 100644 --- a/include/phasar/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEExtendedTaintAnalysis.h +++ b/include/phasar/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEExtendedTaintAnalysis.h @@ -154,8 +154,6 @@ class IDEExtendedTaintAnalysis } } - static const llvm::Value *getVAListTagOrNull(const llvm::Function *DestFun); - void populateWithMayAliases(SourceConfigTy &Facts); bool isMustAlias(const SanitizerConfigTy &Facts, d_t CurrNod); diff --git a/include/phasar/PhasarLLVM/Utils/LLVMShorthands.h b/include/phasar/PhasarLLVM/Utils/LLVMShorthands.h index 3a96157e3..8407a8d83 100644 --- a/include/phasar/PhasarLLVM/Utils/LLVMShorthands.h +++ b/include/phasar/PhasarLLVM/Utils/LLVMShorthands.h @@ -33,6 +33,7 @@ class StoreInst; class BranchInst; class Module; class CallInst; +class AllocaInst; } // namespace llvm namespace psr { @@ -273,6 +274,11 @@ class ModulesToSlotTracker { static llvm::ModuleSlotTracker & getSlotTrackerForModule(const llvm::Module *Module); }; + +[[nodiscard]] const llvm::AllocaInst * +getVaListTagOrNull(const llvm::Function &Fun); + +[[nodiscard]] bool isVaListAlloca(const llvm::AllocaInst &Alloc); } // namespace psr #endif diff --git a/lib/PhasarLLVM/ControlFlow/Resolver/OTFResolver.cpp b/lib/PhasarLLVM/ControlFlow/Resolver/OTFResolver.cpp index 6e70e7de0..d82c1d29c 100644 --- a/lib/PhasarLLVM/ControlFlow/Resolver/OTFResolver.cpp +++ b/lib/PhasarLLVM/ControlFlow/Resolver/OTFResolver.cpp @@ -252,24 +252,8 @@ OTFResolver::getActualFormalPointerPairs(const llvm::CallBase *CallSite, // in case of vararg, we can pair-up incoming pointer parameters with the // vararg pack of the callee target. the vararg pack will alias // (intra-procedurally) with any pointer values loaded from the pack - const llvm::AllocaInst *VarArgs = nullptr; - - for (const auto &I : llvm::instructions(CalleeTarget)) { - if (const auto *Alloca = llvm::dyn_cast(&I)) { - if (const auto *AT = - llvm::dyn_cast(Alloca->getAllocatedType())) { - if (const auto *ST = - llvm::dyn_cast(AT->getArrayElementType())) { - if (ST->hasName() && ST->getName() == "struct.__va_list_tag") { - VarArgs = Alloca; - break; - } - } - } - } - } - if (VarArgs) { + if (const auto *VarArgs = getVaListTagOrNull(*CalleeTarget)) { for (; Idx < CallSite->arg_size(); ++Idx) { if (CallSite->getArgOperand(Idx)->getType()->isPointerTy()) { Pairs.emplace_back(CallSite->getArgOperand(Idx), VarArgs); diff --git a/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEExtendedTaintAnalysis.cpp b/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEExtendedTaintAnalysis.cpp index b617db988..1f189a29c 100644 --- a/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEExtendedTaintAnalysis.cpp +++ b/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEExtendedTaintAnalysis.cpp @@ -301,7 +301,7 @@ IDEExtendedTaintAnalysis::getCallFlowFunction(n_t CallStmt, f_t DestFun) { } bool HasVarargs = Call->arg_size() > DestFun->arg_size(); - const auto *const VA = HasVarargs ? getVAListTagOrNull(DestFun) : nullptr; + const auto *const VA = HasVarargs ? getVaListTagOrNull(*DestFun) : nullptr; return lambdaFlow([this, Call, DestFun, VA](d_t Source) -> std::set { if (isZeroValue(Source)) { @@ -359,29 +359,6 @@ IDEExtendedTaintAnalysis::getCallFlowFunction(n_t CallStmt, f_t DestFun) { }); } -const llvm::Value * -IDEExtendedTaintAnalysis::getVAListTagOrNull(const llvm::Function *DestFun) { - // Copied from IDELinearConstantAnalysis: - // Over-approximate by trying to add the - // alloca [1 x %struct.__va_list_tag], align 16 - // to the results - // find the allocated %struct.__va_list_tag and generate it - for (auto It = llvm::inst_begin(DestFun), End = llvm::inst_end(DestFun); - It != End; ++It) { - if (const auto *Alloc = llvm::dyn_cast(&*It)) { - if (Alloc->getAllocatedType()->isArrayTy() && - Alloc->getAllocatedType()->getArrayNumElements() > 0 && - Alloc->getAllocatedType()->getArrayElementType()->isStructTy() && - Alloc->getAllocatedType()->getArrayElementType()->getStructName() == - "struct.__va_list_tag") { - return Alloc; - } - } - } - // Maybe the va_list is unused in the function body - return nullptr; -} - IDEExtendedTaintAnalysis::FlowFunctionPtrType IDEExtendedTaintAnalysis::getRetFlowFunction(n_t CallSite, f_t CalleeFun, n_t ExitStmt, diff --git a/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEGeneralizedLCA/MapFactsToCalleeFlowFunction.cpp b/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEGeneralizedLCA/MapFactsToCalleeFlowFunction.cpp index d00d89537..67ff7b7c6 100644 --- a/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEGeneralizedLCA/MapFactsToCalleeFlowFunction.cpp +++ b/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEGeneralizedLCA/MapFactsToCalleeFlowFunction.cpp @@ -9,11 +9,13 @@ #include "phasar/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEGeneralizedLCA/MapFactsToCalleeFlowFunction.h" -#include "phasar/PhasarLLVM/DataFlow/IfdsIde/LLVMFlowFunctions.h" #include "phasar/PhasarLLVM/DataFlow/IfdsIde/LLVMZeroValue.h" #include "phasar/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEGeneralizedLCA/ConstantHelper.h" #include "phasar/PhasarLLVM/Utils/LLVMShorthands.h" +#include "llvm/IR/InstrTypes.h" +#include "llvm/IR/Instructions.h" + namespace psr::glca { MapFactsToCalleeFlowFunction::MapFactsToCalleeFlowFunction( @@ -34,30 +36,14 @@ MapFactsToCalleeFlowFunction::computeTargets(const llvm::Value *Source) { std::set Res; // Handle C-style varargs functions if (Callee->isVarArg()) { + const auto *VaListAlloca = getVaListTagOrNull(*Callee); // Map actual parameter into corresponding formal parameter. for (unsigned Idx = 0; Idx < Actuals.size(); ++Idx) { if (Source == Actuals[Idx] || (LLVMZeroValue::isLLVMZeroValue(Source) && isConstant(Actuals[Idx]))) { - if (Idx >= Callee->arg_size() && !Callee->isDeclaration()) { - // Over-approximate by trying to add the - // alloca [1 x %struct.__va_list_tag], align 16 - // to the results - // find the allocated %struct.__va_list_tag and generate it - for (const auto &BB : *Callee) { - for (const auto &I : BB) { - if (const auto *Alloc = llvm::dyn_cast(&I)) { - if (Alloc->getAllocatedType()->isArrayTy() && - Alloc->getAllocatedType()->getArrayNumElements() > 0 && - Alloc->getAllocatedType() - ->getArrayElementType() - ->isStructTy() && - Alloc->getAllocatedType() - ->getArrayElementType() - ->getStructName() == "struct.__va_list_tag") { - Res.insert(Alloc); - } - } - } + if (Idx >= Callee->arg_size()) { + if (VaListAlloca) { + Res.insert(VaListAlloca); } } else { Res.insert(Formals[Idx]); // corresponding formal diff --git a/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEGeneralizedLCA/MapFactsToCallerFlowFunction.cpp b/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEGeneralizedLCA/MapFactsToCallerFlowFunction.cpp index 731a7ecd5..e26d801d0 100644 --- a/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEGeneralizedLCA/MapFactsToCallerFlowFunction.cpp +++ b/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEGeneralizedLCA/MapFactsToCallerFlowFunction.cpp @@ -10,6 +10,7 @@ #include "phasar/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEGeneralizedLCA/MapFactsToCallerFlowFunction.h" #include "phasar/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEGeneralizedLCA/ConstantHelper.h" +#include "phasar/PhasarLLVM/Utils/LLVMShorthands.h" #include "llvm/IR/Function.h" #include "llvm/IR/InstrTypes.h" @@ -37,23 +38,8 @@ MapFactsToCallerFlowFunction::computeTargets(const llvm::Value *Source) { std::set Res; // Handle C-style varargs functions if (Callee->isVarArg() && !Callee->isDeclaration()) { - const llvm::Instruction *AllocVarArg = nullptr; - // Find the allocation of %struct.__va_list_tag - for (const auto &BB : *Callee) { - for (const auto &I : BB) { - if (const auto *Alloc = llvm::dyn_cast(&I)) { - if (Alloc->getAllocatedType()->isArrayTy() && - Alloc->getAllocatedType()->getArrayNumElements() > 0 && - Alloc->getAllocatedType()->getArrayElementType()->isStructTy() && - Alloc->getAllocatedType() - ->getArrayElementType() - ->getStructName() == "struct.__va_list_tag") { - AllocVarArg = Alloc; - // TODO break out this nested loop earlier (without goto ;-) - } - } - } - } + const auto *AllocVarArg = getVaListTagOrNull(*Callee); + // Generate the varargs things by using an over-approximation if (Source != nullptr && Source == AllocVarArg && Source->getType()->isPointerTy()) { diff --git a/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/IDETypeStateAnalysis.cpp b/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/IDETypeStateAnalysis.cpp index 0a8853338..2ad21cc68 100644 --- a/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/IDETypeStateAnalysis.cpp +++ b/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/IDETypeStateAnalysis.cpp @@ -124,25 +124,7 @@ auto IDETypeStateAnalysisBase::getRetFlowFunction(n_t CallSite, f_t CalleeFun, container_type Res; // Handle C-style varargs functions if (CalleeFun->isVarArg() && !CalleeFun->isDeclaration()) { - const llvm::Instruction *AllocVarArg; - // Find the allocation of %struct.__va_list_tag - for (const auto &BB : *CalleeFun) { - for (const auto &I : BB) { - if (const auto *Alloc = llvm::dyn_cast(&I)) { - if (Alloc->getAllocatedType()->isArrayTy() && - Alloc->getAllocatedType()->getArrayNumElements() > 0 && - Alloc->getAllocatedType() - ->getArrayElementType() - ->isStructTy() && - Alloc->getAllocatedType() - ->getArrayElementType() - ->getStructName() == "struct.__va_list_tag") { - AllocVarArg = Alloc; - // TODO break out this nested loop earlier (without goto ;-) - } - } - } - } + const auto *AllocVarArg = getVaListTagOrNull(*CalleeFun); // Generate the varargs things by using an over-approximation if (Source == AllocVarArg) { for (unsigned Idx = CalleeFun->arg_size(); Idx < CS->arg_size(); diff --git a/lib/PhasarLLVM/Utils/LLVMShorthands.cpp b/lib/PhasarLLVM/Utils/LLVMShorthands.cpp index 2b13575ff..58f10e72f 100644 --- a/lib/PhasarLLVM/Utils/LLVMShorthands.cpp +++ b/lib/PhasarLLVM/Utils/LLVMShorthands.cpp @@ -27,8 +27,10 @@ #include "llvm/IR/Constants.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/Function.h" +#include "llvm/IR/InstIterator.h" #include "llvm/IR/Instruction.h" #include "llvm/IR/Instructions.h" +#include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/Module.h" #include "llvm/IR/ModuleSlotTracker.h" #include "llvm/IR/Value.h" @@ -40,7 +42,6 @@ #include #include -using namespace std; using namespace psr; bool psr::isIntegerLikeType(const llvm::Type *T) noexcept { @@ -275,9 +276,9 @@ std::string psr::getMetaDataID(const llvm::Value *V) { .str(); } } else if (const auto *Arg = llvm::dyn_cast(V)) { - string FName = Arg->getParent()->getName().str(); - string ArgNr = std::to_string(getFunctionArgumentNr(Arg)); - return string(FName + "." + ArgNr); + std::string FName = Arg->getParent()->getName().str(); + std::string ArgNr = std::to_string(getFunctionArgumentNr(Arg)); + return FName + "." + ArgNr; } return "-1"; } @@ -565,3 +566,42 @@ void ModulesToSlotTracker::deleteMSTForModule(const llvm::Module *M) { MToST.erase(It); } } + +const llvm::AllocaInst *psr::getVaListTagOrNull(const llvm::Function &Fun) { + if (Fun.isDeclaration()) { + return nullptr; + } + for (const auto &I : llvm::instructions(Fun)) { + if (const auto *Alloca = llvm::dyn_cast(&I); + Alloca && isVaListAlloca(*Alloca)) { + return Alloca; + } + } + return nullptr; +} + +bool psr::isVaListAlloca(const llvm::AllocaInst &Alloc) { + // Over-approximate by trying to add the + // alloca [1 x %struct.__va_list_tag], align 16 + // to the results + + const auto *Ty = Alloc.getAllocatedType(); + if (Ty->isArrayTy() && Ty->getArrayNumElements() > 0 && + Ty->getArrayElementType()->isStructTy() && + Ty->getArrayElementType()->getStructName() == "struct.__va_list_tag") { + return true; + } + + // On windows, the alloca just allocates a pointer that is directly used by + // the va_start intrinsic. + // Note that on linux (where the above __va_list_tag heuristic works), the + // alloca is *not* directly used by the va_start intrinsic; there, a gep lays + // in between + for (const auto &Use : Alloc.uses()) { + if (llvm::isa(Use.getUser())) { + return true; + } + } + + return false; +} From f28a53df3262a8082b5ba81e338b27411e226c5f Mon Sep 17 00:00:00 2001 From: Fabian Schiebel Date: Sun, 13 Jul 2025 18:32:48 +0200 Subject: [PATCH 78/78] Remove TODO in ProjectIRDB --- .../phasar/PhasarLLVM/DB/LLVMProjectIRDB.h | 7 ++ lib/PhasarLLVM/DB/LLVMProjectIRDB.cpp | 78 ++++++++++--------- 2 files changed, 48 insertions(+), 37 deletions(-) diff --git a/include/phasar/PhasarLLVM/DB/LLVMProjectIRDB.h b/include/phasar/PhasarLLVM/DB/LLVMProjectIRDB.h index 6d334273f..a80f28504 100644 --- a/include/phasar/PhasarLLVM/DB/LLVMProjectIRDB.h +++ b/include/phasar/PhasarLLVM/DB/LLVMProjectIRDB.h @@ -86,6 +86,13 @@ class LLVMProjectIRDB : public ProjectIRDBBase { getParsedIRModuleOrNull(llvm::MemoryBufferRef IRFileContent, llvm::LLVMContext &Ctx) noexcept; + [[nodiscard]] static llvm::ErrorOr> + getParsedIRModuleOrErr(const llvm::Twine &IRFileName, + llvm::LLVMContext &Ctx) noexcept; + [[nodiscard]] static llvm::ErrorOr> + getParsedIRModuleOrErr(llvm::MemoryBufferRef IRFileContent, + llvm::LLVMContext &Ctx) noexcept; + [[nodiscard]] static llvm::ErrorOr load(const llvm::Twine &IRFileName, bool EnableOpaquePointers = LLVM_VERSION_MAJOR > 14); diff --git a/lib/PhasarLLVM/DB/LLVMProjectIRDB.cpp b/lib/PhasarLLVM/DB/LLVMProjectIRDB.cpp index d27aadbca..2f6c81d99 100644 --- a/lib/PhasarLLVM/DB/LLVMProjectIRDB.cpp +++ b/lib/PhasarLLVM/DB/LLVMProjectIRDB.cpp @@ -5,7 +5,6 @@ #include "phasar/Utils/Logger.h" #include "phasar/Utils/Macros.h" -#include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringRef.h" #include "llvm/IR/AssemblyAnnotationWriter.h" #include "llvm/IR/GlobalVariable.h" @@ -14,7 +13,6 @@ #include "llvm/IR/Verifier.h" #include "llvm/IRReader/IRReader.h" #include "llvm/Support/Debug.h" -#include "llvm/Support/Errc.h" #include "llvm/Support/FormattedStream.h" #include "llvm/Support/MemoryBufferRef.h" #include "llvm/Support/SourceMgr.h" @@ -66,7 +64,6 @@ class IRDBParsingErrorCategory : public std::error_category { PSR_CONSTINIT IRDBParsingErrorCategory IRDBParsingErrorCat{}; std::error_code make_error_code(IRDBParsingError Err) noexcept { - // TODO return {int(Err), IRDBParsingErrorCat}; } } // namespace @@ -79,45 +76,64 @@ template <> struct is_error_code_enum : true_type {}; namespace psr { -std::unique_ptr -LLVMProjectIRDB::getParsedIRModuleOrNull(llvm::MemoryBufferRef IRFileContent, - llvm::LLVMContext &Ctx) noexcept { - +llvm::ErrorOr> +LLVMProjectIRDB::getParsedIRModuleOrErr(llvm::MemoryBufferRef IRFileContent, + llvm::LLVMContext &Ctx) noexcept { llvm::SMDiagnostic Diag; std::unique_ptr M = llvm::parseIR(IRFileContent, Diag, Ctx); bool BrokenDebugInfo = false; if (M == nullptr) { Diag.print(nullptr, llvm::errs()); - return nullptr; + return IRDBParsingError::CouldNotParse; } - /* Crash in presence of llvm-3.9.1 module (segfault) */ - if (M == nullptr || llvm::verifyModule(*M, &llvm::errs(), &BrokenDebugInfo)) { + + if (llvm::verifyModule(*M, &llvm::errs(), &BrokenDebugInfo)) { PHASAR_LOG_LEVEL(ERROR, IRFileContent.getBufferIdentifier() << " could not be parsed correctly!"); - return nullptr; + return IRDBParsingError::CouldNotVerify; } if (BrokenDebugInfo) { PHASAR_LOG_LEVEL(WARNING, "Debug info is broken!"); } + return M; } -std::unique_ptr -LLVMProjectIRDB::getParsedIRModuleOrNull(const llvm::Twine &IRFileName, - llvm::LLVMContext &Ctx) noexcept { +llvm::ErrorOr> +LLVMProjectIRDB::getParsedIRModuleOrErr(const llvm::Twine &IRFileName, + llvm::LLVMContext &Ctx) noexcept { // Look at LLVM's IRReader.cpp for reference auto FileOrErr = llvm::MemoryBuffer::getFileOrSTDIN(IRFileName, /*IsText=*/true); if (std::error_code EC = FileOrErr.getError()) { - llvm::SmallString<128> Buf; - auto Err = llvm::SMDiagnostic(IRFileName.toStringRef(Buf), - llvm::SourceMgr::DK_Error, - "Could not open input file: " + EC.message()); - Err.print(nullptr, llvm::errs()); - return nullptr; + return FileOrErr.getError(); + } + + return getParsedIRModuleOrErr(*FileOrErr.get(), Ctx); +} + +std::unique_ptr +LLVMProjectIRDB::getParsedIRModuleOrNull(llvm::MemoryBufferRef IRFileContent, + llvm::LLVMContext &Ctx) noexcept { + + auto Mod = getParsedIRModuleOrErr(IRFileContent, Ctx); + if (Mod) { + return std::move(*Mod); } - return getParsedIRModuleOrNull(*FileOrErr.get(), Ctx); + + return nullptr; +} + +std::unique_ptr +LLVMProjectIRDB::getParsedIRModuleOrNull(const llvm::Twine &IRFileName, + llvm::LLVMContext &Ctx) noexcept { + auto Mod = getParsedIRModuleOrErr(IRFileName, Ctx); + if (Mod) { + return std::move(*Mod); + } + + return nullptr; } llvm::ErrorOr @@ -131,24 +147,12 @@ LLVMProjectIRDB::load(const llvm::Twine &IRFileName, auto Ctx = std::make_unique(); - llvm::SMDiagnostic Diag; - std::unique_ptr M = llvm::parseIR(**FileOrErr, Diag, *Ctx); - bool BrokenDebugInfo = false; - if (M == nullptr) { - Diag.print(nullptr, llvm::errs()); - return IRDBParsingError::CouldNotParse; - } - - if (llvm::verifyModule(*M, &llvm::errs(), &BrokenDebugInfo)) { - PHASAR_LOG_LEVEL(ERROR, FileOrErr.get()->getBufferIdentifier() - << " could not be parsed correctly!"); - return IRDBParsingError::CouldNotVerify; - } - if (BrokenDebugInfo) { - PHASAR_LOG_LEVEL(WARNING, "Debug info is broken!"); + auto M = getParsedIRModuleOrErr(**FileOrErr, *Ctx); + if (!M) { + return M.getError(); } - return LLVMProjectIRDB(std::move(M), std::move(Ctx), EnableOpaquePointers); + return LLVMProjectIRDB(std::move(*M), std::move(Ctx), EnableOpaquePointers); } LLVMProjectIRDB::LLVMProjectIRDB(const llvm::Twine &IRFileName,