Skip to content

Commit 590f19f

Browse files
fabianbs96fabianbs
andauthored
Misc fixes (#743)
* Make TaintConfigData compatible with C++20 * Compatibility with opaque pointers * Allow setting the LLVM version from higher-level projects * Getting rid of UB in CHAResolver * Better IntraMonoSolver dump * minor * improve intra mono dump * minor * expose getNonPureVirtualVFTEntry as namespace-scope function + fix build with LLVM 14 * Fix solveIFDSProblem --------- Co-authored-by: Fabian Schiebel <fabianbs@mail.uni-paderborn.de>
1 parent 64a7233 commit 590f19f

File tree

12 files changed

+130
-39
lines changed

12 files changed

+130
-39
lines changed

CMakeLists.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ set(CMAKE_POLICY_DEFAULT_CMP0069 NEW)
88
cmake_policy(SET CMP0077 NEW)
99
set(CMAKE_POLICY_DEFAULT_CMP0077 NEW)
1010

11+
# Allow overwriting cache variables of external projects from this CMakeLists file
12+
cmake_policy(SET CMP0126 NEW)
13+
set(CMAKE_POLICY_DEFAULT_CMP0126 NEW)
14+
1115
# Allow portable use of CMAKE_VISIBILITY_INLINES_HIDDEN not only for shared libraries
1216
cmake_policy(SET CMP0063 NEW)
1317
set(CMAKE_POLICY_DEFAULT_CMP0063 NEW)
@@ -303,6 +307,9 @@ endif()
303307
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)
304308

305309
# LLVM
310+
if (NOT PHASAR_LLVM_VERSION)
311+
set(PHASAR_LLVM_VERSION 14)
312+
endif()
306313
include(add_llvm)
307314
add_llvm()
308315

cmake/add_llvm.cmake

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ macro(add_llvm)
22

33
if (NOT PHASAR_IN_TREE)
44
# Only search for LLVM if we build out of tree
5-
find_package(LLVM 14 REQUIRED CONFIG)
5+
find_package(LLVM ${PHASAR_LLVM_VERSION} REQUIRED CONFIG)
66
find_library(LLVM_LIBRARY NAMES LLVM PATHS ${LLVM_LIBRARY_DIRS} NO_DEFAULT_PATH)
77

88
if(USE_LLVM_FAT_LIB AND ${LLVM_LIBRARY} STREQUAL "LLVM_LIBRARY-NOTFOUND")

cmake/phasar_macros.cmake

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,10 +125,21 @@ function(generate_ll_file)
125125
endif()
126126

