clang: include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SYMBOLMANAGER_H
15#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SYMBOLMANAGER_H
16
25#include "llvm/ADT/DenseMap.h"
26#include "llvm/ADT/DenseSet.h"
27#include "llvm/ADT/FoldingSet.h"
28#include "llvm/ADT/ImmutableSet.h"
29#include "llvm/ADT/iterator_range.h"
30#include "llvm/Support/Allocator.h"
31#include
32
34
35class ASTContext;
36class Stmt;
37
38namespace ento {
39
40class BasicValueFactory;
41class StoreManager;
42
43
46
49 : SymbolData(SymbolRegionValueKind, sym), R(r) {
50 assert(r);
52 }
53
54public:
55 LLVM_ATTRIBUTE_RETURNS_NONNULL
57
59 profile.AddInteger((unsigned) SymbolRegionValueKind);
60 profile.AddPointer(R);
61 }
62
63 void Profile(llvm::FoldingSetNodeID& profile) override {
65 }
66
67 StringRef getKindStr() const override;
68
69 void dumpToStream(raw_ostream &os) const override;
71
73
74
76 return SE->getKind() == SymbolRegionValueKind;
77 }
78};
79
80
81
83 const Stmt *S;
85 unsigned Count;
87 const void *SymbolTag;
88
91 QualType t, unsigned count, const void *symbolTag)
92 : SymbolData(SymbolConjuredKind, sym), S(s), T(t), Count(count),
93 LCtx(lctx), SymbolTag(symbolTag) {
94
95
96
97
98
99 assert(lctx);
101 }
102
103public:
104
106 unsigned getCount() const { return Count; }
107
108 const void *getTag() const { return SymbolTag; }
109
111
112 StringRef getKindStr() const override;
113
114 void dumpToStream(raw_ostream &os) const override;
115
116 static void Profile(llvm::FoldingSetNodeID &profile, const Stmt *S,
118 const void *SymbolTag) {
119 profile.AddInteger((unsigned)SymbolConjuredKind);
120 profile.AddPointer(S);
121 profile.AddPointer(LCtx);
122 profile.Add(T);
123 profile.AddInteger(Count);
124 profile.AddPointer(SymbolTag);
125 }
126
127 void Profile(llvm::FoldingSetNodeID& profile) override {
128 Profile(profile, S, LCtx, T, Count, SymbolTag);
129 }
130
131
133 return SE->getKind() == SymbolConjuredKind;
134 }
135};
136
137
138
142
145 : SymbolData(SymbolDerivedKind, sym), parentSymbol(parent), R(r) {
146 assert(parent);
147 assert(r);
149 }
150
151public:
152 LLVM_ATTRIBUTE_RETURNS_NONNULL
154 LLVM_ATTRIBUTE_RETURNS_NONNULL
156
158
159 StringRef getKindStr() const override;
160
161 void dumpToStream(raw_ostream &os) const override;
163
166 profile.AddInteger((unsigned) SymbolDerivedKind);
167 profile.AddPointer(r);
168 profile.AddPointer(parent);
169 }
170
171 void Profile(llvm::FoldingSetNodeID& profile) override {
172 Profile(profile, parentSymbol, R);
173 }
174
175
177 return SE->getKind() == SymbolDerivedKind;
178 }
179};
180
181
182
183
186
189 : SymbolData(SymbolExtentKind, sym), R(r) {
190 assert(r);
191 }
192
193public:
194 LLVM_ATTRIBUTE_RETURNS_NONNULL
196
198
199 StringRef getKindStr() const override;
200
201 void dumpToStream(raw_ostream &os) const override;
202
203 static void Profile(llvm::FoldingSetNodeID& profile, const SubRegion *R) {
204 profile.AddInteger((unsigned) SymbolExtentKind);
205 profile.AddPointer(R);
206 }
207
208 void Profile(llvm::FoldingSetNodeID& profile) override {
210 }
211
212
214 return SE->getKind() == SymbolExtentKind;
215 }
216};
217
218
219
220
221
224 const Stmt *S;
227
228
229 unsigned Count;
230 const void *Tag;
231
234 const LocationContext *LCtx, unsigned count, const void *tag)
235 : SymbolData(SymbolMetadataKind, sym), R(r), S(s), T(t), LCtx(LCtx),
236 Count(count), Tag(tag) {
237 assert(r);
238 assert(s);
240 assert(LCtx);
241 assert(tag);
242 }
243
244 public:
245 LLVM_ATTRIBUTE_RETURNS_NONNULL
247
248 LLVM_ATTRIBUTE_RETURNS_NONNULL
250
251 LLVM_ATTRIBUTE_RETURNS_NONNULL
253
254 unsigned getCount() const { return Count; }
255
256 LLVM_ATTRIBUTE_RETURNS_NONNULL
257 const void *getTag() const { return Tag; }
258
260
261 StringRef getKindStr() const override;
262
263 void dumpToStream(raw_ostream &os) const override;
264
267 unsigned Count, const void *Tag) {
268 profile.AddInteger((unsigned)SymbolMetadataKind);
269 profile.AddPointer(R);
270 profile.AddPointer(S);
271 profile.Add(T);
272 profile.AddPointer(LCtx);
273 profile.AddInteger(Count);
274 profile.AddPointer(Tag);
275 }
276
277 void Profile(llvm::FoldingSetNodeID& profile) override {
278 Profile(profile, R, S, T, LCtx, Count, Tag);
279 }
280
281
283 return SE->getKind() == SymbolMetadataKind;
284 }
285};
286
287
290
291
293
294
296
299 : SymExpr(SymbolCastKind, Sym), Operand(In), FromTy(From), ToTy(To) {
300 assert(In);
302
303
304 }
305
306public:
309 Complexity = 1 + Operand->computeComplexity();
311 }
312
314
315 LLVM_ATTRIBUTE_RETURNS_NONNULL
317
318 void dumpToStream(raw_ostream &os) const override;
319
320 static void Profile(llvm::FoldingSetNodeID& ID,
322 ID.AddInteger((unsigned) SymbolCastKind);
323 ID.AddPointer(In);
324 ID.Add(From);
325 ID.Add(To);
326 }
327
328 void Profile(llvm::FoldingSetNodeID& ID) override {
329 Profile(ID, Operand, FromTy, ToTy);
330 }
331
332
334 return SE->getKind() == SymbolCastKind;
335 }
336};
337
338
343
347 : SymExpr(UnarySymExprKind, Sym), Operand(In), Op(Op), T(T) {
348
349
350 assert((Op == UO_Minus || Op == UO_Not) && "non-supported unary expression");
351
352
353
355 assert((T) && "unary symbol should be nonloc");
356 }
357
358public:
361 Complexity = 1 + Operand->computeComplexity();
363 }
364
368
369 void dumpToStream(raw_ostream &os) const override;
370
373 ID.AddInteger((unsigned)UnarySymExprKind);
374 ID.AddPointer(In);
375 ID.AddInteger(Op);
377 }
378
379 void Profile(llvm::FoldingSetNodeID &ID) override {
381 }
382
383
385 return SE->getKind() == UnarySymExprKind;
386 }
387};
388
389
393
394protected:
396 : SymExpr(k, Sym), Op(op), T(t) {
398
399
400
402 }
403
404public:
405
406
408
410
411
414 return k >= BEGIN_BINARYSYMEXPRS && k <= END_BINARYSYMEXPRS;
415 }
416
417protected:
419 return Value->computeComplexity();
420 }
422 return 1;
423 }
424
427
431};
432
433
434template <class LHSTYPE, class RHSTYPE, SymExpr::Kind ClassKind>
436 LHSTYPE LHS;
437 RHSTYPE RHS;
438
442 : BinarySymExpr(Sym, ClassKind, op, t), LHS(lhs), RHS(rhs) {
445 }
446
447public:
452 }
453
454 LHSTYPE getLHS() const { return LHS; }
455 RHSTYPE getRHS() const { return RHS; }
456
462 }
463
464 static void Profile(llvm::FoldingSetNodeID &ID, LHSTYPE lhs,
466 ID.AddInteger((unsigned)ClassKind);
468 ID.AddInteger(op);
470 ID.Add(t);
471 }
472
473 void Profile(llvm::FoldingSetNodeID &ID) override {
475 }
476
477
479};
480
481
483 SymExpr::Kind::SymIntExprKind>;
484
485
487 SymExpr::Kind::IntSymExprKind>;
488
489
491 SymExpr::Kind::SymSymExprKind>;
492
495 llvm::BumpPtrAllocator &Alloc;
496
497public:
498 explicit SymExprAllocator(llvm::BumpPtrAllocator &Alloc) : Alloc(Alloc) {}
499
500 template <class SymT, typename... ArgsT> SymT *make(ArgsT &&...Args) {
501 return new (Alloc) SymT(nextID(), std::forward(Args)...);
502 }
503
504private:
505 SymbolID nextID() { return NextSymbolID++; }
506};
507
509 using DataSetTy = llvm::FoldingSet;
510 using SymbolDependTy =
511 llvm::DenseMap<SymbolRef, std::unique_ptr>;
512
513 DataSetTy DataSet;
514
515
516
517 SymbolDependTy SymbolDependencies;
518
522
523public:
525 llvm::BumpPtrAllocator &bpalloc)
526 : SymbolDependencies(16), Alloc(bpalloc), BV(bv), Ctx(ctx) {}
527
529
530
531
532
533 template <typename SymExprT, typename... Args>
534 const SymExprT *acquire(Args &&...args);
535
539 const void *SymbolTag = nullptr) {
540 return acquire(E, LCtx, T, VisitCount, SymbolTag);
541 }
542
546 const void *SymbolTag = nullptr) {
548 }
549
552 }
553
554
555
556
558
560
563};
564
565
567 enum SymbolStatus {
568 NotProcessed,
569 HaveMarkedDependents
570 };
571
572 using SymbolSetTy = llvm::DenseSet;
573 using SymbolMapTy = llvm::DenseMap<SymbolRef, SymbolStatus>;
574 using RegionSetTy = llvm::DenseSet<const MemRegion *>;
575
576 SymbolMapTy TheLiving;
577 SymbolSetTy MetadataInUse;
578
579 RegionSetTy LiveRegionRoots;
580
581
582
583
584 RegionSetTy LazilyCopiedRegionRoots;
585
590 llvm::DenseMap<const MemRegion *, unsigned> includedRegionCache;
591
592public:
593
594
595
596
597
598
599
602 : LCtx(Ctx), Loc(s), SymMgr(symmgr), reapedStore(nullptr, storeMgr) {}
603
604
606
610 bool isLive(const VarRegion *VR, bool includeStoreBindings = false) const;
611
612
613
614
615
616
618
619
620
621
622
623
624
625
627
628 llvm::iterator_rangeRegionSetTy::const\_iterator regions() const {
629 return LiveRegionRoots;
630 }
631
632
633
634
635
638 }
639
643
644
645
647
648private:
649 bool isLazilyCopiedRegion(const MemRegion *region) const;
650
651
652
653 bool isReadableRegion(const MemRegion *region);
654
655
656 void markDependentsLive(SymbolRef sym);
657};
658
660protected:
662
663public:
667
668
669
672
673
674
675
676
679};
680
681template <typename T, typename... Args>
683 llvm::FoldingSetNodeID profile;
684 T::Profile(profile, args...);
685 void *InsertPos;
686 SymExpr *SD = DataSet.FindNodeOrInsertPos(profile, InsertPos);
687 if (!SD) {
688 SD = Alloc.make<T>(std::forward(args)...);
689 DataSet.InsertNode(SD, InsertPos);
690 }
691 return cast(SD);
692}
693
694}
695
696}
697
698
699
700
701
702
703template <>
704struct llvm::ImutContainerInfo<clang::ento::SymbolRef>
712
715
718 }
719
722 }
723
724
725
726
728};
729
730#endif
This file defines AnalysisDeclContext, a class that manages the analysis context data for context sen...
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
llvm::DenseMap< const CFGBlock *, unsigned > VisitCount
C Language Family Type Representation.
__device__ __2f16 float __ockl_bool s
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
This represents one expression.
It wraps the AnalysisDeclContext to represent both the call stack with the help of StackFrameContext ...
A (possibly-)qualified type.
It represents a stack frame of the call stack (based on CallEvent).
Stmt - This represents one statement.
A safe wrapper around APSInt objects allocated and owned by BasicValueFactory.
Template implementation for all binary symbolic expressions.
static void Profile(llvm::FoldingSetNodeID &ID, LHSTYPE lhs, BinaryOperator::Opcode op, RHSTYPE rhs, QualType t)
void Profile(llvm::FoldingSetNodeID &ID) override
void dumpToStream(raw_ostream &os) const override
unsigned computeComplexity() const override
static bool classof(const SymExpr *SE)
Represents a symbolic expression involving a binary operator.
QualType getType() const override
BinaryOperator::Opcode getOpcode() const
static unsigned computeOperandComplexity(const SymExpr *Value)
static void dumpToStreamImpl(raw_ostream &os, const SymExpr *Value)
static bool classof(const SymExpr *SE)
static unsigned computeOperandComplexity(const llvm::APSInt &Value)
BinarySymExpr(SymbolID Sym, Kind k, BinaryOperator::Opcode op, QualType t)
static const llvm::APSInt * getPointer(APSIntPtr Value)
static const SymExpr * getPointer(const SymExpr *Value)
static bool isLocType(QualType T)
MemRegion - The root abstract class for all memory regions.
SubRegion - A region that subsets another larger region.
SymT * make(ArgsT &&...Args)
SymExprAllocator(llvm::BumpPtrAllocator &Alloc)
static bool isValidTypeForSymbol(QualType T)
virtual QualType getType() const =0
SymbolID getSymbolID() const
Get a unique identifier for this symbol.
Represents a cast expression.
static bool classof(const SymExpr *SE)
static void Profile(llvm::FoldingSetNodeID &ID, const SymExpr *In, QualType From, QualType To)
QualType getType() const override
void Profile(llvm::FoldingSetNodeID &ID) override
void dumpToStream(raw_ostream &os) const override
LLVM_ATTRIBUTE_RETURNS_NONNULL const SymExpr * getOperand() const
unsigned computeComplexity() const override
A symbol representing the result of an expression in the case when we do not know anything about what...
void Profile(llvm::FoldingSetNodeID &profile) override
unsigned getCount() const
static bool classof(const SymExpr *SE)
StringRef getKindStr() const override
Get a string representation of the kind of the region.
static void Profile(llvm::FoldingSetNodeID &profile, const Stmt *S, const LocationContext *LCtx, QualType T, unsigned Count, const void *SymbolTag)
const void * getTag() const
It might return null.
void dumpToStream(raw_ostream &os) const override
QualType getType() const override
const Stmt * getStmt() const
It might return null.
A symbol representing data which can be stored in a memory location (region).
A symbol representing the value of a MemRegion whose parent region has symbolic value.
LLVM_ATTRIBUTE_RETURNS_NONNULL SymbolRef getParentSymbol() const
StringRef getKindStr() const override
Get a string representation of the kind of the region.
void dumpToStream(raw_ostream &os) const override
const MemRegion * getOriginRegion() const override
Find the region from which this symbol originates.
static void Profile(llvm::FoldingSetNodeID &profile, SymbolRef parent, const TypedValueRegion *r)
void Profile(llvm::FoldingSetNodeID &profile) override
QualType getType() const override
LLVM_ATTRIBUTE_RETURNS_NONNULL const TypedValueRegion * getRegion() const
static bool classof(const SymExpr *SE)
SymbolExtent - Represents the extent (size in bytes) of a bounded region.
static bool classof(const SymExpr *SE)
LLVM_ATTRIBUTE_RETURNS_NONNULL const SubRegion * getRegion() const
void dumpToStream(raw_ostream &os) const override
QualType getType() const override
static void Profile(llvm::FoldingSetNodeID &profile, const SubRegion *R)
StringRef getKindStr() const override
Get a string representation of the kind of the region.
void Profile(llvm::FoldingSetNodeID &profile) override
SymbolManager(ASTContext &ctx, BasicValueFactory &bv, llvm::BumpPtrAllocator &bpalloc)
const SymExprT * acquire(Args &&...args)
Create or retrieve a SymExpr of type SymExprT for the given arguments.
const SymbolConjured * conjureSymbol(const Stmt *E, const LocationContext *LCtx, QualType T, unsigned VisitCount, const void *SymbolTag=nullptr)
void addSymbolDependency(const SymbolRef Primary, const SymbolRef Dependent)
Add artificial symbol dependency.
BasicValueFactory & getBasicVals()
QualType getType(const SymExpr *SE) const
const SymbolConjured * conjureSymbol(const Expr *E, const LocationContext *LCtx, unsigned VisitCount, const void *SymbolTag=nullptr)
const SymbolRefSmallVectorTy * getDependentSymbols(const SymbolRef Primary)
static bool canSymbolicate(QualType T)
ASTContext & getContext()
A class responsible for cleaning up unused symbols.
void markLive(SymbolRef sym)
Unconditionally marks a symbol as live.
void markElementIndicesLive(const MemRegion *region)
SymbolReaper(const StackFrameContext *Ctx, const Stmt *s, SymbolManager &symmgr, StoreManager &storeMgr)
Construct a reaper object, which removes everything which is not live before we execute statement s i...
bool isDead(SymbolRef sym)
Returns whether or not a symbol has been confirmed dead.
void markInUse(SymbolRef sym)
Marks a symbol as important to a checker.
bool isLiveRegion(const MemRegion *region)
void markLazilyCopied(const MemRegion *region)
const LocationContext * getLocationContext() const
It might return null.
void setReapedStore(StoreRef st)
Set to the value of the symbolic store after StoreManager::removeDeadBindings has been called.
bool isLive(SymbolRef sym)
llvm::iterator_range< RegionSetTy::const_iterator > regions() const
A symbol representing the value stored at a MemRegion.
void dumpToStream(raw_ostream &os) const override
const MemRegion * getOriginRegion() const override
Find the region from which this symbol originates.
void Profile(llvm::FoldingSetNodeID &profile) override
LLVM_ATTRIBUTE_RETURNS_NONNULL const TypedValueRegion * getRegion() const
static void Profile(llvm::FoldingSetNodeID &profile, const TypedValueRegion *R)
QualType getType() const override
StringRef getKindStr() const override
Get a string representation of the kind of the region.
static bool classof(const SymExpr *SE)
virtual bool VisitMemRegion(const MemRegion *)
SymbolVisitor(const SymbolVisitor &)=default
SymbolVisitor(SymbolVisitor &&)
SymbolVisitor & operator=(SymbolVisitor &&)=delete
SymbolVisitor & operator=(const SymbolVisitor &)=delete
virtual bool VisitSymbol(SymbolRef sym)=0
A visitor method invoked by ProgramStateManager::scanReachableSymbols.
TypedValueRegion - An abstract class representing regions having a typed value.
virtual QualType getValueType() const =0
Represents a symbolic expression involving a unary operator.
void dumpToStream(raw_ostream &os) const override
void Profile(llvm::FoldingSetNodeID &ID) override
QualType getType() const override
static bool classof(const SymExpr *SE)
UnaryOperator::Opcode getOpcode() const
unsigned computeComplexity() const override
static void Profile(llvm::FoldingSetNodeID &ID, const SymExpr *In, UnaryOperator::Opcode Op, QualType T)
const SymExpr * getOperand() const
const SymExpr * SymbolRef
The JSON file list parser is used to communicate input to InstallAPI.
const FunctionProtoType * T
static key_type_ref KeyOfValue(value_type_ref D)
static data_type_ref DataOfValue(value_type_ref)
static bool isEqual(clang::ento::SymbolRef LHS, clang::ento::SymbolRef RHS)
static bool isLess(clang::ento::SymbolRef LHS, clang::ento::SymbolRef RHS)
static bool isDataEqual(data_type_ref, data_type_ref)