Skip to content

Commit e0c5057

Browse files
committed
Various fixes
1 parent aed66c0 commit e0c5057

14 files changed

Lines changed: 296 additions & 85 deletions

File tree

external/googletest

Submodule googletest updated 115 files

external/json

Submodule json updated 373 files

external/json-schema-validator

include/phasar/PhasarLLVM/DataFlowSolver/IfdsIde/Problems/ExtendedTaintAnalysis/AbstractMemoryLocation.h

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -153,31 +153,45 @@ class AbstractMemoryLocationImpl final
153153
class AbstractMemoryLocation {
154154
public:
155155
explicit AbstractMemoryLocation() noexcept = default;
156+
157+
AbstractMemoryLocation(const AbstractMemoryLocation &) noexcept = default;
158+
AbstractMemoryLocation(AbstractMemoryLocation &&) noexcept = default;
159+
~AbstractMemoryLocation() = default;
160+
161+
AbstractMemoryLocation &
162+
operator=(const AbstractMemoryLocation &) noexcept = default;
163+
AbstractMemoryLocation &
164+
operator=(AbstractMemoryLocation &&) noexcept = default;
165+
156166
AbstractMemoryLocation(
157167
const detail::AbstractMemoryLocationImpl *Impl) noexcept;
168+
158169
inline const detail::AbstractMemoryLocationImpl *operator->() const {
159170
return PImpl;
160171
}
161172

162173
/// Provide an arbitrary partial order for being able to store TaintedValues
163174
/// in std::set or as key in std::map
164-
inline bool operator<(const AbstractMemoryLocation &TV) const {
165-
return PImpl->base() < TV->base();
175+
inline bool operator<(AbstractMemoryLocation TV) const {
176+
return PImpl < TV.PImpl;
166177
}
167178

168-
inline bool operator==(const AbstractMemoryLocation &AML) const {
179+
inline bool operator==(AbstractMemoryLocation AML) const {
169180
return PImpl == AML.PImpl;
170181
}
171182

172-
friend std::ostream &operator<<(std::ostream &OS,
173-
const AbstractMemoryLocation &TV);
183+
inline bool operator!=(AbstractMemoryLocation AML) const {
184+
return !(*this == AML);
185+
}
186+
187+
friend std::ostream &operator<<(std::ostream &OS, AbstractMemoryLocation TV);
174188
friend llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
175-
const AbstractMemoryLocation &TV);
189+
AbstractMemoryLocation TV);
176190

177191
/// Computes the absolute offset-difference between this and TV assuming,
178192
/// either this->isProperPrefixOf(TV) or vice versa.
179193
[[nodiscard]] inline llvm::ArrayRef<ptrdiff_t>
180-
operator-(const AbstractMemoryLocation &TV) const {
194+
operator-(AbstractMemoryLocation TV) const {
181195
return *PImpl - *TV.PImpl;
182196
}
183197

@@ -188,13 +202,13 @@ class AbstractMemoryLocation {
188202
};
189203

190204
std::string DToString(const AbstractMemoryLocation &AML);
205+
206+
llvm::hash_code hash_value(psr::AbstractMemoryLocation Val);
191207
} // namespace psr
192208

193209
// Hashing support
194210
namespace llvm {
195211

196-
hash_code hash_value(const psr::AbstractMemoryLocation &Val);
197-
198212
template <> struct DenseMapInfo<psr::AbstractMemoryLocation> {
199213
static inline psr::AbstractMemoryLocation getEmptyKey() {
200214
return psr::AbstractMemoryLocation(
@@ -205,11 +219,11 @@ template <> struct DenseMapInfo<psr::AbstractMemoryLocation> {
205219
DenseMapInfo<
206220
psr::detail::AbstractMemoryLocationImpl *>::getTombstoneKey());
207221
}
208-
static unsigned getHashValue(const psr::AbstractMemoryLocation &Val) {
222+
static unsigned getHashValue(psr::AbstractMemoryLocation Val) {
209223
return hash_value(Val);
210224
}
211-
static bool isEqual(const psr::AbstractMemoryLocation &LHS,
212-
const psr::AbstractMemoryLocation &RHS) {
225+
static bool isEqual(psr::AbstractMemoryLocation LHS,
226+
psr::AbstractMemoryLocation RHS) {
213227
return LHS.operator->() == RHS.operator->();
214228
}
215229
};
@@ -219,7 +233,7 @@ template <> struct DenseMapInfo<psr::AbstractMemoryLocation> {
219233
namespace std {
220234
template <> struct hash<psr::AbstractMemoryLocation> {
221235
size_t operator()(const psr::AbstractMemoryLocation &Val) const {
222-
return llvm::hash_value(Val);
236+
return hash_value(Val);
223237
}
224238
};
225239

include/phasar/PhasarLLVM/DataFlowSolver/IfdsIde/Problems/ExtendedTaintAnalysis/XTaintAnalysisBase.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ class AnalysisBase {
4545
getSinkConfigAt(const llvm::Instruction *Inst,
4646
const llvm::Function *Callee = nullptr) const;
4747

48+
[[nodiscard]] bool isSink(const llvm::Value *SinkCandidate,
49+
const llvm::Instruction *AtInst) const;
50+
4851
[[nodiscard]] SanitizerConfigTy
4952
getSanitizerConfigAt(const llvm::Instruction *Inst,
5053
const llvm::Function *Callee = nullptr) const;

include/phasar/PhasarLLVM/DataFlowSolver/IfdsIde/Problems/IDEExtendedTaintAnalysis.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include <type_traits>
2121
#include <unordered_map>
2222

23+
#include "llvm/ADT/STLExtras.h"
2324
#include "llvm/ADT/SmallBitVector.h"
2425
#include "llvm/IR/InstIterator.h"
2526
#include "llvm/IR/IntrinsicInst.h"
@@ -35,6 +36,7 @@
3536
#include "phasar/PhasarLLVM/DataFlowSolver/IfdsIde/Problems/ExtendedTaintAnalysis/XTaintAnalysisBase.h"
3637
#include "phasar/PhasarLLVM/DataFlowSolver/IfdsIde/Solver/IDESolver.h"
3738
#include "phasar/PhasarLLVM/Domain/AnalysisDomain.h"
39+
#include "phasar/PhasarLLVM/Pointer/PointsToInfo.h"
3840
#include "phasar/PhasarLLVM/TaintConfig/TaintConfig.h"
3941
#include "phasar/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.h"
4042
#include "phasar/PhasarLLVM/Utils/BasicBlockOrdering.h"
@@ -120,6 +122,27 @@ class IDEExtendedTaintAnalysis
120122
const llvm::Instruction *Store,
121123
unsigned PALevel = 1);
122124

125+
template <typename CallBack, typename = std::enable_if_t<std::is_invocable_v<
126+
CallBack, const llvm::Value *>>>
127+
void forEachAliasOf(PointsToInfo<v_t, n_t>::PointsToSetPtrTy PTS,
128+
const llvm::Value *Of, CallBack &&CB) {
129+
if (!HasPrecisePointsToInfo) {
130+
auto OfFF = makeFlowFact(Of);
131+
for (const auto *Alias : *PTS) {
132+
auto AliasFF = makeFlowFact(Alias);
133+
134+
if (AliasFF->base() == OfFF->base() && AliasFF != OfFF) {
135+
continue;
136+
}
137+
std::invoke(CB, Alias);
138+
}
139+
} else {
140+
for (const auto *Alias : *PTS) {
141+
std::invoke(CB, Alias);
142+
}
143+
}
144+
}
145+
123146
void populateWithMayAliases(SourceConfigTy &Facts) const;
124147

125148
bool isMustAlias(const SanitizerConfigTy &Facts, d_t CurrNod);
@@ -158,6 +181,9 @@ class IDEExtendedTaintAnalysis
158181
base_t::ZeroValue = createZeroValue();
159182

160183
FactFactory.setDataLayout(DL);
184+
185+
/// TODO: Once we have better PointsToInfo, do a dynamic_cast over PT and
186+
/// set HasPrecisePointsToInfo accordingly
161187
}
162188

163189
~IDEExtendedTaintAnalysis() override = default;
@@ -251,6 +277,8 @@ class IDEExtendedTaintAnalysis
251277

252278
bool DisableStrongUpdates = false;
253279

280+
bool HasPrecisePointsToInfo = false;
281+
254282
public:
255283
BasicBlockOrdering &getBasicBlockOrdering() { return BBO; }
256284

include/phasar/Utils/TypeTraits.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "llvm/Support/raw_ostream.h"
1818

1919
namespace psr {
20+
// NOLINTBEGIN(readability-identifier-naming)
2021
namespace detail {
2122

2223
template <typename T, typename = void>
@@ -98,6 +99,7 @@ constexpr bool is_std_hashable_v = detail::is_std_hashable<T>::value;
9899

99100
template <typename T>
100101
constexpr bool is_llvm_hashable_v = detail::is_llvm_hashable<T>::value;
102+
// NOLINTEND(readability-identifier-naming)
101103
} // namespace psr
102104

103105
#endif // PHASAR_UTILS_TYPETRAITS_H

include/phasar/Utils/Utilities.h

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,8 @@ template <class... Ts> overloaded(Ts...) -> overloaded<Ts...>;
191191
/// "https://en.cppreference.com/w/cpp/algorithm/remove" and optimized for the
192192
/// case that a sorted list of indices is given instead of an unary predicate
193193
/// specifying the elements to be removed.
194-
template <typename It, typename EndIt, typename IdxIt, typename IdxEndIt>
194+
template <typename It, typename EndIt, typename IdxIt,
195+
typename IdxEndIt> // NOLINTNEXTLINE(readability-identifier-naming)
195196
It remove_by_index(It First, EndIt Last, IdxIt FirstIndex, IdxEndIt LastIndex) {
196197
if (FirstIndex == LastIndex || First == Last) {
197198
return Last;
@@ -203,20 +204,40 @@ It remove_by_index(It First, EndIt Last, IdxIt FirstIndex, IdxEndIt LastIndex) {
203204

204205
auto CurrIdx = *FirstIndex;
205206

206-
/// TODO: Optimize this loop
207+
if constexpr (std::is_same_v<It, EndIt> &&
208+
std::is_same_v<
209+
std::random_access_iterator_tag,
210+
typename std::iterator_traits<It>::iterator_category>) {
211+
size_t GapSize = 1;
212+
auto Curr = First + 1;
213+
214+
while (++FirstIndex != LastIndex) {
215+
auto Offset = *FirstIndex - CurrIdx - 1;
216+
if (Offset >= std::distance(Curr, Last)) {
217+
break;
218+
}
219+
First = std::move(Curr, Curr + Offset, First);
220+
CurrIdx = *FirstIndex;
221+
Curr = First + ++GapSize;
222+
}
207223

208-
for (auto I = First; ++I != Last; ++CurrIdx) {
209-
if (FirstIndex == LastIndex || CurrIdx != *FirstIndex) {
210-
*First++ = std::move(*I);
211-
if (FirstIndex != LastIndex) {
212-
++FirstIndex;
224+
return std::move(Curr, Last, First);
225+
} else {
226+
227+
for (auto I = First; I != Last; ++CurrIdx, ++I) {
228+
if (CurrIdx != *FirstIndex) {
229+
*First++ = std::move(*I);
230+
if (++FirstIndex == LastIndex) {
231+
return std::move(std::next(I), Last, First);
232+
}
213233
}
214234
}
235+
return First;
215236
}
216-
return First;
217237
}
218238

219-
template <typename Container, typename IdxIt, typename IdxEndIt>
239+
template <typename Container, typename IdxIt,
240+
typename IdxEndIt> // NOLINTNEXTLINE(readability-identifier-naming)
220241
auto remove_by_index(Container &Cont, IdxIt FirstIndex, IdxEndIt LastIndex) {
221242
using std::begin;
222243
using std::end;
@@ -225,7 +246,8 @@ auto remove_by_index(Container &Cont, IdxIt FirstIndex, IdxEndIt LastIndex) {
225246
std::move(LastIndex));
226247
}
227248

228-
template <typename Container, typename Indices>
249+
template <typename Container,
250+
typename Indices> // NOLINTNEXTLINE(readability-identifier-naming)
229251
auto remove_by_index(Container &Cont, const Indices &Idx) {
230252
using std::begin;
231253
using std::end;

lib/PhasarLLVM/ControlFlow/LLVMBasedCFG.cpp

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -82,27 +82,43 @@ LLVMBasedCFG::getSuccsOf(const llvm::Instruction *I) const {
8282
std::vector<const llvm::Instruction *> Successors;
8383
// case we wish to consider LLVM's debug instructions
8484
if (!IgnoreDbgInstructions) {
85-
if (auto *NextInst = I->getNextNode()) {
85+
if (const auto *NextInst = I->getNextNode()) {
8686
return {NextInst};
8787
}
8888
} else {
89-
if (auto *NextNonDbgInst =
89+
if (const auto *NextNonDbgInst =
9090
I->getNextNonDebugInstruction(false /*Only debug instructions*/)) {
9191
Successors.push_back(NextNonDbgInst);
9292
}
9393
}
94-
if (I->isTerminator()) {
95-
Successors.reserve(I->getNumSuccessors() + Successors.size());
96-
std::transform(llvm::succ_begin(I), llvm::succ_end(I),
97-
back_inserter(Successors), [](const llvm::BasicBlock *BB) {
98-
const llvm::Instruction *Succ = &BB->front();
99-
if (llvm::isa<llvm::DbgInfoIntrinsic>(Succ)) {
100-
Succ = Succ->getNextNonDebugInstruction(
101-
false /*Only debug instructions*/);
102-
}
103-
return Succ;
104-
});
94+
95+
if (Successors.empty()) {
96+
if (const auto *Branch = llvm::dyn_cast<llvm::BranchInst>(I);
97+
Branch && isStaticVariableLazyInitializationBranch(Branch)) {
98+
// Skip the "already initialized" case, such that the analysis is always
99+
// aware of the initialized value.
100+
const llvm::Instruction *Succ = &Branch->getSuccessor(0)->front();
101+
Successors.push_back(llvm::isa<llvm::DbgInfoIntrinsic>(Succ)
102+
? Succ->getNextNonDebugInstruction(
103+
false /*Only debug instructions*/)
104+
: Succ);
105+
106+
} else {
107+
Successors.reserve(I->getNumSuccessors() + Successors.size());
108+
std::transform(llvm::succ_begin(I), llvm::succ_end(I),
109+
std::back_inserter(Successors),
110+
[](const llvm::BasicBlock *BB) {
111+
const llvm::Instruction *Succ = &BB->front();
112+
if (llvm::isa<llvm::DbgInfoIntrinsic>(Succ)) {
113+
return Succ->getNextNonDebugInstruction(
114+
false /*Only debug instructions*/);
115+
}
116+
117+
return Succ;
118+
});
119+
}
105120
}
121+
106122
return Successors;
107123
}
108124

lib/PhasarLLVM/DataFlowSolver/IfdsIde/Problems/ExtendedTaintAnalysis/AbstractMemoryLocation.cpp

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -184,14 +184,14 @@ AbstractMemoryLocation::AbstractMemoryLocation(
184184
assert(Impl);
185185
}
186186

187-
std::ostream &operator<<(std::ostream &OS, const AbstractMemoryLocation &TV) {
187+
std::ostream &operator<<(std::ostream &OS, AbstractMemoryLocation TV) {
188188
llvm::raw_os_ostream ROS(OS);
189189
ROS << TV;
190190
return OS;
191191
}
192192

193193
llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
194-
const AbstractMemoryLocation &TV) {
194+
AbstractMemoryLocation TV) {
195195
// -> Think about better representation
196196
OS << "(";
197197
if (LLVMZeroValue::getInstance()->isLLVMZeroValue(TV->base())) {
@@ -211,12 +211,9 @@ std::string DToString(const AbstractMemoryLocation &AML) {
211211
return OS.str();
212212
}
213213

214-
} // namespace psr
215-
216-
namespace llvm {
217-
llvm::hash_code hash_value(const psr::AbstractMemoryLocation &Val) {
214+
llvm::hash_code hash_value(psr::AbstractMemoryLocation Val) {
218215
return hash_combine(
219216
Val->base(), Val->lifetime() == 0,
220-
hash_combine_range(Val->offsets().begin(), Val->offsets().end()));
217+
llvm::hash_combine_range(Val->offsets().begin(), Val->offsets().end()));
221218
}
222-
} // namespace llvm
219+
} // namespace psr

0 commit comments

Comments
 (0)