Skip to content

Commit a106ad0

Browse files
authored
Revert "[clang][analyzer] Stable order for SymbolRef-keyed containers" (#121592)
Reverts #121551 We had a bunch of build errors caused by this PR. https://lab.llvm.org/buildbot/#/builders/144/builds/14875
1 parent 0844f83 commit a106ad0

11 files changed

+85
-149
lines changed

clang/include/clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h

Lines changed: 9 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,6 @@ namespace ento {
2525

2626
class MemRegion;
2727

28-
using SymbolID = unsigned;
29-
3028
/// Symbolic value. These values used to capture symbolic execution of
3129
/// the program.
3230
class SymExpr : public llvm::FoldingSetNode {
@@ -41,19 +39,9 @@ class SymExpr : public llvm::FoldingSetNode {
4139

4240
private:
4341
Kind K;
44-
/// A unique identifier for this symbol.
45-
///
46-
/// It is useful for SymbolData to easily differentiate multiple symbols, but
47-
/// also for "ephemeral" symbols, such as binary operations, because this id
48-
/// can be used for arranging constraints or equivalence classes instead of
49-
/// unstable pointer values.
50-
///
51-
/// Note, however, that it can't be used in Profile because SymbolManager
52-
/// needs to compute Profile before allocating SymExpr.
53-
const SymbolID Sym;
5442

5543
protected:
56-
SymExpr(Kind k, SymbolID Sym) : K(k), Sym(Sym) {}
44+
SymExpr(Kind k) : K(k) {}
5745

5846
static bool isValidTypeForSymbol(QualType T) {
5947
// FIXME: Depending on whether we choose to deprecate structural symbols,
@@ -68,14 +56,6 @@ class SymExpr : public llvm::FoldingSetNode {
6856

6957
Kind getKind() const { return K; }
7058

71-
/// Get a unique identifier for this symbol.
72-
/// The ID is unique across all SymExprs in a SymbolManager.
73-
/// They reflect the allocation order of these SymExprs,
74-
/// and are likely stable across runs.
75-
/// Used as a key in SymbolRef containers and as part of identity
76-
/// for SymbolData, e.g. SymbolConjured with ID = 7 is "conj_$7".
77-
SymbolID getSymbolID() const { return Sym; }
78-
7959
virtual void dump() const;
8060

8161
virtual void dumpToStream(raw_ostream &os) const {}
@@ -132,21 +112,28 @@ inline raw_ostream &operator<<(raw_ostream &os,
132112

133113
using SymbolRef = const SymExpr *;
134114
using SymbolRefSmallVectorTy = SmallVector<SymbolRef, 2>;
115+
using SymbolID = unsigned;
135116

136117
/// A symbol representing data which can be stored in a memory location
137118
/// (region).
138119
class SymbolData : public SymExpr {
120+
const SymbolID Sym;
121+
139122
void anchor() override;
140123

141124
protected:
142-
SymbolData(Kind k, SymbolID sym) : SymExpr(k, sym) { assert(classof(this)); }
125+
SymbolData(Kind k, SymbolID sym) : SymExpr(k), Sym(sym) {
126+
assert(classof(this));
127+
}
143128

144129
public:
145130
~SymbolData() override = default;
146131

147132
/// Get a string representation of the kind of the region.
148133
virtual StringRef getKindStr() const = 0;
149134

135+
SymbolID getSymbolID() const { return Sym; }
136+
150137
unsigned computeComplexity() const override {
151138
return 1;
152139
};

clang/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h

Lines changed: 22 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
#include "llvm/ADT/DenseMap.h"
2626
#include "llvm/ADT/DenseSet.h"
2727
#include "llvm/ADT/FoldingSet.h"
28-
#include "llvm/ADT/ImmutableSet.h"
2928
#include "llvm/ADT/iterator_range.h"
3029
#include "llvm/Support/Allocator.h"
3130
#include <cassert>
@@ -44,16 +43,15 @@ class StoreManager;
4443
class SymbolRegionValue : public SymbolData {
4544
const TypedValueRegion *R;
4645

47-
friend class SymExprAllocator;
46+
public:
4847
SymbolRegionValue(SymbolID sym, const TypedValueRegion *r)
4948
: SymbolData(SymbolRegionValueKind, sym), R(r) {
5049
assert(r);
5150
assert(isValidTypeForSymbol(r->getValueType()));
5251
}
5352

54-
public:
5553
LLVM_ATTRIBUTE_RETURNS_NONNULL
56-
const TypedValueRegion *getRegion() const { return R; }
54+
const TypedValueRegion* getRegion() const { return R; }
5755

5856
static void Profile(llvm::FoldingSetNodeID& profile, const TypedValueRegion* R) {
5957
profile.AddInteger((unsigned) SymbolRegionValueKind);
@@ -86,7 +84,7 @@ class SymbolConjured : public SymbolData {
8684
const LocationContext *LCtx;
8785
const void *SymbolTag;
8886

89-
friend class SymExprAllocator;
87+
public:
9088
SymbolConjured(SymbolID sym, const Stmt *s, const LocationContext *lctx,
9189
QualType t, unsigned count, const void *symbolTag)
9290
: SymbolData(SymbolConjuredKind, sym), S(s), T(t), Count(count),
@@ -100,7 +98,6 @@ class SymbolConjured : public SymbolData {
10098
assert(isValidTypeForSymbol(t));
10199
}
102100

103-
public:
104101
/// It might return null.
105102
const Stmt *getStmt() const { return S; }
106103
unsigned getCount() const { return Count; }
@@ -140,15 +137,14 @@ class SymbolDerived : public SymbolData {
140137
SymbolRef parentSymbol;
141138
const TypedValueRegion *R;
142139

143-
friend class SymExprAllocator;
140+
public:
144141
SymbolDerived(SymbolID sym, SymbolRef parent, const TypedValueRegion *r)
145142
: SymbolData(SymbolDerivedKind, sym), parentSymbol(parent), R(r) {
146143
assert(parent);
147144
assert(r);
148145
assert(isValidTypeForSymbol(r->getValueType()));
149146
}
150147

151-
public:
152148
LLVM_ATTRIBUTE_RETURNS_NONNULL
153149
SymbolRef getParentSymbol() const { return parentSymbol; }
154150
LLVM_ATTRIBUTE_RETURNS_NONNULL
@@ -184,13 +180,12 @@ class SymbolDerived : public SymbolData {
184180
class SymbolExtent : public SymbolData {
185181
const SubRegion *R;
186182

187-
friend class SymExprAllocator;
183+
public:
188184
SymbolExtent(SymbolID sym, const SubRegion *r)
189185
: SymbolData(SymbolExtentKind, sym), R(r) {
190186
assert(r);
191187
}
192188

193-
public:
194189
LLVM_ATTRIBUTE_RETURNS_NONNULL
195190
const SubRegion *getRegion() const { return R; }
196191

@@ -227,7 +222,7 @@ class SymbolMetadata : public SymbolData {
227222
unsigned Count;
228223
const void *Tag;
229224

230-
friend class SymExprAllocator;
225+
public:
231226
SymbolMetadata(SymbolID sym, const MemRegion* r, const Stmt *s, QualType t,
232227
const LocationContext *LCtx, unsigned count, const void *tag)
233228
: SymbolData(SymbolMetadataKind, sym), R(r), S(s), T(t), LCtx(LCtx),
@@ -239,7 +234,6 @@ class SymbolMetadata : public SymbolData {
239234
assert(tag);
240235
}
241236

242-
public:
243237
LLVM_ATTRIBUTE_RETURNS_NONNULL
244238
const MemRegion *getRegion() const { return R; }
245239

@@ -292,16 +286,15 @@ class SymbolCast : public SymExpr {
292286
/// The type of the result.
293287
QualType ToTy;
294288

295-
friend class SymExprAllocator;
296-
SymbolCast(SymbolID Sym, const SymExpr *In, QualType From, QualType To)
297-
: SymExpr(SymbolCastKind, Sym), Operand(In), FromTy(From), ToTy(To) {
289+
public:
290+
SymbolCast(const SymExpr *In, QualType From, QualType To)
291+
: SymExpr(SymbolCastKind), Operand(In), FromTy(From), ToTy(To) {
298292
assert(In);
299293
assert(isValidTypeForSymbol(From));
300294
// FIXME: GenericTaintChecker creates symbols of void type.
301295
// Otherwise, 'To' should also be a valid type.
302296
}
303297

304-
public:
305298
unsigned computeComplexity() const override {
306299
if (Complexity == 0)
307300
Complexity = 1 + Operand->computeComplexity();
@@ -339,10 +332,9 @@ class UnarySymExpr : public SymExpr {
339332
UnaryOperator::Opcode Op;
340333
QualType T;
341334

342-
friend class SymExprAllocator;
343-
UnarySymExpr(SymbolID Sym, const SymExpr *In, UnaryOperator::Opcode Op,
344-
QualType T)
345-
: SymExpr(UnarySymExprKind, Sym), Operand(In), Op(Op), T(T) {
335+
public:
336+
UnarySymExpr(const SymExpr *In, UnaryOperator::Opcode Op, QualType T)
337+
: SymExpr(UnarySymExprKind), Operand(In), Op(Op), T(T) {
346338
// Note, some unary operators are modeled as a binary operator. E.g. ++x is
347339
// modeled as x + 1.
348340
assert((Op == UO_Minus || Op == UO_Not) && "non-supported unary expression");
@@ -353,7 +345,6 @@ class UnarySymExpr : public SymExpr {
353345
assert(!Loc::isLocType(T) && "unary symbol should be nonloc");
354346
}
355347

356-
public:
357348
unsigned computeComplexity() const override {
358349
if (Complexity == 0)
359350
Complexity = 1 + Operand->computeComplexity();
@@ -390,8 +381,8 @@ class BinarySymExpr : public SymExpr {
390381
QualType T;
391382

392383
protected:
393-
BinarySymExpr(SymbolID Sym, Kind k, BinaryOperator::Opcode op, QualType t)
394-
: SymExpr(k, Sym), Op(op), T(t) {
384+
BinarySymExpr(Kind k, BinaryOperator::Opcode op, QualType t)
385+
: SymExpr(k), Op(op), T(t) {
395386
assert(classof(this));
396387
// Binary expressions are results of arithmetic. Pointer arithmetic is not
397388
// handled by binary expressions, but it is instead handled by applying
@@ -434,15 +425,14 @@ class BinarySymExprImpl : public BinarySymExpr {
434425
LHSTYPE LHS;
435426
RHSTYPE RHS;
436427

437-
friend class SymExprAllocator;
438-
BinarySymExprImpl(SymbolID Sym, LHSTYPE lhs, BinaryOperator::Opcode op,
439-
RHSTYPE rhs, QualType t)
440-
: BinarySymExpr(Sym, ClassKind, op, t), LHS(lhs), RHS(rhs) {
428+
public:
429+
BinarySymExprImpl(LHSTYPE lhs, BinaryOperator::Opcode op, RHSTYPE rhs,
430+
QualType t)
431+
: BinarySymExpr(ClassKind, op, t), LHS(lhs), RHS(rhs) {
441432
assert(getPointer(lhs));
442433
assert(getPointer(rhs));
443434
}
444435

445-
public:
446436
void dumpToStream(raw_ostream &os) const override {
447437
dumpToStreamImpl(os, LHS);
448438
dumpToStreamImpl(os, getOpcode());
@@ -488,21 +478,6 @@ using IntSymExpr = BinarySymExprImpl<APSIntPtr, const SymExpr *,
488478
using SymSymExpr = BinarySymExprImpl<const SymExpr *, const SymExpr *,
489479
SymExpr::Kind::SymSymExprKind>;
490480

491-
class SymExprAllocator {
492-
SymbolID NextSymbolID = 0;
493-
llvm::BumpPtrAllocator &Alloc;
494-
495-
public:
496-
explicit SymExprAllocator(llvm::BumpPtrAllocator &Alloc) : Alloc(Alloc) {}
497-
498-
template <class SymT, typename... ArgsT> SymT *make(ArgsT &&...Args) {
499-
return new (Alloc) SymT(nextID(), std::forward<ArgsT>(Args)...);
500-
}
501-
502-
private:
503-
SymbolID nextID() { return NextSymbolID++; }
504-
};
505-
506481
class SymbolManager {
507482
using DataSetTy = llvm::FoldingSet<SymExpr>;
508483
using SymbolDependTy =
@@ -514,14 +489,15 @@ class SymbolManager {
514489
/// alive as long as the key is live.
515490
SymbolDependTy SymbolDependencies;
516491

517-
SymExprAllocator Alloc;
492+
unsigned SymbolCounter = 0;
493+
llvm::BumpPtrAllocator& BPAlloc;
518494
BasicValueFactory &BV;
519495
ASTContext &Ctx;
520496

521497
public:
522498
SymbolManager(ASTContext &ctx, BasicValueFactory &bv,
523-
llvm::BumpPtrAllocator &bpalloc)
524-
: SymbolDependencies(16), Alloc(bpalloc), BV(bv), Ctx(ctx) {}
499+
llvm::BumpPtrAllocator& bpalloc)
500+
: SymbolDependencies(16), BPAlloc(bpalloc), BV(bv), Ctx(ctx) {}
525501

526502
static bool canSymbolicate(QualType T);
527503

@@ -711,36 +687,4 @@ class SymbolVisitor {
711687

712688
} // namespace clang
713689

714-
// Override the default definition that would use pointer values of SymbolRefs
715-
// to order them, which is unstable due to ASLR.
716-
// Use the SymbolID instead which reflect the order in which the symbols were
717-
// allocated. This is usually stable across runs leading to the stability of
718-
// ConstraintMap and other containers using SymbolRef as keys.
719-
template <>
720-
struct ::llvm::ImutContainerInfo<clang::ento::SymbolRef>
721-
: public ImutProfileInfo<clang::ento::SymbolRef> {
722-
using value_type = clang::ento::SymbolRef;
723-
using value_type_ref = clang::ento::SymbolRef;
724-
using key_type = value_type;
725-
using key_type_ref = value_type_ref;
726-
using data_type = bool;
727-
using data_type_ref = bool;
728-
729-
static key_type_ref KeyOfValue(value_type_ref D) { return D; }
730-
static data_type_ref DataOfValue(value_type_ref) { return true; }
731-
732-
static bool isEqual(clang::ento::SymbolRef LHS, clang::ento::SymbolRef RHS) {
733-
return LHS->getSymbolID() == RHS->getSymbolID();
734-
}
735-
736-
static bool isLess(clang::ento::SymbolRef LHS, clang::ento::SymbolRef RHS) {
737-
return LHS->getSymbolID() < RHS->getSymbolID();
738-
}
739-
740-
// This might seem redundant, but it is required because of the way
741-
// ImmutableSet is implemented through AVLTree:
742-
// same as ImmutableMap, but with a non-informative "data".
743-
static bool isDataEqual(data_type_ref, data_type_ref) { return true; }
744-
};
745-
746690
#endif // LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SYMBOLMANAGER_H

0 commit comments

Comments
 (0)