From 4c6bd944025000d59e820ab849210ee28e73c8fe Mon Sep 17 00:00:00 2001 From: Fabian Schiebel Date: Fri, 12 Jan 2024 13:51:55 +0100 Subject: [PATCH 1/2] Fix InitialSeeds Join values correctly when reaching a seed location from a different path --- include/phasar/DataFlow/IfdsIde/Solver/IDESolver.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/include/phasar/DataFlow/IfdsIde/Solver/IDESolver.h b/include/phasar/DataFlow/IfdsIde/Solver/IDESolver.h index 36b782b4cf..eb2c323c3a 100644 --- a/include/phasar/DataFlow/IfdsIde/Solver/IDESolver.h +++ b/include/phasar/DataFlow/IfdsIde/Solver/IDESolver.h @@ -725,7 +725,10 @@ class IDESolver << ", value: " << LToString(Value)); // initialize the initial seeds with the top element as we have no // information at the beginning of the value computation problem - setVal(StartPoint, Fact, Value); + l_t OldVal = val(StartPoint, Fact); + auto NewVal = IDEProblem.join(Value, std::move(OldVal)); + setVal(StartPoint, Fact, std::move(NewVal)); + std::pair SuperGraphNode(StartPoint, Fact); valuePropagationTask(std::move(SuperGraphNode)); } From 35dbf159194c00ca795bd9cd6645bc75237dcbdc Mon Sep 17 00:00:00 2001 From: Fabian Schiebel Date: Fri, 12 Jan 2024 14:34:37 +0100 Subject: [PATCH 2/2] Fix MaybeUniquePtr --- .../PhasarLLVM/ControlFlow/LLVMBasedICFG.h | 1 + .../phasar/PhasarLLVM/DB/LLVMProjectIRDB.h | 2 +- include/phasar/Utils/DFAMinimizer.h | 2 - include/phasar/Utils/MaybeUniquePtr.h | 53 ++++++++++++------- .../TaintConfig/LLVMTaintConfig.cpp | 1 - unittests/Utils/CMakeLists.txt | 3 ++ unittests/Utils/CompilationTests.cpp | 14 +++++ 7 files changed, 53 insertions(+), 23 deletions(-) create mode 100644 unittests/Utils/CompilationTests.cpp diff --git a/include/phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h b/include/phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h index f1af71970b..12bc784930 100644 --- a/include/phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h +++ b/include/phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h @@ -96,6 +96,7 @@ class LLVMBasedICFG : public LLVMBasedCFG, public ICFGBase { const nlohmann::json &SerializedCG, LLVMTypeHierarchy *TH = nullptr); + // Deleter of LLVMTypeHierarchy may be unknown here... ~LLVMBasedICFG(); LLVMBasedICFG(const LLVMBasedICFG &) = delete; diff --git a/include/phasar/PhasarLLVM/DB/LLVMProjectIRDB.h b/include/phasar/PhasarLLVM/DB/LLVMProjectIRDB.h index 590ffafa6d..47df476adf 100644 --- a/include/phasar/PhasarLLVM/DB/LLVMProjectIRDB.h +++ b/include/phasar/PhasarLLVM/DB/LLVMProjectIRDB.h @@ -109,7 +109,7 @@ class LLVMProjectIRDB : public ProjectIRDBBase { [[nodiscard]] m_t getModuleImpl() const noexcept { return Mod.get(); } [[nodiscard]] bool debugInfoAvailableImpl() const; [[nodiscard]] FunctionRange getAllFunctionsImpl() const { - return llvm::map_range(Mod->functions(), + return llvm::map_range(ProjectIRDBBase::getModule()->functions(), Ref2PointerConverter{}); } [[nodiscard]] f_t getFunctionImpl(llvm::StringRef FunctionName) const { diff --git a/include/phasar/Utils/DFAMinimizer.h b/include/phasar/Utils/DFAMinimizer.h index 00a20f0db9..9c08a3b7cc 100644 --- a/include/phasar/Utils/DFAMinimizer.h +++ b/include/phasar/Utils/DFAMinimizer.h @@ -110,8 +110,6 @@ template } } - size_t Idx = 0; - llvm::IntEqClasses Equiv(traits_t::size(G)); auto isEquivalent = [&Equiv](edge_t LHS, edge_t RHS) { diff --git a/include/phasar/Utils/MaybeUniquePtr.h b/include/phasar/Utils/MaybeUniquePtr.h index d7cc7db022..fe086fc85e 100644 --- a/include/phasar/Utils/MaybeUniquePtr.h +++ b/include/phasar/Utils/MaybeUniquePtr.h @@ -11,6 +11,7 @@ #define PHASAR_UTILS_MAYBEUNIQUEPTR_H_ #include "llvm/ADT/PointerIntPair.h" +#include "llvm/Support/PointerLikeTypeTraits.h" #include #include @@ -39,8 +40,12 @@ template class MaybeUniquePtrBase { }; template class MaybeUniquePtrBase { + struct PointerTraits : llvm::PointerLikeTypeTraits { + static constexpr int NumLowBitsAvailable = 1; + }; + protected: - llvm::PointerIntPair Data{}; + llvm::PointerIntPair Data{}; constexpr MaybeUniquePtrBase(T *Ptr, bool Owns) noexcept : Data{Ptr, Owns} {} constexpr MaybeUniquePtrBase() noexcept = default; @@ -61,12 +66,15 @@ class MaybeUniquePtr : detail::MaybeUniquePtrBase { constexpr MaybeUniquePtr() noexcept = default; constexpr MaybeUniquePtr(T *Pointer, bool Owns = false) noexcept - : detail::MaybeUniquePtrBase(Pointer, Owns) {} + : detail::MaybeUniquePtrBase(Pointer, + Owns && Pointer) {} constexpr MaybeUniquePtr(std::unique_ptr &&Owner) noexcept : MaybeUniquePtr(Owner.release(), true) {} - template + template && + std::is_convertible_v>> constexpr MaybeUniquePtr(std::unique_ptr &&Owner) noexcept : MaybeUniquePtr(Owner.release(), true) {} @@ -92,16 +100,20 @@ class MaybeUniquePtr : detail::MaybeUniquePtrBase { if (owns()) { delete Data.getPointer(); } - Data = {Owner.release(), true}; + auto *Ptr = Owner.release(); + Data = {Ptr, Ptr != nullptr}; return *this; } - template + template && + std::is_convertible_v>> constexpr MaybeUniquePtr &operator=(std::unique_ptr &&Owner) noexcept { if (owns()) { delete Data.getPointer(); } - Data = {Owner.release(), true}; + auto *Ptr = Owner.release(); + Data = {Ptr, Ptr != nullptr}; return *this; } @@ -118,24 +130,16 @@ class MaybeUniquePtr : detail::MaybeUniquePtrBase { } } - [[nodiscard]] constexpr T *get() noexcept { return Data.getPointer(); } - [[nodiscard]] constexpr const T *get() const noexcept { - return Data.getPointer(); - } + [[nodiscard]] constexpr T *get() const noexcept { return Data.getPointer(); } - [[nodiscard]] constexpr T *operator->() noexcept { return get(); } - [[nodiscard]] constexpr const T *operator->() const noexcept { return get(); } + [[nodiscard]] constexpr T *operator->() const noexcept { return get(); } - [[nodiscard]] constexpr T &operator*() noexcept { - assert(get() != nullptr); - return *get(); - } - [[nodiscard]] constexpr const T &operator*() const noexcept { + [[nodiscard]] constexpr T &operator*() const noexcept { assert(get() != nullptr); return *get(); } - T *release() noexcept { + constexpr T *release() noexcept { Data.setInt(false); return Data.getPointer(); } @@ -147,8 +151,19 @@ class MaybeUniquePtr : detail::MaybeUniquePtrBase { Data = {}; } + template + constexpr void reset(MaybeUniquePtr &&Other) noexcept { + *this = std::move(Other); + } + + template + constexpr void reset(std::unique_ptr &&Other) noexcept { + *this = std::move(Other); + } + [[nodiscard]] constexpr bool owns() const noexcept { - return Data.getInt() && Data.getPointer(); + assert(Data.getPointer() || !Data.getInt()); + return Data.getInt(); } constexpr friend bool operator==(const MaybeUniquePtr &LHS, diff --git a/lib/PhasarLLVM/TaintConfig/LLVMTaintConfig.cpp b/lib/PhasarLLVM/TaintConfig/LLVMTaintConfig.cpp index a448f43f12..e814aba766 100644 --- a/lib/PhasarLLVM/TaintConfig/LLVMTaintConfig.cpp +++ b/lib/PhasarLLVM/TaintConfig/LLVMTaintConfig.cpp @@ -130,7 +130,6 @@ LLVMTaintConfig::LLVMTaintConfig(const psr::LLVMProjectIRDB &Code, std::unordered_map StructConfigMap; // read all struct types from config - size_t Counter = 0; for (const auto &VarDesc : Config.Variables) { llvm::DebugInfoFinder DIF; const auto *M = Code.getModule(); diff --git a/unittests/Utils/CMakeLists.txt b/unittests/Utils/CMakeLists.txt index fea979d614..62831a3c1c 100644 --- a/unittests/Utils/CMakeLists.txt +++ b/unittests/Utils/CMakeLists.txt @@ -1,4 +1,5 @@ set(UtilsSources + CompilationTests.cpp BitVectorSetTest.cpp EquivalenceClassMapTest.cpp IOTest.cpp @@ -16,3 +17,5 @@ endif() foreach(TEST_SRC ${UtilsSources}) add_phasar_unittest(${TEST_SRC}) endforeach(TEST_SRC) + +target_compile_options(CompilationTests PRIVATE -Wno-delete-incomplete) diff --git a/unittests/Utils/CompilationTests.cpp b/unittests/Utils/CompilationTests.cpp new file mode 100644 index 0000000000..40b21b58a5 --- /dev/null +++ b/unittests/Utils/CompilationTests.cpp @@ -0,0 +1,14 @@ + +#include "phasar/Utils/MaybeUniquePtr.h" + +#include + +struct IncompleteType; + +using MUP = psr::MaybeUniquePtr; +MUP maybeUniquePtrSupportsIncompleteTypes( + std::unique_ptr &&UP) { + return std::move(UP); +} + +int main() {}