From d2c7bcbe985825278f982ecdcb2eb9e675ecf610 Mon Sep 17 00:00:00 2001 From: mxHuber Date: Wed, 15 May 2024 20:25:10 +0200 Subject: [PATCH 01/66] 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 2bed11717b..45cb80d40b 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 345d885700..5c8b6db624 --- 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 7cf3ceb94c..107deac114 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 2ce5cd45fe..1c20a9196f 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 0000000000..fe0b2d1775 --- /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/66] 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 92e964e142..b52a11d9ea 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 ba92829e59..3e255c2fcc 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 c5b744e125..39d16892df 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 eadc987db1..92f1ab1add 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 eeb0b2393a..1a948cbaca 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 bc2e32534c..e9b768e6ed 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/66] 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 46c752d3e2..66c6777d61 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 3cfd888ca3..f539e1a570 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 1b23477eea..ed1ad0612d 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 13c75d8f34..d328341949 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 5b67a4c929..85aa0ca31d 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 73adbd37e8..b453b1b626 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 92f1ab1add..d3cfecee0c 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/66] 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 39d16892df..0e1f3b0318 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 d3cfecee0c..7ca738f679 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 e9b768e6ed..39cd86ed87 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 9b1b58ebe1..9a4557b178 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/66] 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 7ca738f679..1380da51e0 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/66] 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 107deac114..bd05dcb49c 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 07b5127b31..833ee453f9 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 0812fafcf0..69ea7f0d2d 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/66] 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 d65e8ea9cf..c6efc8783c 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 bc2e32534c..f18476fb91 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 76c2f7c824..921b59c989 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 833ee453f9..bfb1522268 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 18f503fc3d..7eb5463a77 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 806cb58e2c..f6755e304b 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 17a74b610d..c0f91e102e 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/66] 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 bfb1522268..b97f2429a7 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 bc722d66e6..c7af226d56 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/66] 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 f18476fb91..5a2cf23875 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 921b59c989..20d09dff28 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 3dd219fde1..a11555de66 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/66] 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 d0ca110ab1..fab4238489 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/66] 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 7ce08382f4..b4f0ddfcba 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/66] 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 3274ced1a8..e6e7bb58ed 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 f6755e304b..b6b9cb075f 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 77f858c30d..25cf404618 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 1da7459377..f0ee361b04 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 34a110d537..546c9d3049 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 2c19ff6755..e6678d43a2 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/66] 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 45cb80d40b..9317cbbade 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 5c8b6db624..0d829f265f 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 bd05dcb49c..b4544620ae 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 1c20a9196f..3a6d28dbb8 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 3392c6793c..d2acc3e977 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 d15fb9d8a5..49b9262c26 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 becd3c95ee..b58ec4d7b3 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 abbf3c2cc5..e97704c268 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 065d550ebe..e86dd792a8 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 ee1e9ee250..597706ae25 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 32c37bc11b..699fe9176b 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 4157bb564c..d8b3c99756 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 c3f5ed1ab1..808cea86fe 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 f493de1dc6..98a67b9a0a 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 2ddd53dcf0..1169ff97bd 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 75985f1a8e..6de7b81369 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 0a3b822de4..e89324b2c9 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 3c844bceee..c9346523ae 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 1859de3c6d..891d134a97 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 51861f1789..4bb15f8a06 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 926cc4bdba..7b5b18a481 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 dee6cb5821..f8e42f9abd 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 15189fbf0a..70421c290f 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 5bd50fa1fe..5fa16bd771 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 ce639ae558..1b1f9bb532 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 4246cccc97..70187ede5d 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/66] 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 fab4238489..5e0a4bfb75 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/66] 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 e93e96c4e5..1b0c2accc9 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 26c8f30d25..3753a403a2 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 7eb5463a77..d89cd99312 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 ba4df9fc76..954b7fcef3 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 5e0a4bfb75..02b9865a7e 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/66] 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 c6efc8783c..a8898c9e91 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/66] 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 4206070fc1..ba36102969 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 b34384bd22..46fd591c45 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/66] 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 1b0c2accc9..1cf20ffc8d 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 3753a403a2..26c8f30d25 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 02b9865a7e..c05d4745db 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 25cf404618..77f858c30d 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 69ea7f0d2d..0812fafcf0 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 f0ee361b04..533212bebc 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 c7af226d56..3c6a3199fc 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/66] 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 83e796b6bc..ebf8af5387 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/66] 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 79c2de56c1..5967f993c2 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/66] 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 1cf20ffc8d..1b0c2accc9 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 26c8f30d25..3753a403a2 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 c05d4745db..02b9865a7e 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 77f858c30d..25cf404618 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 0812fafcf0..69ea7f0d2d 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 533212bebc..f0ee361b04 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 3c6a3199fc..c7af226d56 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/66] 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 1b0c2accc9..e1e54fda46 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/66] 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 954b7fcef3..d745c5937b 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 b6b9cb075f..5c3395b6d2 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 25cf404618..b36430c3c6 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/66] 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 e8f997f17a..b143270f00 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 0000000000..0779c72994 --- /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 f8e56c1828..7c4a5abcf3 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 6b2c144a58..9ee78fe92e 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 eed1094223..5f44717b13 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 27ec5c5a1a..79c2bfcf25 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 745a4e8667..70cb731b51 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 0000000000..9c3dbd74d9 --- /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 d745c5937b..ba4df9fc76 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/66] 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 0779c72994..67565e1cb6 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 70cb731b51..3dfe811659 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 9c3dbd74d9..5b48b1990c 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 9b1b58ebe1..ca97cd932d 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 ba4df9fc76..ebe5345d48 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/66] 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 ca8506e112..66fcba08ac 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/66] 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 b143270f00..5cbf894b2a 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 0000000000..afd7e1ebc5 --- /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 67565e1cb6..0000000000 --- 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 3dfe811659..bff1fb881d 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 0000000000..36c94b77d4 --- /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 5b48b1990c..0000000000 --- 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 ca97cd932d..9a4557b178 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/66] 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 0000000000..baa7cb6bc8 --- /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 0000000000..8ff16763fc --- /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/66] 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 baa7cb6bc8..0000000000 --- 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 8ff16763fc..0000000000 --- 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/66] 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 7cd8e71821..dd363f5c82 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 4206070fc1..126251da85 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 299a600ea9..0b72ef94f1 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 7b4484f6e1..3e8e1ed958 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 6010443f0b..a17ceedc3f 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 5cbf894b2a..d2e311daa0 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 8674ff564d..a280365a53 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 13c5ac42f3..75e31f25ef 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 f8cb8029b9..2c6f06000b 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 dc7df6ea4b..34b1943503 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 9432e9c921..b36149fbe2 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 afd7e1ebc5..0000000000 --- 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 fd77d2ec52..32922b2c94 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 7c4a5abcf3..6ebd3af3da 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 b34384bd22..0c4f201434 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 9ee78fe92e..7428f9fd88 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 5f44717b13..adfc979347 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 79c2bfcf25..1cd9cad40c 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 bff1fb881d..03bff4eca2 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 5d14d7fa48..51b8a92604 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 815f9d8870..ce9b2f095f 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 fd01a07595..4d581373e4 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 01dd076031..d4b9372a96 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 d16a1fb78e..7d133b7619 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 36c94b77d4..0000000000 --- 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 d89cd99312..d8c05b849b 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 0977c8189b..6e95f9c1a0 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 249283fde0..aa9b79ded0 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 07f5b80b95..73e3aa9486 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 ebe5345d48..43de678814 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 7503bca449..c807f55125 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 0194d0eead..262073e920 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 b6144d68b7..74a242dec3 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/66] 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 126251da85..d27fe4b3af 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 e278cf786f..24f5a0f0d1 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 d2e311daa0..9992c81673 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 df91bce7d7..d1e1ffce70 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 211de3a916..7a78746ecf 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 010e2f517d..0bebfc4e68 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 e813e38d33..b08b91179c 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 11490fe208..3fd7fd5847 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 fce91ea9c2..e6e80094a9 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 34b1943503..9bb3178035 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 0c4f201434..afad9c05d9 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 adfc979347..002c1211f5 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 c1f783d54b..be2dbe9136 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 1cd9cad40c..12120ac621 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 03bff4eca2..a38bdff341 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 b2c2365b91..8f5630d236 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 04830d72ca..2d552d64cc 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 41aeb91a4a..ca659b551d 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 dc0a9782d5..8d59c06836 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 3d7aa3a8ac..ebbe5e586c 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 4d581373e4..493dc456f3 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 d4b9372a96..49fdc29a33 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 b062bdd4c9..832836639b 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 43de678814..7ebb50987d 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 1cd66805ee..f1ae8b0840 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 f0ee361b04..73bb6d1525 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 beb7620edb..01f1f4dbd3 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/66] 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 d27fe4b3af..9e0ee85925 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 afad9c05d9..0c4f5703b7 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 7ebb50987d..69c26705c6 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 f1ae8b0840..1608749eb9 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 262073e920..76261020e9 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/66] 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 9e0ee85925..ce5d26b547 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 3e8e1ed958..0c047c9500 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 9992c81673..45cd13c2fa 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 fd55a006ab..3ab40dc18a 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 0c4f5703b7..a96052a153 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 002c1211f5..b6731637a7 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 a38bdff341..c651ec1066 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 73e3aa9486..d3838d840f 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 1608749eb9..54ef8b0d77 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/66] 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 69c26705c6..6509fd0be8 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/66] 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 b6731637a7..7863c024a4 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/66] 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 dd363f5c82..e513ea0c87 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 0c047c9500..56d00a7073 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 45cd13c2fa..7442a49997 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 9bb3178035..aa260bab3f 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 6ebd3af3da..0afffd715a 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 a96052a153..c3ab17624e 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 c651ec1066..e807ef2fdb 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 493dc456f3..c0241ccd45 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/66] 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 a17ceedc3f..08953a53f8 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 12120ac621..0a77b05c5b 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/66] 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 56d00a7073..a93721c25e 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/66] 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 0afffd715a..6deae92cb6 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/66] 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 08953a53f8..4984406689 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 0a77b05c5b..58ad46ff5a 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/66] 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 e513ea0c87..ce87d2795a 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 ce5d26b547..1fdc8100bf 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 0b72ef94f1..e38d12db43 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 4984406689..c891f0d57c 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 7442a49997..158385c3e1 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 3fd7fd5847..755bbc9230 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 3ab40dc18a..0386f83e79 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 c3ab17624e..43c6dab56d 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 7428f9fd88..89ebe3bc69 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 58ad46ff5a..05342b05ac 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 e807ef2fdb..687d0b86e2 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 c0241ccd45..b3c60c3108 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 8080dabbe1..8fe62e8d2b 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 d8c05b849b..4244a7c385 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 d3838d840f..f4c080c307 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 6509fd0be8..bb6c8da5dc 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 c0f91e102e..b3381ff3dc 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 02b9865a7e..a1368dc258 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 fe0b2d1775..0000000000 --- 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/66] 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 a8a9b4d12b..7f9c9d6078 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 687d0b86e2..dda9fec28c 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 8fe62e8d2b..8080dabbe1 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 6781e8e4ba..301e9c7041 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 f4c080c307..f66e024303 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/66] Add breaking changes --- BreakingChanges.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/BreakingChanges.md b/BreakingChanges.md index 597f54a976..2afe3d276e 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/66] 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 a8898c9e91..2952fc354f 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/66] 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 9432e9c921..36bd2d66e7 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 01dd076031..2f86236b2f 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/66] 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 36bd2d66e7..cdc71e4a09 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 2f86236b2f..fb02800bf2 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/66] 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 5d3dc71f6d..27d1ba767b 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 e669a26a9d..cbafa68c3a 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 e1195bb573..3a58bae1e4 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 e994671bbe..cf568e2837 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 be868e5605..6054b56917 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 039a212ed6..24d7b5f108 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 308245c825..0bf9b7ba0f 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 f98bd9eaa5..e36d7a0364 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 e904ef5310..03f6098b38 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 76915be0f9..cdd3b410e3 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 c45a8efd0c..9b55162717 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 203027cf2f..bfb0f0b02d 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 0000000000..5e072ad56b --- /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 50f8f215c2..00f4bb3c78 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 2c6d771c75..25bd6198ae 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 6be3445368..fc1f1c5334 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 1836e070fc..86b72a47d5 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 6ff07a20fd..0848925e45 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/66] 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 3e255c2fcc..c9ddc240cd 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/66] 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 2ce5cd45fe..e44a61e009 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 47df476adf..677b26639d 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 d4632d49f1..0d81ef828d 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/66] 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 9743e3ad86..7d792dd2ea 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 7cf3ceb94c..a2c47b8ee0 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 0d81ef828d..2bb171e1be 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/66] 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 2bc202e0a7..ca5c165521 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 6b2c144a58..fc2e22b5dc 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/66] 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 dda9fec28c..a18e621095 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 e1a2fefe1d..b0d4a4af75 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/66] 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 b0d4a4af75..528ec65eb3 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/66] 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 528ec65eb3..550e022bbf 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/66] 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 ac46b90687..f93ade8df3 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/66] 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 f93ade8df3..c05b24c0e0 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/66] 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 c05b24c0e0..d1b45f332b 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/66] 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 d1b45f332b..739b6fa301 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/66] 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 93faa54a75..598bb39b31 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 a18e621095..8e2fca0712 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/66] 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 05342b05ac..05ef7f040e 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/66] 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 05ef7f040e..b13c953379 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/66] 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 3a5f20d8f0..041f8c9339 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 b3c60c3108..f79c4d036f 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 7ecfa21a8c38ad89bffca2c1e25fdbe82396de32 Mon Sep 17 00:00:00 2001 From: mxHuber Date: Wed, 11 Dec 2024 12:42:41 +0100 Subject: [PATCH 63/66] Potential fix, needs testing --- .../ControlFlow/Resolver/Resolver.h | 12 +-- .../ControlFlow/Resolver/CHAResolver.cpp | 4 +- .../ControlFlow/Resolver/RTAResolver.cpp | 4 +- .../ControlFlow/Resolver/Resolver.cpp | 8 +- .../call_graphs/virtual_call_10.cpp | 22 +++++ ...MBasedICFG_RTA_MultipleInheritanceTest.cpp | 90 +++++++++++++++++++ 6 files changed, 126 insertions(+), 14 deletions(-) create mode 100644 test/llvm_test_code/call_graphs/virtual_call_10.cpp create mode 100644 unittests/PhasarLLVM/ControlFlow/LLVMBasedICFG_RTA_MultipleInheritanceTest.cpp diff --git a/include/phasar/PhasarLLVM/ControlFlow/Resolver/Resolver.h b/include/phasar/PhasarLLVM/ControlFlow/Resolver/Resolver.h index 5b74ba3b3b..fd11a2fb94 100644 --- a/include/phasar/PhasarLLVM/ControlFlow/Resolver/Resolver.h +++ b/include/phasar/PhasarLLVM/ControlFlow/Resolver/Resolver.h @@ -52,10 +52,9 @@ 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]] const llvm::Function *getNonPureVirtualVFTEntry( + const llvm::DIType *T, unsigned Idx, const llvm::CallBase *CallSite, + const psr::LLVMVFTableProvider &VTP, const llvm::DIType *ReceiverType); [[nodiscard]] std::string getReceiverTypeName(const llvm::CallBase *CallSite); @@ -75,11 +74,12 @@ class Resolver { const llvm::Function * getNonPureVirtualVFTEntry(const llvm::DIType *T, unsigned Idx, - const llvm::CallBase *CallSite) { + const llvm::CallBase *CallSite, + const llvm::DIType *ReceiverType) { if (!VTP) { return nullptr; } - return psr::getNonPureVirtualVFTEntry(T, Idx, CallSite, *VTP); + return psr::getNonPureVirtualVFTEntry(T, Idx, CallSite, *VTP, ReceiverType); } public: diff --git a/lib/PhasarLLVM/ControlFlow/Resolver/CHAResolver.cpp b/lib/PhasarLLVM/ControlFlow/Resolver/CHAResolver.cpp index ba464cd0a6..97ff4ad797 100644 --- a/lib/PhasarLLVM/ControlFlow/Resolver/CHAResolver.cpp +++ b/lib/PhasarLLVM/ControlFlow/Resolver/CHAResolver.cpp @@ -74,8 +74,8 @@ auto CHAResolver::resolveVirtualCall(const llvm::CallBase *CallSite) FunctionSetTy PossibleCallees; for (const auto &FallbackTy : FallbackTys) { - const auto *Target = - getNonPureVirtualVFTEntry(FallbackTy, VtableIndex, CallSite); + const auto *Target = getNonPureVirtualVFTEntry(FallbackTy, VtableIndex, + CallSite, ReceiverTy); if (Target) { PossibleCallees.insert(Target); } diff --git a/lib/PhasarLLVM/ControlFlow/Resolver/RTAResolver.cpp b/lib/PhasarLLVM/ControlFlow/Resolver/RTAResolver.cpp index b13c953379..595d4450de 100644 --- a/lib/PhasarLLVM/ControlFlow/Resolver/RTAResolver.cpp +++ b/lib/PhasarLLVM/ControlFlow/Resolver/RTAResolver.cpp @@ -71,8 +71,8 @@ auto RTAResolver::resolveVirtualCall(const llvm::CallBase *CallSite) auto EndIt = ReachableTypes.end(); for (const auto *PossibleType : AllocatedCompositeTypes) { if (ReachableTypes.find(PossibleType) != EndIt) { - const auto *Target = - getNonPureVirtualVFTEntry(PossibleType, VtableIndex, CallSite); + const auto *Target = getNonPureVirtualVFTEntry(PossibleType, VtableIndex, + CallSite, ReceiverType); if (Target) { PossibleCallTargets.insert(Target); } diff --git a/lib/PhasarLLVM/ControlFlow/Resolver/Resolver.cpp b/lib/PhasarLLVM/ControlFlow/Resolver/Resolver.cpp index 7254a17be5..20d264f795 100644 --- a/lib/PhasarLLVM/ControlFlow/Resolver/Resolver.cpp +++ b/lib/PhasarLLVM/ControlFlow/Resolver/Resolver.cpp @@ -92,15 +92,15 @@ 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) { +const llvm::Function *psr::getNonPureVirtualVFTEntry( + const llvm::DIType *T, unsigned Idx, const llvm::CallBase *CallSite, + const LLVMVFTableProvider &VTP, const llvm::DIType *ReceiverType) { if (const auto *VT = VTP.getVFTableOrNull(T)) { const auto *Target = VT->getFunction(Idx); if (Target && Target->getName() != DIBasedTypeHierarchy::PureVirtualCallName && + Target->getName() == ReceiverType->getName() && isConsistentCall(CallSite, Target)) { return Target; } diff --git a/test/llvm_test_code/call_graphs/virtual_call_10.cpp b/test/llvm_test_code/call_graphs/virtual_call_10.cpp new file mode 100644 index 0000000000..b0bdf36030 --- /dev/null +++ b/test/llvm_test_code/call_graphs/virtual_call_10.cpp @@ -0,0 +1,22 @@ +// handle virtual function call on a pointer to an interface implementation + +struct A { + virtual ~A() = default; + virtual void foo() = 0; +}; + +struct B { + virtual ~B() = default; + virtual void bar() = 0; +}; + +struct ABImpl : A, B { + void foo() override {} + void bar() override {} +}; + +int main() { + auto *ABptr = new ABImpl; + ABptr->foo(); + delete ABptr; +} diff --git a/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFG_RTA_MultipleInheritanceTest.cpp b/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFG_RTA_MultipleInheritanceTest.cpp new file mode 100644 index 0000000000..339433688c --- /dev/null +++ b/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFG_RTA_MultipleInheritanceTest.cpp @@ -0,0 +1,90 @@ +#include "phasar/Config/Configuration.h" +#include "phasar/ControlFlow/CallGraphAnalysisType.h" +#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/Utils/LLVMShorthands.h" + +#include "TestConfig.h" +#include "gtest/gtest.h" + +using namespace std; +using namespace psr; + +TEST(LLVMBasedICFG_RTATest, VirtualCallSite_10) { + // TODO: test if getNonPureVirtualVFTEntry gets the correct inheritance and + // not just the first one every time + + LLVMProjectIRDB IRDB(unittest::PathToLLTestFiles + + "call_graphs/virtual_call_10_cpp.ll"); + DIBasedTypeHierarchy TH(IRDB); + LLVMAliasSet PT(&IRDB); + LLVMBasedICFG ICFG(&IRDB, CallGraphAnalysisType::RTA, {"main"}, &TH, &PT); + const llvm::Function *F = IRDB.getFunctionDefinition("main"); + const llvm::Function *FooD = IRDB.getFunctionDefinition("_ZN1D3fooEv"); + ASSERT_TRUE(FooD); + ASSERT_TRUE(F); + + const llvm::Instruction *I = getNthInstruction(F, 11); + if (llvm::isa(I) || llvm::isa(I)) { + const auto &Callees = ICFG.getCalleesOfCallAt(I); + set CalleeNames; + for (const llvm::Function *F : Callees) { + CalleeNames.insert(F->getName().str()); + } + ASSERT_EQ(Callees.size(), 3U); + ASSERT_TRUE(CalleeNames.count("_ZN1B3fooEv")); + ASSERT_TRUE(CalleeNames.count("_ZN1D3fooEv")); + ASSERT_TRUE(CalleeNames.count("_ZN1C3fooEv")); + ASSERT_TRUE(llvm::is_contained(ICFG.getCallersOf(FooD), I)); + } +} + +// TODO: +#if false +TEST(LLVMBasedICFG_RTATest, VirtualCallSite_3) { + LLVMProjectIRDB IRDB(unittest::PathToLLTestFiles + + "call_graphs/virtual_call_3_cpp.ll"); + DIBasedTypeHierarchy TH(IRDB); + LLVMAliasSet PT(&IRDB); + LLVMBasedICFG ICFG(&IRDB, CallGraphAnalysisType::RTA, {"main"}, &TH, &PT); + const llvm::Function *F = IRDB.getFunctionDefinition("main"); + const llvm::Function *AptrFoo = IRDB.getFunctionDefinition("_ZN5AImpl3fooEv"); + ASSERT_TRUE(F); + ASSERT_TRUE(AptrFoo); + + const llvm::Instruction *I = getNthInstruction(F, 14); + if (llvm::isa(I) || llvm::isa(I)) { + ASSERT_TRUE(ICFG.isVirtualFunctionCall(I)); + const auto &Callees = ICFG.getCalleesOfCallAt(I); + ASSERT_EQ(Callees.size(), 1U); + ASSERT_TRUE(llvm::is_contained(Callees, AptrFoo)); + } +} + +TEST(LLVMBasedICFG_RTATest, StaticCallSite_13) { + LLVMProjectIRDB IRDB(unittest::PathToLLTestFiles + + "call_graphs/static_callsite_13_cpp.ll"); + DIBasedTypeHierarchy TH(IRDB); + LLVMAliasSet PT(&IRDB); + LLVMBasedICFG ICFG(&IRDB, CallGraphAnalysisType::RTA, {"main"}, &TH, &PT); + const llvm::Function *F = IRDB.getFunctionDefinition("main"); + const llvm::Function *Vfunc = IRDB.getFunctionDefinition("_Z5VfuncP1A"); + const llvm::Function *VfuncA = IRDB.getFunctionDefinition("_ZN1A5VfuncEv"); + ASSERT_TRUE(F); + ASSERT_TRUE(Vfunc); + ASSERT_TRUE(VfuncA); + + const llvm::Instruction *I = getNthInstruction(F, 15); + if (llvm::isa(I) || llvm::isa(I)) { + const auto &Callees = ICFG.getCalleesOfCallAt(I); + ASSERT_EQ(Callees.size(), 1U); + } +} +#endif + +int main(int Argc, char **Argv) { + ::testing::InitGoogleTest(&Argc, Argv); + return RUN_ALL_TESTS(); +} From 9e2d4ea77a8b19e32a4ea8a13fd6073dd4ef6d9c Mon Sep 17 00:00:00 2001 From: Fabian Schiebel Date: Sat, 7 Jun 2025 16:12:17 +0200 Subject: [PATCH 64/66] Look into the right VTable, when resolving a virtual call --- .../ControlFlow/LLVMVFTableProvider.h | 20 ++- .../ControlFlow/Resolver/CHAResolver.h | 5 +- .../ControlFlow/Resolver/NOResolver.h | 6 +- .../ControlFlow/Resolver/OTFResolver.h | 8 +- .../ControlFlow/Resolver/RTAResolver.h | 5 +- .../ControlFlow/Resolver/Resolver.h | 21 ++- .../PhasarLLVM/TypeHierarchy/LLVMVFTable.h | 2 +- include/phasar/Utils/DefaultValue.h | 20 +++ include/phasar/Utils/HashUtils.h | 27 ++++ include/phasar/Utils/MapUtils.h | 69 ++++++++ .../ControlFlow/LLVMVFTableProvider.cpp | 93 ++++++++--- .../ControlFlow/Resolver/CHAResolver.cpp | 11 +- .../ControlFlow/Resolver/NOResolver.cpp | 14 +- .../ControlFlow/Resolver/OTFResolver.cpp | 27 ++-- .../ControlFlow/Resolver/RTAResolver.cpp | 19 +-- .../ControlFlow/Resolver/Resolver.cpp | 46 ++++-- lib/PhasarLLVM/TypeHierarchy/LLVMVFTable.cpp | 30 ++-- .../llvm_test_code/call_graphs/CMakeLists.txt | 2 + .../call_graphs/virtual_call_10.cpp | 4 +- .../call_graphs/virtual_call_11.cpp | 45 ++++++ .../PhasarLLVM/ControlFlow/CMakeLists.txt | 1 + ...MBasedICFG_RTA_MultipleInheritanceTest.cpp | 152 +++++++++++------- 22 files changed, 446 insertions(+), 181 deletions(-) create mode 100644 include/phasar/Utils/HashUtils.h create mode 100644 include/phasar/Utils/MapUtils.h create mode 100644 test/llvm_test_code/call_graphs/virtual_call_11.cpp diff --git a/include/phasar/PhasarLLVM/ControlFlow/LLVMVFTableProvider.h b/include/phasar/PhasarLLVM/ControlFlow/LLVMVFTableProvider.h index ffaa42caef..a9b6f964c0 100644 --- a/include/phasar/PhasarLLVM/ControlFlow/LLVMVFTableProvider.h +++ b/include/phasar/PhasarLLVM/ControlFlow/LLVMVFTableProvider.h @@ -11,9 +11,13 @@ #define PHASAR_PHASARLLVM_CONTROLFLOW_LLVMVFTABLEPROVIDER_H #include "phasar/PhasarLLVM/TypeHierarchy/LLVMVFTable.h" +#include "phasar/Utils/HashUtils.h" +#include "llvm/ADT/DenseSet.h" #include "llvm/ADT/StringMap.h" +#include "llvm/IR/DebugInfoMetadata.h" +#include #include namespace llvm { @@ -37,8 +41,8 @@ class LLVMVFTableProvider { explicit LLVMVFTableProvider(const LLVMProjectIRDB &IRDB); [[nodiscard]] bool hasVFTable(const llvm::DIType *Type) const; - [[nodiscard]] const LLVMVFTable * - getVFTableOrNull(const llvm::DIType *Type) const; + [[nodiscard]] const LLVMVFTable *getVFTableOrNull(const llvm::DIType *Type, + uint32_t Index = 0) const; [[nodiscard]] const llvm::GlobalVariable * getVFTableGlobal(const llvm::DIType *Type) const; @@ -46,9 +50,19 @@ class LLVMVFTableProvider { [[nodiscard]] const llvm::GlobalVariable * getVFTableGlobal(llvm::StringRef ClearTypeName) const; + [[nodiscard]] const llvm::SmallDenseSet & + getVTableIndexInHierarchy(const llvm::DIType *DerivedType, + const llvm::DIType *BaseType) const; + private: llvm::StringMap ClearNameTVMap; - std::unordered_map TypeVFTMap; + std::unordered_map, LLVMVFTable, + PairHash> + TypeVFTMap; + std::unordered_map< + const llvm::DIType *, + llvm::SmallDenseMap>> + BasesOfVirt; }; } // namespace psr diff --git a/include/phasar/PhasarLLVM/ControlFlow/Resolver/CHAResolver.h b/include/phasar/PhasarLLVM/ControlFlow/Resolver/CHAResolver.h index 406f32c289..8186bdba16 100644 --- a/include/phasar/PhasarLLVM/ControlFlow/Resolver/CHAResolver.h +++ b/include/phasar/PhasarLLVM/ControlFlow/Resolver/CHAResolver.h @@ -38,9 +38,8 @@ class CHAResolver : public Resolver { // dtor in CHAResolver.cpp ~CHAResolver() override; - FunctionSetTy resolveVirtualCall(const llvm::CallBase *CallSite) override; - - [[nodiscard]] bool isIndependent() const noexcept override { return true; } + void resolveVirtualCall(FunctionSetTy &PossibleTargets, + const llvm::CallBase *CallSite) override; [[nodiscard]] std::string str() const override; diff --git a/include/phasar/PhasarLLVM/ControlFlow/Resolver/NOResolver.h b/include/phasar/PhasarLLVM/ControlFlow/Resolver/NOResolver.h index 88afa796e5..044815e287 100644 --- a/include/phasar/PhasarLLVM/ControlFlow/Resolver/NOResolver.h +++ b/include/phasar/PhasarLLVM/ControlFlow/Resolver/NOResolver.h @@ -25,9 +25,11 @@ class NOResolver final : public Resolver { ~NOResolver() override = default; - FunctionSetTy resolveVirtualCall(const llvm::CallBase *CallSite) override; + void resolveVirtualCall(FunctionSetTy &PossibleTargets, + const llvm::CallBase *CallSite) override; - FunctionSetTy resolveFunctionPointer(const llvm::CallBase *CallSite) override; + void resolveFunctionPointer(FunctionSetTy &PossibleTargets, + const llvm::CallBase *CallSite) 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 d92494cc59..41b3f6e878 100644 --- a/include/phasar/PhasarLLVM/ControlFlow/Resolver/OTFResolver.h +++ b/include/phasar/PhasarLLVM/ControlFlow/Resolver/OTFResolver.h @@ -48,9 +48,11 @@ class OTFResolver : public Resolver { void handlePossibleTargets(const llvm::CallBase *CallSite, FunctionSetTy &CalleeTargets) override; - FunctionSetTy resolveVirtualCall(const llvm::CallBase *CallSite) override; + void resolveVirtualCall(FunctionSetTy &PossibleTargets, + const llvm::CallBase *CallSite) override; - FunctionSetTy resolveFunctionPointer(const llvm::CallBase *CallSite) override; + void resolveFunctionPointer(FunctionSetTy &PossibleTargets, + const llvm::CallBase *CallSite) override; static std::set getReachableTypes(const LLVMAliasInfo::AliasSetTy &Values); @@ -59,8 +61,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 81a9eae0a4..6e89063a9d 100644 --- a/include/phasar/PhasarLLVM/ControlFlow/Resolver/RTAResolver.h +++ b/include/phasar/PhasarLLVM/ControlFlow/Resolver/RTAResolver.h @@ -38,9 +38,8 @@ class RTAResolver : public CHAResolver { ~RTAResolver() override = default; - FunctionSetTy resolveVirtualCall(const llvm::CallBase *CallSite) override; - - [[nodiscard]] bool isIndependent() const noexcept override { return true; } + void resolveVirtualCall(FunctionSetTy &PossibleTargets, + const llvm::CallBase *CallSite) override; [[nodiscard]] std::string str() const override; diff --git a/include/phasar/PhasarLLVM/ControlFlow/Resolver/Resolver.h b/include/phasar/PhasarLLVM/ControlFlow/Resolver/Resolver.h index 35ed728965..09b8147424 100644 --- a/include/phasar/PhasarLLVM/ControlFlow/Resolver/Resolver.h +++ b/include/phasar/PhasarLLVM/ControlFlow/Resolver/Resolver.h @@ -103,22 +103,14 @@ class Resolver { [[nodiscard]] FunctionSetTy resolveIndirectCall(const llvm::CallBase *CallSite); - [[nodiscard]] virtual FunctionSetTy - resolveVirtualCall(const llvm::CallBase *CallSite) = 0; - - [[nodiscard]] virtual FunctionSetTy - resolveFunctionPointer(const llvm::CallBase *CallSite); - 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; @@ -128,6 +120,13 @@ class Resolver { const LLVMVFTableProvider *VTP, const DIBasedTypeHierarchy *TH, LLVMAliasInfoRef PT = nullptr); + +protected: + virtual void resolveVirtualCall(FunctionSetTy &PossibleTargets, + const llvm::CallBase *CallSite) = 0; + + virtual void resolveFunctionPointer(FunctionSetTy &PossibleTargets, + const llvm::CallBase *CallSite); }; } // namespace psr diff --git a/include/phasar/PhasarLLVM/TypeHierarchy/LLVMVFTable.h b/include/phasar/PhasarLLVM/TypeHierarchy/LLVMVFTable.h index a68c1b341a..5b55901e82 100644 --- a/include/phasar/PhasarLLVM/TypeHierarchy/LLVMVFTable.h +++ b/include/phasar/PhasarLLVM/TypeHierarchy/LLVMVFTable.h @@ -92,7 +92,7 @@ class LLVMVFTable : public VFTable { }; [[nodiscard]] static std::vector - getVFVectorFromIRVTable(const llvm::ConstantStruct &); + getVFVectorFromIRVTable(const llvm::ConstantStruct &VT, uint32_t Index = 0); }; } // namespace psr diff --git a/include/phasar/Utils/DefaultValue.h b/include/phasar/Utils/DefaultValue.h index 3dde71aeb3..e63b10018a 100644 --- a/include/phasar/Utils/DefaultValue.h +++ b/include/phasar/Utils/DefaultValue.h @@ -40,6 +40,26 @@ getDefaultValue() noexcept(std::is_nothrow_default_constructible_v) { } } +namespace detail { +struct DefaultCast { + template >> + operator To() && { + return psr::getDefaultValue(); + } + + template >> + operator const To &() && { + return psr::getDefaultValue(); + } +}; +} // namespace detail + +/// Provides a value that automatically converts to (a const-ref to) the +/// default-constructed object of the expected receiver type. +static constexpr detail::DefaultCast default_value() noexcept { return {}; } + } // namespace psr #endif // PHASAR_UTILS_DEFAULTVALUE_H diff --git a/include/phasar/Utils/HashUtils.h b/include/phasar/Utils/HashUtils.h new file mode 100644 index 0000000000..3815d29ff7 --- /dev/null +++ b/include/phasar/Utils/HashUtils.h @@ -0,0 +1,27 @@ +/****************************************************************************** + * Copyright (c) 2025 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_HASHUTILS_H +#define PHASAR_UTILS_HASHUTILS_H + +#include "llvm/ADT/DenseMapInfo.h" + +#include +#include + +namespace psr { +struct PairHash { + template + size_t operator()(const std::pair &Pair) const noexcept { + return llvm::DenseMapInfo>::getHashValue(Pair); + } +}; +} // namespace psr + +#endif // PHASAR_UTILS_HASHUTILS_H diff --git a/include/phasar/Utils/MapUtils.h b/include/phasar/Utils/MapUtils.h new file mode 100644 index 0000000000..c087aaa0ee --- /dev/null +++ b/include/phasar/Utils/MapUtils.h @@ -0,0 +1,69 @@ +/****************************************************************************** + * Copyright (c) 2025 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_MAPUTILS_H +#define PHASAR_UTILS_MAPUTILS_H + +#include "phasar/Utils/ByRef.h" +#include "phasar/Utils/DefaultValue.h" +#include "phasar/Utils/Macros.h" + +#include "llvm/ADT/STLForwardCompat.h" + +#include +#include + +namespace psr { + +template >> +static auto getOrDefault(MapT &&Map, KeyT &&Key) -> ByConstRef< + llvm::remove_cvref_tsecond)>> { + auto It = Map.find(PSR_FWD(Key)); + if (It == Map.end()) { + return default_value(); + } + + return It->second; +} + +template < + typename MapT, typename KeyT, + typename = std::enable_if_t>, + std::enable_if_t< + !psr::CanEfficientlyPassByValue>, int> = 0> +static auto getOrNull(MapT &&Map, KeyT &&Key) + -> decltype(&Map.find(PSR_FWD(Key))->second) { + auto It = Map.find(PSR_FWD(Key)); + decltype(&It->second) Ret = nullptr; + if (It != Map.end()) { + Ret = &It->second; + } + + return Ret; +} + +template < + typename MapT, typename KeyT, + typename = std::enable_if_t>, + std::enable_if_t>, + int> = 0> +static auto getOrNull(MapT &&Map, KeyT Key) + -> decltype(&Map.find(Key)->second) { + auto It = Map.find(Key); + decltype(&It->second) Ret = nullptr; + if (It != Map.end()) { + Ret = &It->second; + } + + return Ret; +} +} // namespace psr + +#endif // PHASAR_UTILS_MAPUTILS_H diff --git a/lib/PhasarLLVM/ControlFlow/LLVMVFTableProvider.cpp b/lib/PhasarLLVM/ControlFlow/LLVMVFTableProvider.cpp index aeab698497..95d097f16d 100644 --- a/lib/PhasarLLVM/ControlFlow/LLVMVFTableProvider.cpp +++ b/lib/PhasarLLVM/ControlFlow/LLVMVFTableProvider.cpp @@ -5,7 +5,9 @@ #include "phasar/PhasarLLVM/TypeHierarchy/LLVMVFTable.h" #include "phasar/PhasarLLVM/Utils/LLVMIRToSrc.h" #include "phasar/Utils/Logger.h" +#include "phasar/Utils/MapUtils.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" #include "llvm/BinaryFormat/Dwarf.h" #include "llvm/Demangle/Demangle.h" @@ -35,25 +37,50 @@ static std::string getTypeName(const llvm::DIType *DITy) { return Ret; } -static std::vector getVirtualFunctions( - const llvm::StringMap &ClearNameTVMap, - const llvm::DIType *Type) { - auto ClearName = getTypeName(Type); +static void insertVirtualFunctions( + std::unordered_map, LLVMVFTable, + PairHash> &Into, + const llvm::DIType *Type, const llvm::GlobalVariable *VTableGlobal) { + if (!VTableGlobal) { + return; + } + + if (const auto *VT = llvm::dyn_cast( + VTableGlobal->getInitializer())) { + auto NumElems = VT->getNumOperands(); - auto It = ClearNameTVMap.find(ClearName); + // llvm::errs() << "[insertVirtualFunctions]: VT: " << *VT << '\n'; + // llvm::errs() << "[insertVirtualFunctions]: > NumElems: " << NumElems + // << '\n'; + for (uint32_t I = 0; I != NumElems; ++I) { + Into[{Type, I}] = LLVMVFTable::getVFVectorFromIRVTable(*VT, I); + } + } +} - if (It != ClearNameTVMap.end()) { - if (!It->second->hasInitializer()) { - PHASAR_LOG_LEVEL_CAT(DEBUG, "DIBasedTypeHierarchy", - ClearName << " does not have initializer"); - return {}; +static void getBasesOfVirt( + llvm::SmallDenseMap> + &Into, + const llvm::DICompositeType *VirtTy, uint32_t CurrIdx = 0) { + Into[VirtTy].insert(CurrIdx); + for (const auto *Elem : VirtTy->getElements()) { + const auto *Inher = llvm::dyn_cast(Elem); + if (!Inher) { + // Inheritance is always at the front of the member-list + break; + } + if (Inher->getTag() != llvm::dwarf::DW_TAG_inheritance) { + continue; } - if (const auto *I = llvm::dyn_cast( - It->second->getInitializer())) { - return LLVMVFTable::getVFVectorFromIRVTable(*I); + + const auto *BaseClass = + llvm::dyn_cast(Inher->getBaseType()); + if (!BaseClass || !BaseClass->getVTableHolder()) { + continue; } + getBasesOfVirt(Into, BaseClass, CurrIdx); + CurrIdx++; } - return {}; } LLVMVFTableProvider::LLVMVFTableProvider(const llvm::Module &Mod) { @@ -72,8 +99,14 @@ LLVMVFTableProvider::LLVMVFTableProvider(const llvm::Module &Mod) { 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)); + insertVirtualFunctions( + TypeVFTMap, CompTy, + getOrDefault(ClearNameTVMap, getTypeName(CompTy))); + + if (CompTy->getVTableHolder()) { + auto &BaseTys = BasesOfVirt[CompTy]; + getBasesOfVirt(BaseTys, CompTy); + } } } } @@ -83,12 +116,13 @@ LLVMVFTableProvider::LLVMVFTableProvider(const LLVMProjectIRDB &IRDB) : LLVMVFTableProvider(*IRDB.getModule()) {} bool LLVMVFTableProvider::hasVFTable(const llvm::DIType *Type) const { - return TypeVFTMap.count(Type); + return TypeVFTMap.count({Type, 0}); } const LLVMVFTable * -LLVMVFTableProvider::getVFTableOrNull(const llvm::DIType *Type) const { - auto It = TypeVFTMap.find(Type); +LLVMVFTableProvider::getVFTableOrNull(const llvm::DIType *Type, + uint32_t Index) const { + auto It = TypeVFTMap.find({Type, Index}); return It != TypeVFTMap.end() ? &It->second : nullptr; } @@ -107,3 +141,24 @@ LLVMVFTableProvider::getVFTableGlobal(llvm::StringRef ClearTypeName) const { } return nullptr; } + +static const auto &getDefaultIndices() { + static const llvm::SmallDenseSet DefaultIndices = {0}; + return DefaultIndices; +} + +const llvm::SmallDenseSet & +LLVMVFTableProvider::getVTableIndexInHierarchy( + const llvm::DIType *DerivedType, const llvm::DIType *BaseType) const { + auto OuterIt = BasesOfVirt.find(DerivedType); + if (OuterIt == BasesOfVirt.end()) { + return getDefaultIndices(); + } + + auto InnerIt = OuterIt->second.find(BaseType); + if (InnerIt == OuterIt->second.end()) { + return getDefaultIndices(); + } + + return InnerIt->second; +} diff --git a/lib/PhasarLLVM/ControlFlow/Resolver/CHAResolver.cpp b/lib/PhasarLLVM/ControlFlow/Resolver/CHAResolver.cpp index 97ff4ad797..25f5c0fd02 100644 --- a/lib/PhasarLLVM/ControlFlow/Resolver/CHAResolver.cpp +++ b/lib/PhasarLLVM/ControlFlow/Resolver/CHAResolver.cpp @@ -43,8 +43,8 @@ CHAResolver::CHAResolver(const LLVMProjectIRDB *IRDB, CHAResolver::~CHAResolver() = default; -auto CHAResolver::resolveVirtualCall(const llvm::CallBase *CallSite) - -> FunctionSetTy { +void CHAResolver::resolveVirtualCall(FunctionSetTy &PossibleTargets, + const llvm::CallBase *CallSite) { PHASAR_LOG_LEVEL(DEBUG, "Call virtual function: "); // Leading to SEGFAULT in Unittests. Error only when run in Debug mode // << llvmIRToString(CallSite)); @@ -59,7 +59,7 @@ auto CHAResolver::resolveVirtualCall(const llvm::CallBase *CallSite) // run in Debug mode // << llvmIRToString(CallSite) << "\n"); - return {}; + return; } auto VtableIndex = RetrievedVtableIndex.value(); @@ -71,16 +71,13 @@ auto CHAResolver::resolveVirtualCall(const llvm::CallBase *CallSite) // also insert all possible subtypes vtable entries auto FallbackTys = TH->getSubTypes(ReceiverTy); - FunctionSetTy PossibleCallees; - for (const auto &FallbackTy : FallbackTys) { const auto *Target = getNonPureVirtualVFTEntry(FallbackTy, VtableIndex, CallSite, ReceiverTy); if (Target) { - PossibleCallees.insert(Target); + PossibleTargets.insert(Target); } } - return PossibleCallees; } std::string CHAResolver::str() const { return "CHA"; } diff --git a/lib/PhasarLLVM/ControlFlow/Resolver/NOResolver.cpp b/lib/PhasarLLVM/ControlFlow/Resolver/NOResolver.cpp index f825f52549..9dc6a56c28 100644 --- a/lib/PhasarLLVM/ControlFlow/Resolver/NOResolver.cpp +++ b/lib/PhasarLLVM/ControlFlow/Resolver/NOResolver.cpp @@ -26,15 +26,11 @@ NOResolver::NOResolver(const LLVMProjectIRDB *IRDB, const LLVMVFTableProvider *VTP) : Resolver(IRDB, VTP) {} -auto NOResolver::resolveVirtualCall(const llvm::CallBase * /*CallSite*/) - -> FunctionSetTy { - return {}; -} - -auto NOResolver::resolveFunctionPointer(const llvm::CallBase * /*CallSite*/) - -> FunctionSetTy { - return {}; -} +void NOResolver::resolveVirtualCall(FunctionSetTy & /*PossibleTargets*/, + const llvm::CallBase * /*CallSite*/) {} + +void NOResolver::resolveFunctionPointer(FunctionSetTy & /*PossibleTargets*/, + const llvm::CallBase * /*CallSite*/) {} std::string NOResolver::str() const { return "NOResolver"; } diff --git a/lib/PhasarLLVM/ControlFlow/Resolver/OTFResolver.cpp b/lib/PhasarLLVM/ControlFlow/Resolver/OTFResolver.cpp index 6e70e7de01..9a206c9e21 100644 --- a/lib/PhasarLLVM/ControlFlow/Resolver/OTFResolver.cpp +++ b/lib/PhasarLLVM/ControlFlow/Resolver/OTFResolver.cpp @@ -65,9 +65,8 @@ void OTFResolver::handlePossibleTargets(const llvm::CallBase *CallSite, } } -auto OTFResolver::resolveVirtualCall(const llvm::CallBase *CallSite) - -> FunctionSetTy { - FunctionSetTy PossibleCallTargets; +void OTFResolver::resolveVirtualCall(FunctionSetTy &PossibleTargets, + const llvm::CallBase *CallSite) { PHASAR_LOG_LEVEL(DEBUG, "Call virtual function: " << llvmIRToString(CallSite)); @@ -79,7 +78,7 @@ auto OTFResolver::resolveVirtualCall(const llvm::CallBase *CallSite) "Error with resolveVirtualCall : impossible to retrieve " "the vtable index\n" << llvmIRToString(CallSite) << "\n"); - return {}; + return; } auto VtableIndex = RetrievedVtableIndex.value(); @@ -104,23 +103,19 @@ auto OTFResolver::resolveVirtualCall(const llvm::CallBase *CallSite) !isConsistentCall(CallSite, Callee)) { continue; } - PossibleCallTargets.insert(Callee); + PossibleTargets.insert(Callee); } } } } - - return PossibleCallTargets; } -auto OTFResolver::resolveFunctionPointer(const llvm::CallBase *CallSite) - -> FunctionSetTy { +void OTFResolver::resolveFunctionPointer(FunctionSetTy &PossibleTargets, + const llvm::CallBase *CallSite) { if (!CallSite->getCalledOperand()) { - return {}; + return; } - FunctionSetTy Callees; - auto PTS = PT.getAliasSet(CallSite->getCalledOperand(), CallSite); llvm::SmallVector GlobalVariableWL; @@ -138,7 +133,7 @@ auto OTFResolver::resolveFunctionPointer(const llvm::CallBase *CallSite) if (const auto *F = llvm::dyn_cast(P)) { if (isConsistentCall(CallSite, F)) { - Callees.insert(F); + PossibleTargets.insert(F); } } @@ -181,14 +176,14 @@ auto OTFResolver::resolveFunctionPointer(const llvm::CallBase *CallSite) if (const auto *F = llvm::dyn_cast(CE->getOperand(0)); F && isConsistentCall(CallSite, F)) { - Callees.insert(F); + PossibleTargets.insert(F); } } } if (const auto *F = llvm::dyn_cast(Op)) { if (isConsistentCall(CallSite, F)) { - Callees.insert(F); + PossibleTargets.insert(F); } } else if (auto *CA = llvm::dyn_cast(Op)) { ConstantAggregateWL.push_back(CA); @@ -204,8 +199,6 @@ auto OTFResolver::resolveFunctionPointer(const llvm::CallBase *CallSite) } } } - - return Callees; } std::set diff --git a/lib/PhasarLLVM/ControlFlow/Resolver/RTAResolver.cpp b/lib/PhasarLLVM/ControlFlow/Resolver/RTAResolver.cpp index 6044d83a5d..216118a1c8 100644 --- a/lib/PhasarLLVM/ControlFlow/Resolver/RTAResolver.cpp +++ b/lib/PhasarLLVM/ControlFlow/Resolver/RTAResolver.cpp @@ -29,8 +29,8 @@ #include "llvm/IR/InstrTypes.h" #include "llvm/IR/Instructions.h" #include "llvm/Support/Casting.h" +#include "llvm/Support/raw_ostream.h" -using namespace std; using namespace psr; RTAResolver::RTAResolver(const LLVMProjectIRDB *IRDB, @@ -40,10 +40,8 @@ RTAResolver::RTAResolver(const LLVMProjectIRDB *IRDB, resolveAllocatedCompositeTypes(); } -auto RTAResolver::resolveVirtualCall(const llvm::CallBase *CallSite) - -> FunctionSetTy { - - FunctionSetTy PossibleCallTargets; +void RTAResolver::resolveVirtualCall(FunctionSetTy &PossibleTargets, + const llvm::CallBase *CallSite) { PHASAR_LOG_LEVEL(DEBUG, "Call virtual function: " << llvmIRToString(CallSite)); @@ -55,7 +53,7 @@ auto RTAResolver::resolveVirtualCall(const llvm::CallBase *CallSite) "Error with resolveVirtualCall : impossible to retrieve " "the vtable index\n" << llvmIRToString(CallSite) << "\n"); - return {}; + return; } auto VtableIndex = RetrievedVtableIndex.value(); @@ -71,19 +69,18 @@ auto RTAResolver::resolveVirtualCall(const llvm::CallBase *CallSite) auto EndIt = ReachableTypes.end(); for (const auto *PossibleType : AllocatedCompositeTypes) { if (ReachableTypes.find(PossibleType) != EndIt) { + const auto *Target = getNonPureVirtualVFTEntry(PossibleType, VtableIndex, CallSite, ReceiverType); if (Target) { - PossibleCallTargets.insert(Target); + PossibleTargets.insert(Target); } } } - if (PossibleCallTargets.empty()) { - return CHAResolver::resolveVirtualCall(CallSite); + if (PossibleTargets.empty()) { + CHAResolver::resolveVirtualCall(PossibleTargets, CallSite); } - - return PossibleCallTargets; } std::string RTAResolver::str() const { return "RTA"; } diff --git a/lib/PhasarLLVM/ControlFlow/Resolver/Resolver.cpp b/lib/PhasarLLVM/ControlFlow/Resolver/Resolver.cpp index 6c9087cf96..fb9eaa55dd 100644 --- a/lib/PhasarLLVM/ControlFlow/Resolver/Resolver.cpp +++ b/lib/PhasarLLVM/ControlFlow/Resolver/Resolver.cpp @@ -61,6 +61,15 @@ std::optional psr::getVFTIndex(const llvm::CallBase *CallSite) { return std::nullopt; } +static const llvm::DIType *stripPointerTypes(const llvm::DIType *DITy) { + while (const auto *DerivedTy = + llvm::dyn_cast_if_present(DITy)) { + // get rid of the pointer + DITy = DerivedTy->getBaseType(); + } + return DITy; +} + const llvm::DIType *psr::getReceiverType(const llvm::CallBase *CallSite) { if (CallSite->arg_empty() || (CallSite->hasStructRetAttr() && CallSite->arg_size() < 2)) { @@ -75,12 +84,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)) { - // get rid of the pointer - DITy = DerivedTy->getBaseType(); - } - return DITy; + return stripPointerTypes(DITy); + } + + if (const auto *Var = + getDILocalVariable(Receiver->stripPointerCastsAndAliases())) { + return stripPointerTypes(Var->getType()); } return nullptr; @@ -89,12 +98,12 @@ const llvm::DIType *psr::getReceiverType(const llvm::CallBase *CallSite) { const llvm::Function *psr::getNonPureVirtualVFTEntry( const llvm::DIType *T, unsigned Idx, const llvm::CallBase *CallSite, const LLVMVFTableProvider &VTP, const llvm::DIType *ReceiverType) { + auto VTIndex = *VTP.getVTableIndexInHierarchy(T, ReceiverType).begin(); - if (const auto *VT = VTP.getVFTableOrNull(T)) { + if (const auto *VT = VTP.getVFTableOrNull(T, VTIndex)) { const auto *Target = VT->getFunction(Idx); if (Target && Target->getName() != DIBasedTypeHierarchy::PureVirtualCallName && - Target->getName() == ReceiverType->getName() && isConsistentCall(CallSite, Target)) { return Target; } @@ -135,6 +144,8 @@ bool psr::isVirtualCall(const llvm::Instruction *Inst, // check potential receiver type const auto *RecType = getReceiverType(CallSite); if (!RecType) { + llvm::errs() << "No receiver type found for call at " + << llvmIRToString(Inst) << '\n'; return false; } @@ -160,28 +171,31 @@ void Resolver::postCall(const llvm::Instruction *Inst) {} auto Resolver::resolveIndirectCall(const llvm::CallBase *CallSite) -> FunctionSetTy { + FunctionSetTy PossibleTargets; if (VTP && isVirtualCall(CallSite, *VTP)) { - return resolveVirtualCall(CallSite); + resolveVirtualCall(PossibleTargets, CallSite); } - return resolveFunctionPointer(CallSite); + + if (PossibleTargets.empty()) { + resolveFunctionPointer(PossibleTargets, CallSite); + } + + return PossibleTargets; } -auto Resolver::resolveFunctionPointer(const llvm::CallBase *CallSite) - -> FunctionSetTy { +void Resolver::resolveFunctionPointer(FunctionSetTy &PossibleTargets, + const llvm::CallBase *CallSite) { // we may wish to optimise this function // naive implementation that considers every function whose signature // matches the call-site's signature as a callee target PHASAR_LOG_LEVEL(DEBUG, "Call function pointer: " << llvmIRToString(CallSite)); - FunctionSetTy CalleeTargets; for (const auto *F : IRDB->getAllFunctions()) { if (F->hasAddressTaken() && isConsistentCall(CallSite, F)) { - CalleeTargets.insert(F); + PossibleTargets.insert(F); } } - - return CalleeTargets; } void Resolver::otherInst(const llvm::Instruction *Inst) {} diff --git a/lib/PhasarLLVM/TypeHierarchy/LLVMVFTable.cpp b/lib/PhasarLLVM/TypeHierarchy/LLVMVFTable.cpp index f2a5a849bd..78d2bd2e9e 100644 --- a/lib/PhasarLLVM/TypeHierarchy/LLVMVFTable.cpp +++ b/lib/PhasarLLVM/TypeHierarchy/LLVMVFTable.cpp @@ -69,22 +69,26 @@ void LLVMVFTable::printAsJson(llvm::raw_ostream &OS) const { } std::vector -LLVMVFTable::getVFVectorFromIRVTable(const llvm::ConstantStruct &VT) { +LLVMVFTable::getVFVectorFromIRVTable(const llvm::ConstantStruct &VT, + uint32_t Index) { std::vector VFS; - for (const auto &Op : VT.operands()) { - if (const auto *CA = llvm::dyn_cast(Op)) { - // Start iterating at offset 2, because offset 0 is vbase offset, offset 1 - // is RTTI - for (const auto *It = std::next(CA->operands().begin(), 2); - It != CA->operands().end(); ++It) { - const auto *Entry = It->get()->stripPointerCastsAndAliases(); - - const auto *F = llvm::dyn_cast(Entry); - VFS.push_back(F); - } + if (Index >= VT.getNumOperands()) { + return VFS; + } + + const auto *Op = VT.getOperand(Index); + + if (const auto *CA = llvm::dyn_cast(Op)) { + // Start iterating at offset 2, because offset 0 is vbase offset, offset 1 + // is RTTI + for (const auto *It = std::next(CA->operands().begin(), 2); + It != CA->operands().end(); ++It) { + const auto *Entry = It->get()->stripPointerCastsAndAliases(); + + const auto *F = llvm::dyn_cast(Entry); + VFS.push_back(F); } } return VFS; } - } // namespace psr diff --git a/test/llvm_test_code/call_graphs/CMakeLists.txt b/test/llvm_test_code/call_graphs/CMakeLists.txt index 9a4557b178..833ff39d2e 100644 --- a/test/llvm_test_code/call_graphs/CMakeLists.txt +++ b/test/llvm_test_code/call_graphs/CMakeLists.txt @@ -27,6 +27,8 @@ set(NoMem2regSources virtual_call_7.cpp virtual_call_8.cpp virtual_call_9.cpp + virtual_call_10.cpp + virtual_call_11.cpp global_ctor_dtor_1.cpp global_ctor_dtor_2.cpp global_ctor_dtor_3.cpp diff --git a/test/llvm_test_code/call_graphs/virtual_call_10.cpp b/test/llvm_test_code/call_graphs/virtual_call_10.cpp index b0bdf36030..121eee4d41 100644 --- a/test/llvm_test_code/call_graphs/virtual_call_10.cpp +++ b/test/llvm_test_code/call_graphs/virtual_call_10.cpp @@ -16,7 +16,7 @@ struct ABImpl : A, B { }; int main() { - auto *ABptr = new ABImpl; - ABptr->foo(); + B *ABptr = new ABImpl; + ABptr->bar(); delete ABptr; } diff --git a/test/llvm_test_code/call_graphs/virtual_call_11.cpp b/test/llvm_test_code/call_graphs/virtual_call_11.cpp new file mode 100644 index 0000000000..e98782e23f --- /dev/null +++ b/test/llvm_test_code/call_graphs/virtual_call_11.cpp @@ -0,0 +1,45 @@ +// handle virtual function call on a pointer to an interface implementation + +struct A { + virtual void foo() = 0; +}; + +struct B { + virtual void bar() = 0; +}; + +struct ABImpl : A, B { + void foo() override {} + void bar() override {} +}; + +struct C { + + virtual void baz() {} +}; + +struct ABCImpl : C, ABImpl { + void foo() override {} + void bar() override {} + void baz() override {} +}; + +void callFoo(A &a) { // + a.foo(); +} + +void callBar(B &b) { // + b.bar(); +} + +void callBaz(C &c) { // + c.baz(); +} + +int main() { + ABCImpl abc; + + callFoo(abc); + callBar(abc); + callBaz(abc); +} diff --git a/unittests/PhasarLLVM/ControlFlow/CMakeLists.txt b/unittests/PhasarLLVM/ControlFlow/CMakeLists.txt index 11a79b8389..95d3b00e67 100644 --- a/unittests/PhasarLLVM/ControlFlow/CMakeLists.txt +++ b/unittests/PhasarLLVM/ControlFlow/CMakeLists.txt @@ -4,6 +4,7 @@ set(ControlFlowSources LLVMBasedICFG_CHATest.cpp LLVMBasedICFG_OTFTest.cpp LLVMBasedICFG_RTATest.cpp + LLVMBasedICFG_RTA_MultipleInheritanceTest.cpp LLVMBasedBackwardCFGTest.cpp LLVMBasedBackwardICFGTest.cpp LLVMBasedICFGExportTest.cpp diff --git a/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFG_RTA_MultipleInheritanceTest.cpp b/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFG_RTA_MultipleInheritanceTest.cpp index 339433688c..594aa828cc 100644 --- a/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFG_RTA_MultipleInheritanceTest.cpp +++ b/unittests/PhasarLLVM/ControlFlow/LLVMBasedICFG_RTA_MultipleInheritanceTest.cpp @@ -4,85 +4,117 @@ #include "phasar/PhasarLLVM/DB/LLVMProjectIRDB.h" #include "phasar/PhasarLLVM/Pointer/LLVMAliasSet.h" #include "phasar/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.h" +#include "phasar/PhasarLLVM/Utils/LLVMIRToSrc.h" #include "phasar/PhasarLLVM/Utils/LLVMShorthands.h" +#include "llvm/IR/InstIterator.h" +#include "llvm/IR/InstrTypes.h" +#include "llvm/Support/Casting.h" + #include "TestConfig.h" #include "gtest/gtest.h" -using namespace std; using namespace psr; -TEST(LLVMBasedICFG_RTATest, VirtualCallSite_10) { - // TODO: test if getNonPureVirtualVFTEntry gets the correct inheritance and - // not just the first one every time +static const llvm::CallBase *getCallInLine(const llvm::Function &F, + uint32_t Line) { + for (const auto &I : llvm::instructions(F)) { + const auto *CB = llvm::dyn_cast(&I); + if (!CB) { + continue; + } - LLVMProjectIRDB IRDB(unittest::PathToLLTestFiles + - "call_graphs/virtual_call_10_cpp.ll"); - DIBasedTypeHierarchy TH(IRDB); - LLVMAliasSet PT(&IRDB); - LLVMBasedICFG ICFG(&IRDB, CallGraphAnalysisType::RTA, {"main"}, &TH, &PT); - const llvm::Function *F = IRDB.getFunctionDefinition("main"); - const llvm::Function *FooD = IRDB.getFunctionDefinition("_ZN1D3fooEv"); - ASSERT_TRUE(FooD); - ASSERT_TRUE(F); - - const llvm::Instruction *I = getNthInstruction(F, 11); - if (llvm::isa(I) || llvm::isa(I)) { - const auto &Callees = ICFG.getCalleesOfCallAt(I); - set CalleeNames; - for (const llvm::Function *F : Callees) { - CalleeNames.insert(F->getName().str()); + auto CBLine = getLineFromIR(CB); + if (CBLine == Line) { + return CB; } - ASSERT_EQ(Callees.size(), 3U); - ASSERT_TRUE(CalleeNames.count("_ZN1B3fooEv")); - ASSERT_TRUE(CalleeNames.count("_ZN1D3fooEv")); - ASSERT_TRUE(CalleeNames.count("_ZN1C3fooEv")); - ASSERT_TRUE(llvm::is_contained(ICFG.getCallersOf(FooD), I)); } + return nullptr; } -// TODO: -#if false -TEST(LLVMBasedICFG_RTATest, VirtualCallSite_3) { +TEST(LLVMBasedICFG_RTATest, VirtualCallSite_10) { + // TODO: test if getNonPureVirtualVFTEntry gets the correct inheritance and + // not just the first one every time + LLVMProjectIRDB IRDB(unittest::PathToLLTestFiles + - "call_graphs/virtual_call_3_cpp.ll"); + "call_graphs/virtual_call_10_cpp_dbg.ll"); DIBasedTypeHierarchy TH(IRDB); - LLVMAliasSet PT(&IRDB); - LLVMBasedICFG ICFG(&IRDB, CallGraphAnalysisType::RTA, {"main"}, &TH, &PT); - const llvm::Function *F = IRDB.getFunctionDefinition("main"); - const llvm::Function *AptrFoo = IRDB.getFunctionDefinition("_ZN5AImpl3fooEv"); - ASSERT_TRUE(F); - ASSERT_TRUE(AptrFoo); - - const llvm::Instruction *I = getNthInstruction(F, 14); - if (llvm::isa(I) || llvm::isa(I)) { - ASSERT_TRUE(ICFG.isVirtualFunctionCall(I)); - const auto &Callees = ICFG.getCalleesOfCallAt(I); - ASSERT_EQ(Callees.size(), 1U); - ASSERT_TRUE(llvm::is_contained(Callees, AptrFoo)); - } + LLVMBasedICFG ICFG(&IRDB, CallGraphAnalysisType::RTA, {"main"}, &TH); + const llvm::Function *MainF = IRDB.getFunctionDefinition("main"); + ASSERT_TRUE(MainF); + + // --- At Line 20: ABptr->bar(); + + const auto *CallToBar = getCallInLine(*MainF, 20); + ASSERT_TRUE(CallToBar); + const auto *BarF = IRDB.getFunction("_ZThn8_N6ABImpl3barEv"); + ASSERT_TRUE(BarF); + + auto BarCallees = ICFG.getCalleesOfCallAt(CallToBar); + // non-virtual thunk to ABImpl::bar() + EXPECT_EQ(llvm::ArrayRef{BarF}, BarCallees); + + // --- At Line 21: delete ABptr; + + const auto *CallToDtor = getCallInLine(*MainF, 21); + ASSERT_TRUE(CallToDtor); + const auto *DtorF = IRDB.getFunction("_ZThn8_N6ABImplD0Ev"); + ASSERT_TRUE(DtorF); + + auto DtorCallees = ICFG.getCalleesOfCallAt(CallToDtor); + + // non-virtual thunk to ABImpl::~ABImpl() + EXPECT_EQ(llvm::ArrayRef{DtorF}, DtorCallees); } -TEST(LLVMBasedICFG_RTATest, StaticCallSite_13) { +TEST(LLVMBasedICFG_RTATest, VirtualCallSite_11) { + // TODO: test if getNonPureVirtualVFTEntry gets the correct inheritance and + // not just the first one every time + LLVMProjectIRDB IRDB(unittest::PathToLLTestFiles + - "call_graphs/static_callsite_13_cpp.ll"); + "call_graphs/virtual_call_11_cpp_dbg.ll"); DIBasedTypeHierarchy TH(IRDB); - LLVMAliasSet PT(&IRDB); - LLVMBasedICFG ICFG(&IRDB, CallGraphAnalysisType::RTA, {"main"}, &TH, &PT); - const llvm::Function *F = IRDB.getFunctionDefinition("main"); - const llvm::Function *Vfunc = IRDB.getFunctionDefinition("_Z5VfuncP1A"); - const llvm::Function *VfuncA = IRDB.getFunctionDefinition("_ZN1A5VfuncEv"); - ASSERT_TRUE(F); - ASSERT_TRUE(Vfunc); - ASSERT_TRUE(VfuncA); - - const llvm::Instruction *I = getNthInstruction(F, 15); - if (llvm::isa(I) || llvm::isa(I)) { - const auto &Callees = ICFG.getCalleesOfCallAt(I); - ASSERT_EQ(Callees.size(), 1U); - } + LLVMBasedICFG ICFG(&IRDB, CallGraphAnalysisType::RTA, {"main"}, &TH); + const llvm::Function *CallFooF = IRDB.getFunctionDefinition("_Z7callFooR1A"); + const llvm::Function *CallBarF = IRDB.getFunctionDefinition("_Z7callBarR1B"); + const llvm::Function *CallBazF = IRDB.getFunctionDefinition("_Z7callBazR1C"); + ASSERT_TRUE(CallFooF); + ASSERT_TRUE(CallBarF); + ASSERT_TRUE(CallBazF); + + // --- At Line 28: a.foo(); + + const auto *CallToFoo = getCallInLine(*CallFooF, 28); + ASSERT_TRUE(CallToFoo); + const auto *FooF = IRDB.getFunction("_ZThn8_N7ABCImpl3fooEv"); + ASSERT_TRUE(FooF); + + auto FooCallees = ICFG.getCalleesOfCallAt(CallToFoo); + // non-virtual thunk to ABCImpl::foo() + EXPECT_EQ(llvm::ArrayRef{FooF}, FooCallees); + + // --- At Line 32: b.bar(); + + const auto *CallToBar = getCallInLine(*CallBarF, 32); + ASSERT_TRUE(CallToBar); + const auto *BarF = IRDB.getFunction("_ZThn16_N7ABCImpl3barEv"); + ASSERT_TRUE(BarF); + + auto BarCallees = ICFG.getCalleesOfCallAt(CallToBar); + // non-virtual thunk to ABCImpl::bar() + EXPECT_EQ(llvm::ArrayRef{BarF}, BarCallees); + + // --- At Line 36: c.baz(); + + const auto *CallToBaz = getCallInLine(*CallBazF, 36); + ASSERT_TRUE(CallToBaz); + const auto *BazF = IRDB.getFunction("_ZN7ABCImpl3bazEv"); + ASSERT_TRUE(BazF); + + auto BazCallees = ICFG.getCalleesOfCallAt(CallToBaz); + // ABCImpl::baz() + EXPECT_EQ(llvm::ArrayRef{BazF}, BazCallees); } -#endif int main(int Argc, char **Argv) { ::testing::InitGoogleTest(&Argc, Argv); From b2e021bfc9b3e1c77d14c8834f51a75ba7742998 Mon Sep 17 00:00:00 2001 From: Fabian Schiebel Date: Sat, 7 Jun 2025 16:29:38 +0200 Subject: [PATCH 65/66] pre-commit --- lib/PhasarLLVM/ControlFlow/LLVMBasedCallGraphBuilder.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/PhasarLLVM/ControlFlow/LLVMBasedCallGraphBuilder.cpp b/lib/PhasarLLVM/ControlFlow/LLVMBasedCallGraphBuilder.cpp index 692d1ea7a5..e3f65c00ec 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 4a997de42766699b0c3ee00681d802f93741d0c6 Mon Sep 17 00:00:00 2001 From: Fabian Schiebel Date: Mon, 9 Jun 2025 13:56:19 +0200 Subject: [PATCH 66/66] some cleanup --- .../ControlFlow/LLVMVFTableProvider.h | 7 +++ .../TypeHierarchy/DIBasedTypeHierarchy.h | 2 + .../PhasarLLVM/TypeHierarchy/LLVMVFTable.h | 8 ++-- .../ControlFlow/LLVMVFTableProvider.cpp | 44 ++++++++++++++----- .../TypeHierarchy/DIBasedTypeHierarchy.cpp | 2 +- lib/PhasarLLVM/TypeHierarchy/LLVMVFTable.cpp | 7 +-- 6 files changed, 48 insertions(+), 22 deletions(-) diff --git a/include/phasar/PhasarLLVM/ControlFlow/LLVMVFTableProvider.h b/include/phasar/PhasarLLVM/ControlFlow/LLVMVFTableProvider.h index a9b6f964c0..accb0dfcb9 100644 --- a/include/phasar/PhasarLLVM/ControlFlow/LLVMVFTableProvider.h +++ b/include/phasar/PhasarLLVM/ControlFlow/LLVMVFTableProvider.h @@ -54,6 +54,13 @@ class LLVMVFTableProvider { getVTableIndexInHierarchy(const llvm::DIType *DerivedType, const llvm::DIType *BaseType) const; + /// Supercedes DIBasedTypeHierarchy::removeVTablePrefix + [[nodiscard]] static llvm::StringRef + removeVTablePrefix(llvm::StringRef GlobName) noexcept; + + /// Supercedes DIBasedTypeHierarchy::isVTable + [[nodiscard]] static bool isVTable(llvm::StringRef MangledVarName); + private: llvm::StringMap ClearNameTVMap; std::unordered_map, LLVMVFTable, diff --git a/include/phasar/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.h b/include/phasar/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.h index d4554958a8..fccd023f85 100644 --- a/include/phasar/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.h +++ b/include/phasar/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.h @@ -58,7 +58,9 @@ class DIBasedTypeHierarchy const DIBasedTypeHierarchyData &SerializedData); ~DIBasedTypeHierarchy() override = default; + [[deprecated("Use LLVMVFTableProvider::isVTable() instead")]] static bool isVTable(llvm::StringRef VarName); + [[deprecated("Use LLVMVFTableProvider::removeVTablePrefix() instead")]] static std::string removeVTablePrefix(llvm::StringRef VarName); [[nodiscard]] bool hasType(ClassType Type) const override { diff --git a/include/phasar/PhasarLLVM/TypeHierarchy/LLVMVFTable.h b/include/phasar/PhasarLLVM/TypeHierarchy/LLVMVFTable.h index 5b55901e82..e4955ab05b 100644 --- a/include/phasar/PhasarLLVM/TypeHierarchy/LLVMVFTable.h +++ b/include/phasar/PhasarLLVM/TypeHierarchy/LLVMVFTable.h @@ -73,21 +73,21 @@ class LLVMVFTable : public VFTable { void printAsJson(llvm::raw_ostream &OS) const override; - [[nodiscard]] std::vector::iterator begin() { + [[nodiscard]] std::vector::iterator begin() noexcept { return VFT.begin(); } [[nodiscard]] std::vector::const_iterator - begin() const { + begin() const noexcept { return VFT.begin(); }; - [[nodiscard]] std::vector::iterator end() { + [[nodiscard]] std::vector::iterator end() noexcept { return VFT.end(); }; [[nodiscard]] std::vector::const_iterator - end() const { + end() const noexcept { return VFT.end(); }; diff --git a/lib/PhasarLLVM/ControlFlow/LLVMVFTableProvider.cpp b/lib/PhasarLLVM/ControlFlow/LLVMVFTableProvider.cpp index 95d097f16d..67246c938e 100644 --- a/lib/PhasarLLVM/ControlFlow/LLVMVFTableProvider.cpp +++ b/lib/PhasarLLVM/ControlFlow/LLVMVFTableProvider.cpp @@ -4,10 +4,8 @@ #include "phasar/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.h" #include "phasar/PhasarLLVM/TypeHierarchy/LLVMVFTable.h" #include "phasar/PhasarLLVM/Utils/LLVMIRToSrc.h" -#include "phasar/Utils/Logger.h" #include "phasar/Utils/MapUtils.h" -#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" #include "llvm/BinaryFormat/Dwarf.h" #include "llvm/Demangle/Demangle.h" @@ -18,20 +16,26 @@ #include "llvm/Support/Casting.h" using namespace psr; -static constexpr llvm::StringLiteral TIPrefix = "typeinfo name for "; + +static constexpr llvm::StringLiteral TSPrefixDemang = "typeinfo name for "; +static constexpr llvm::StringLiteral VTablePrefixDemang = "vtable for "; +static constexpr llvm::StringLiteral VTablePrefix = "_ZTV"; static std::string getTypeName(const llvm::DIType *DITy) { - auto Ret = [DITy] { + auto TypeName = [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()); + if (auto Ident = CompTy->getIdentifier(); !Ident.empty()) { + return Ident; + } } - return llvm::demangle(DITy->getName().str()); + return DITy->getName(); }(); - if (llvm::StringRef(Ret).startswith(TIPrefix)) { - Ret.erase(0, TIPrefix.size()); + // In LLVM 17 demangle() takes a StringRef + auto Ret = llvm::demangle(TypeName.str()); + + if (llvm::StringRef(Ret).startswith(TSPrefixDemang)) { + Ret.erase(0, TSPrefixDemang.size()); } return Ret; @@ -85,9 +89,9 @@ static void getBasesOfVirt( LLVMVFTableProvider::LLVMVFTableProvider(const llvm::Module &Mod) { for (const auto &Glob : Mod.globals()) { - if (DIBasedTypeHierarchy::isVTable(Glob.getName())) { + if (isVTable(Glob.getName())) { auto Demang = llvm::demangle(Glob.getName().str()); - auto ClearName = DIBasedTypeHierarchy::removeVTablePrefix(Demang); + auto ClearName = removeVTablePrefix(Demang); // llvm::errs() << "> ClearName: " << ClearName << '\n'; ClearNameTVMap.try_emplace(ClearName, &Glob); } @@ -162,3 +166,19 @@ LLVMVFTableProvider::getVTableIndexInHierarchy( return InnerIt->second; } + +llvm::StringRef +LLVMVFTableProvider::removeVTablePrefix(llvm::StringRef GlobName) noexcept { + if (GlobName.startswith(VTablePrefixDemang)) { + return GlobName.drop_front(VTablePrefixDemang.size()); + } + if (GlobName.startswith(VTablePrefix)) { + return GlobName.drop_front(VTablePrefix.size()); + } + return GlobName; +} + +/// Supercedes DIBasedTypeHierarchy::isVTable() + removeVTablePrefix +bool LLVMVFTableProvider::isVTable(llvm::StringRef MangledVarName) { + return MangledVarName.startswith(VTablePrefix); +} diff --git a/lib/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.cpp b/lib/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.cpp index 3d854848b4..4967c9faf0 100644 --- a/lib/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.cpp +++ b/lib/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.cpp @@ -315,7 +315,7 @@ bool DIBasedTypeHierarchy::isVTable(llvm::StringRef VarName) { if (VarName.startswith(VTablePrefix)) { return true; } - // In LLVM 16 demangle() takes a StringRef + // In LLVM 17 demangle() takes a StringRef auto Demang = llvm::demangle(VarName.str()); return llvm::StringRef(Demang).startswith(VTablePrefixDemang); } diff --git a/lib/PhasarLLVM/TypeHierarchy/LLVMVFTable.cpp b/lib/PhasarLLVM/TypeHierarchy/LLVMVFTable.cpp index 78d2bd2e9e..7a7e487b94 100644 --- a/lib/PhasarLLVM/TypeHierarchy/LLVMVFTable.cpp +++ b/lib/PhasarLLVM/TypeHierarchy/LLVMVFTable.cpp @@ -10,15 +10,12 @@ #include "phasar/PhasarLLVM/TypeHierarchy/LLVMVFTable.h" #include "phasar/PhasarLLVM/TypeHierarchy/LLVMVFTableData.h" -#include "phasar/Utils/NlohmannLogging.h" +#include "llvm/IR/Constants.h" #include "llvm/IR/Function.h" -#include "llvm/IR/GlobalAlias.h" -#include "llvm/IR/Operator.h" #include "llvm/Support/raw_ostream.h" #include -#include using namespace psr; @@ -51,7 +48,7 @@ void LLVMVFTable::print(llvm::raw_ostream &OS) const { [[nodiscard]] LLVMVFTableData LLVMVFTable::getVFTableData() const { LLVMVFTableData Data; - for (const auto &Curr : VFT) { + for (const auto *Curr : VFT) { if (Curr) { Data.VFT.push_back(Curr->getName().str()); continue;