127127
if(GEN_LL_MEM2REG)
128+
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
129+
get_filename_component(COMPILER_PATH_STR ${CMAKE_CXX_COMPILER} DIRECTORY)
130+
find_program(OPT_TOOL opt HINTS ${COMPILER_PATH_STR})
131+
else()
132+
find_program(OPT_TOOL opt)
133+
endif()
134+
135+
if(NOT OPT_TOOL)
136+
set(OPT_TOOL opt)
137+
endif()
138+
128139
add_custom_command(
129140
OUTPUT ${test_code_ll_file}
130141
COMMAND ${GEN_CMD} ${test_code_file_path} -o ${test_code_ll_file}
131-
COMMAND ${CMAKE_CXX_COMPILER_LAUNCHER} opt -mem2reg -S -opaque-pointers=0 ${test_code_ll_file} -o ${test_code_ll_file}
142+
COMMAND ${CMAKE_CXX_COMPILER_LAUNCHER} ${OPT_TOOL} -mem2reg -S -opaque-pointers=0 ${test_code_ll_file} -o ${test_code_ll_file}
132143
COMMENT ${GEN_CMD_COMMENT}
133144
DEPENDS ${GEN_LL_FILE}
134145
VERBATIM

include/phasar/DataFlow/IfdsIde/Solver/IFDSSolver.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
#include "phasar/DataFlow/IfdsIde/Solver/IDESolver.h"
2222
#include "phasar/Domain/BinaryDomain.h"
2323

24-
#include <memory>
2524
#include <set>
2625
#include <type_traits>
2726
#include <unordered_map>
@@ -118,8 +117,7 @@ using IFDSSolver_P = IFDSSolver<typename Problem::ProblemAnalysisDomain,
118117

119118
template <typename AnalysisDomainTy, typename Container>
120119
OwningSolverResults<typename AnalysisDomainTy::n_t,
121-
typename AnalysisDomainTy::d_t,
122-
typename AnalysisDomainTy::l_t>
120+
typename AnalysisDomainTy::d_t, BinaryDomain>
123121
solveIFDSProblem(IFDSTabulationProblem<AnalysisDomainTy, Container> &Problem,
124122
const typename AnalysisDomainTy::i_t &ICF) {
125123
IFDSSolver<AnalysisDomainTy, Container> Solver(Problem, &ICF);

include/phasar/DataFlow/Mono/Solver/IntraMonoSolver.h

Lines changed: 38 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@
1818
#define PHASAR_DATAFLOW_MONO_SOLVER_INTRAMONOSOLVER_H
1919

2020
#include "phasar/DataFlow/Mono/IntraMonoProblem.h"
21-
#include "phasar/Utils/BitVectorSet.h"
21+
#include "phasar/PhasarLLVM/Utils/LLVMShorthands.h"
22+
#include "phasar/Utils/DefaultValue.h"
23+
#include "phasar/Utils/Utilities.h"
2224

2325
#include <deque>
2426
#include <unordered_map>
@@ -109,20 +111,47 @@ template <typename AnalysisDomainTy> class IntraMonoSolver {
109111
}
110112
}
111113

112-
mono_container_t getResultsAt(n_t Stmt) { return Analysis[Stmt]; }
114+
[[nodiscard]] const mono_container_t &getResultsAt(n_t Stmt) const {
115+
auto It = Analysis.find(Stmt);
116+
if (It != Analysis.end()) {
117+
return It->second;
118+
}
119+
return getDefaultValue<mono_container_t>();
120+
}
113121

114122
virtual void dumpResults(llvm::raw_ostream &OS = llvm::outs()) {
115-
OS << "Intra-Monotone solver results:\n"
116-
"------------------------------\n";
117-
for (auto &[Node, FlowFacts] : this->Analysis) {
118-
OS << "Instruction:\n" << NToString(Node);
119-
OS << "\nFacts:\n";
123+
OS << "\n***************************************************************\n"
124+
<< "* Raw IntraMonoSolver results *\n"
125+
<< "***************************************************************\n";
126+
127+
if (Analysis.empty()) {
128+
OS << "No results computed!" << '\n';
129+
return;
130+
}
131+
132+
std::vector<std::pair<n_t, mono_container_t>> Cells;
133+
Cells.reserve(Analysis.size());
134+
Cells.insert(Cells.end(), Analysis.begin(), Analysis.end());
135+
136+
std::sort(Cells.begin(), Cells.end(), [](const auto &Lhs, const auto &Rhs) {
137+
if constexpr (std::is_same_v<n_t, const llvm::Instruction *>) {
138+
return StringIDLess{}(getMetaDataID(Lhs.first),
139+
getMetaDataID(Rhs.first));
140+
} else {
141+
// If non-LLVM IR is used
142+
return Lhs.first < Rhs.first;
143+
}
144+
});
145+
146+
for (const auto &[Node, FlowFacts] : Cells) {
147+
OS << "Instruction: " << NToString(Node);
148+
OS << "\nFacts: ";
120149
if (FlowFacts.empty()) {
121-
OS << "\tEMPTY\n";
150+
OS << "EMPTY\n";
122151
} else {
123152
IMProblem.printContainer(OS, FlowFacts);
124153
}
125-
OS << "\n\n";
154+
OS << "\n";
126155
}
127156
}
128157

include/phasar/PhasarLLVM/ControlFlow/Resolver/CHAResolver.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,9 @@ class CHAResolver : public Resolver {
3131
CHAResolver(const LLVMProjectIRDB *IRDB, const LLVMVFTableProvider *VTP,
3232
const LLVMTypeHierarchy *TH);
3333

34-
~CHAResolver() override = default;
34+
// Deleting an incomplete type (LLVMTypeHierarchy) is UB, so instantiate the
35+
// dtor in CHAResolver.cpp
36+
~CHAResolver() override;
3537

3638
FunctionSetTy resolveVirtualCall(const llvm::CallBase *CallSite) override;
3739

include/phasar/PhasarLLVM/ControlFlow/Resolver/Resolver.h

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,29 @@ class LLVMVFTableProvider;
3838
class LLVMTypeHierarchy;
3939
enum class CallGraphAnalysisType;
4040

41+
/// Assuming that `CallSite` is a virtual call through a vtable, retrieves the
42+
/// index in the vtable of the virtual function called.
4143
[[nodiscard]] std::optional<unsigned>
4244
getVFTIndex(const llvm::CallBase *CallSite);
4345

46+
/// Assuming that `CallSite` is a vall to a non-static member function,
47+
/// retrieves the type of the receiver. Returns nullptr, if the receiver-type
48+
/// could not be extracted
4449
[[nodiscard]] const llvm::StructType *
4550
getReceiverType(const llvm::CallBase *CallSite);
4651

52+
/// Assuming that `CallSite` is a virtual call, where `Idx` is retrieved through
53+
/// `getVFTIndex()` and `T` through `getReceiverType()`
54+
[[nodiscard]] const llvm::Function *
55+
getNonPureVirtualVFTEntry(const llvm::StructType *T, unsigned Idx,
56+
const llvm::CallBase *CallSite,
57+
const psr::LLVMVFTableProvider &VTP);
58+
4759
[[nodiscard]] std::string getReceiverTypeName(const llvm::CallBase *CallSite);
4860

61+
/// Checks whether the signature of `DestFun` matches the required withature of
62+
/// `CallSite`, such that `DestFun` qualifies as callee-candidate, if `CallSite`
63+
/// is an indirect/virtual call.
4964
[[nodiscard]] bool isConsistentCall(const llvm::CallBase *CallSite,
5065
const llvm::Function *DestFun);
5166

@@ -59,7 +74,12 @@ class Resolver {
5974

6075
const llvm::Function *
6176
getNonPureVirtualVFTEntry(const llvm::StructType *T, unsigned Idx,
62-
const llvm::CallBase *CallSite);
77+
const llvm::CallBase *CallSite) {
78+
if (!VTP) {
79+
return nullptr;
80+
}
81+
return psr::getNonPureVirtualVFTEntry(T, Idx, CallSite, *VTP);
82+
}
6383

6484
public:
6585
using FunctionSetTy = llvm::SmallDenseSet<const llvm::Function *, 4>;

include/phasar/PhasarLLVM/DB/LLVMProjectIRDB.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
#include "llvm/ADT/DenseMap.h"
1919
#include "llvm/ADT/STLExtras.h"
2020
#include "llvm/ADT/StringRef.h"
21-
#include "llvm/ADT/iterator_range.h"
2221
#include "llvm/IR/Instruction.h"
2322
#include "llvm/IR/LLVMContext.h"
2423
#include "llvm/IR/Module.h"
@@ -44,7 +43,8 @@ class LLVMProjectIRDB : public ProjectIRDBBase<LLVMProjectIRDB> {
4443
/// Reads and parses the given LLVM IR file and owns the resulting IR Module.
4544
/// If an error occurs, an error message is written to stderr and subsequent
4645
/// calls to isValid() return false.
47-
explicit LLVMProjectIRDB(const llvm::Twine &IRFileName);
46+
explicit LLVMProjectIRDB(const llvm::Twine &IRFileName,
47+
bool EnableOpaquePointers = LLVM_VERSION_MAJOR > 14);
4848
/// Initializes the new ProjectIRDB with the given IR Module _without_ taking
4949
/// ownership. The module is optionally being preprocessed.
5050
///
@@ -58,7 +58,8 @@ class LLVMProjectIRDB : public ProjectIRDBBase<LLVMProjectIRDB> {
5858
/// Parses the given LLVM IR file and owns the resulting IR Module.
5959
/// If an error occurs, an error message is written to stderr and subsequent
6060
/// calls to isValid() return false.
61-
explicit LLVMProjectIRDB(llvm::MemoryBufferRef Buf);
61+
explicit LLVMProjectIRDB(llvm::MemoryBufferRef Buf,
62+
bool EnableOpaquePointers = LLVM_VERSION_MAJOR > 14);
6263

6364
LLVMProjectIRDB(const LLVMProjectIRDB &) = delete;
6465
LLVMProjectIRDB &operator=(LLVMProjectIRDB &) = delete;

include/phasar/PhasarLLVM/TaintConfig/TaintConfigData.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@ namespace psr {
1818
enum class TaintCategory;
1919

2020
struct FunctionData {
21+
#if __cplusplus < 202002L
2122
FunctionData() noexcept = default;
23+
#endif
2224

2325
std::string Name;
2426
TaintCategory ReturnCat{};
@@ -29,7 +31,9 @@ struct FunctionData {
2931
};
3032

3133
struct VariableData {
34+
#if __cplusplus < 202002L
3235
VariableData() noexcept = default;
36+
#endif
3337

3438
size_t Line{};
3539
std::string Name;

lib/PhasarLLVM/ControlFlow/Resolver/CHAResolver.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ CHAResolver::CHAResolver(const LLVMProjectIRDB *IRDB,
4040
}
4141
}
4242

43+
CHAResolver::~CHAResolver() = default;
44+
4345
auto CHAResolver::resolveVirtualCall(const llvm::CallBase *CallSite)
4446
-> FunctionSetTy {
4547
PHASAR_LOG_LEVEL(DEBUG, "Call virtual function: ");

0 commit comments

Comments
 (0)