Skip to content

Commit a5ae39c

Browse files
[analyzer] Enforce not making overly complicated symbols
Out of the worst 500 entry points, 45 were improved by at least 10%. Out of these 45, 5 were improved by more than 50%. Out of these 45, 2 were improved by more than 80%. For example, for the `DelugeFirmware/src/OSLikeStuff/fault_handler/fault_handler.c` TU: - `printPointers` entry point was improved from 31.1 seconds to 1.1 second (28x). - `handle_cpu_fault` entry point was improved from 15.5 seconds to 3 seconds (5x). We had in total 3'037'085 entry points in the test pool. Out of these 390'156 were measured to run over a second. TODO: Add the plot here about RT. CPP-6182
1 parent 7efc861 commit a5ae39c

File tree

12 files changed

+298
-153
lines changed

12 files changed

+298
-153
lines changed

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

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ class SValBuilder {
5757
protected:
5858
ASTContext &Context;
5959

60+
const AnalyzerOptions &AnOpts;
61+
6062
/// Manager of APSInt values.
6163
BasicValueFactory BasicVals;
6264

@@ -68,8 +70,6 @@ class SValBuilder {
6870

6971
ProgramStateManager &StateMgr;
7072

71-
const AnalyzerOptions &AnOpts;
72-
7373
/// The scalar type to use for array indices.
7474
const QualType ArrayIndexTy;
7575

@@ -317,21 +317,21 @@ class SValBuilder {
317317
return nonloc::LocAsInteger(BasicVals.getPersistentSValWithData(loc, bits));
318318
}
319319

320-
nonloc::SymbolVal makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op,
321-
APSIntPtr rhs, QualType type);
320+
DefinedOrUnknownSVal makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op,
321+
APSIntPtr rhs, QualType type);
322322

323-
nonloc::SymbolVal makeNonLoc(APSIntPtr rhs, BinaryOperator::Opcode op,
324-
const SymExpr *lhs, QualType type);
323+
DefinedOrUnknownSVal makeNonLoc(APSIntPtr rhs, BinaryOperator::Opcode op,
324+
const SymExpr *lhs, QualType type);
325325

326-
nonloc::SymbolVal makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op,
327-
const SymExpr *rhs, QualType type);
326+
DefinedOrUnknownSVal makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op,
327+
const SymExpr *rhs, QualType type);
328328

329-
NonLoc makeNonLoc(const SymExpr *operand, UnaryOperator::Opcode op,
330-
QualType type);
329+
DefinedOrUnknownSVal makeNonLoc(const SymExpr *operand,
330+
UnaryOperator::Opcode op, QualType type);
331331

332332
/// Create a NonLoc value for cast.
333-
nonloc::SymbolVal makeNonLoc(const SymExpr *operand, QualType fromTy,
334-
QualType toTy);
333+
DefinedOrUnknownSVal makeNonLoc(const SymExpr *operand, QualType fromTy,
334+
QualType toTy);
335335

336336
nonloc::ConcreteInt makeTruthVal(bool b, QualType type) {
337337
return nonloc::ConcreteInt(BasicVals.getTruthValue(b, type));

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

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -51,18 +51,18 @@ class SymExpr : public llvm::FoldingSetNode {
5151
/// Note, however, that it can't be used in Profile because SymbolManager
5252
/// needs to compute Profile before allocating SymExpr.
5353
const SymbolID Sym;
54+
const unsigned Complexity;
5455

5556
protected:
56-
SymExpr(Kind k, SymbolID Sym) : K(k), Sym(Sym) {}
57+
SymExpr(Kind k, SymbolID Sym, unsigned Complexity)
58+
: K(k), Sym(Sym), Complexity(Complexity) {}
5759

5860
static bool isValidTypeForSymbol(QualType T) {
5961
// FIXME: Depending on whether we choose to deprecate structural symbols,
6062
// this may become much stricter.
6163
return !T.isNull() && !T->isVoidType();
6264
}
6365

64-
mutable unsigned Complexity = 0;
65-
6666
public:
6767
virtual ~SymExpr() = default;
6868

@@ -108,7 +108,7 @@ class SymExpr : public llvm::FoldingSetNode {
108108
return llvm::make_range(symbol_iterator(this), symbol_iterator());
109109
}
110110

111-
virtual unsigned computeComplexity() const = 0;
111+
unsigned complexity() const { return Complexity; }
112112

113113
/// Find the region from which this symbol originates.
114114
///
@@ -136,25 +136,26 @@ using SymbolRefSmallVectorTy = SmallVector<SymbolRef, 2>;
136136
/// A symbol representing data which can be stored in a memory location
137137
/// (region).
138138
class SymbolData : public SymExpr {
139+
friend class SymbolManager;
139140
void anchor() override;
140141

141142
protected:
142-
SymbolData(Kind k, SymbolID sym) : SymExpr(k, sym) { assert(classof(this)); }
143+
SymbolData(Kind k, SymbolID sym) : SymExpr(k, sym, computeComplexity()) {
144+
assert(classof(this));
145+
}
146+
147+
static unsigned computeComplexity(...) { return 1; }
143148

144149
public:
145150
~SymbolData() override = default;
146151

147152
/// Get a string representation of the kind of the region.
148153
virtual StringRef getKindStr() const = 0;
149154

150-
unsigned computeComplexity() const override {
151-
return 1;
152-
};
153-
154155
// Implement isa<T> support.
155-
static inline bool classof(const SymExpr *SE) {
156-
Kind k = SE->getKind();
157-
return k >= BEGIN_SYMBOLS && k <= END_SYMBOLS;
156+
static bool classof(const SymExpr *SE) { return classof(SE->getKind()); }
157+
static constexpr bool classof(Kind K) {
158+
return K >= BEGIN_SYMBOLS && K <= END_SYMBOLS;
158159
}
159160
};
160161

0 commit comments

Comments
 (0)