17
17
#include " clang/AST/Expr.h"
18
18
#include " clang/AST/Type.h"
19
19
#include " clang/Analysis/AnalysisDeclContext.h"
20
+ #include " clang/Analysis/CFG.h"
20
21
#include " clang/Basic/LLVM.h"
21
22
#include " clang/StaticAnalyzer/Core/PathSensitive/APSIntPtr.h"
22
23
#include " clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
@@ -80,29 +81,63 @@ class SymbolRegionValue : public SymbolData {
80
81
// / A symbol representing the result of an expression in the case when we do
81
82
// / not know anything about what the expression is.
82
83
class SymbolConjured : public SymbolData {
83
- const Stmt *S ;
84
+ const CFGBlock::ConstCFGElementRef ElemRef ;
84
85
QualType T;
85
86
unsigned Count;
86
87
const LocationContext *LCtx;
87
88
const void *SymbolTag;
88
89
89
90
friend class SymExprAllocator ;
90
- SymbolConjured (SymbolID sym, const Stmt *s, const LocationContext *lctx,
91
- QualType t, unsigned count, const void *symbolTag)
92
- : SymbolData(SymbolConjuredKind, sym), S(s), T(t), Count(count),
93
- LCtx (lctx), SymbolTag(symbolTag) {
94
- // FIXME: 's' might be a nullptr if we're conducting invalidation
95
- // that was caused by a destructor call on a temporary object,
96
- // which has no statement associated with it.
97
- // Due to this, we might be creating the same invalidation symbol for
98
- // two different invalidation passes (for two different temporaries).
91
+ SymbolConjured (SymbolID sym, CFGBlock::ConstCFGElementRef elemRef,
92
+ const LocationContext *lctx, QualType t, unsigned count,
93
+ const void *symbolTag)
94
+ : SymbolData(SymbolConjuredKind, sym), ElemRef(elemRef), T(t),
95
+ Count (count), LCtx(lctx), SymbolTag(symbolTag) {
99
96
assert (lctx);
100
97
assert (isValidTypeForSymbol (t));
101
98
}
102
99
103
100
public:
104
- // / It might return null.
105
- const Stmt *getStmt () const { return S; }
101
+ const CFGBlock::ConstCFGElementRef getCFGElementRef () const {
102
+ return ElemRef;
103
+ }
104
+
105
+ // It might return null.
106
+ const Stmt *getStmt () const {
107
+ switch (ElemRef->getKind ()) {
108
+ case CFGElement::Initializer:
109
+ return ElemRef->castAs <CFGInitializer>().getInitializer ()->getInit ();
110
+ case CFGElement::ScopeBegin:
111
+ return ElemRef->castAs <CFGScopeBegin>().getTriggerStmt ();
112
+ case CFGElement::ScopeEnd:
113
+ return ElemRef->castAs <CFGScopeEnd>().getTriggerStmt ();
114
+ case CFGElement::NewAllocator:
115
+ return ElemRef->castAs <CFGNewAllocator>().getAllocatorExpr ();
116
+ case CFGElement::LifetimeEnds:
117
+ return ElemRef->castAs <CFGLifetimeEnds>().getTriggerStmt ();
118
+ case CFGElement::LoopExit:
119
+ return ElemRef->castAs <CFGLoopExit>().getLoopStmt ();
120
+ case CFGElement::Statement:
121
+ return ElemRef->castAs <CFGStmt>().getStmt ();
122
+ case CFGElement::Constructor:
123
+ return ElemRef->castAs <CFGConstructor>().getStmt ();
124
+ case CFGElement::CXXRecordTypedCall:
125
+ return ElemRef->castAs <CFGCXXRecordTypedCall>().getStmt ();
126
+ case CFGElement::AutomaticObjectDtor:
127
+ return ElemRef->castAs <CFGAutomaticObjDtor>().getTriggerStmt ();
128
+ case CFGElement::DeleteDtor:
129
+ return ElemRef->castAs <CFGDeleteDtor>().getDeleteExpr ();
130
+ case CFGElement::BaseDtor:
131
+ return nullptr ;
132
+ case CFGElement::MemberDtor:
133
+ return nullptr ;
134
+ case CFGElement::TemporaryDtor:
135
+ return ElemRef->castAs <CFGTemporaryDtor>().getBindTemporaryExpr ();
136
+ case CFGElement::CleanupFunction:
137
+ return nullptr ;
138
+ }
139
+ }
140
+
106
141
unsigned getCount () const { return Count; }
107
142
// / It might return null.
108
143
const void *getTag () const { return SymbolTag; }
@@ -113,19 +148,20 @@ class SymbolConjured : public SymbolData {
113
148
114
149
void dumpToStream (raw_ostream &os) const override ;
115
150
116
- static void Profile (llvm::FoldingSetNodeID &profile, const Stmt *S,
151
+ static void Profile (llvm::FoldingSetNodeID &profile,
152
+ const CFGBlock::ConstCFGElementRef ElemRef,
117
153
const LocationContext *LCtx, QualType T, unsigned Count,
118
154
const void *SymbolTag) {
119
155
profile.AddInteger ((unsigned )SymbolConjuredKind);
120
- profile.AddPointer (S );
156
+ profile.Add (ElemRef );
121
157
profile.AddPointer (LCtx);
122
158
profile.Add (T);
123
159
profile.AddInteger (Count);
124
160
profile.AddPointer (SymbolTag);
125
161
}
126
162
127
163
void Profile (llvm::FoldingSetNodeID& profile) override {
128
- Profile (profile, S , LCtx, T, Count, SymbolTag);
164
+ Profile (profile, ElemRef , LCtx, T, Count, SymbolTag);
129
165
}
130
166
131
167
// Implement isa<T> support.
@@ -533,18 +569,12 @@ class SymbolManager {
533
569
template <typename SymExprT, typename ... Args>
534
570
const SymExprT *acquire (Args &&...args);
535
571
536
- const SymbolConjured *conjureSymbol (const Stmt *E,
537
- const LocationContext *LCtx, QualType T,
538
- unsigned VisitCount,
539
- const void *SymbolTag = nullptr ) {
540
- return acquire<SymbolConjured>(E, LCtx, T, VisitCount, SymbolTag);
541
- }
572
+ const SymbolConjured *
573
+ conjureSymbol (const CFGBlock::ConstCFGElementRef ElemRef,
574
+ const LocationContext *LCtx, QualType T, unsigned VisitCount,
575
+ const void *SymbolTag = nullptr ) {
542
576
543
- const SymbolConjured* conjureSymbol (const Expr *E,
544
- const LocationContext *LCtx,
545
- unsigned VisitCount,
546
- const void *SymbolTag = nullptr ) {
547
- return conjureSymbol (E, LCtx, E->getType (), VisitCount, SymbolTag);
577
+ return acquire<SymbolConjured>(ElemRef, LCtx, T, VisitCount, SymbolTag);
548
578
}
549
579
550
580
QualType getType (const SymExpr *SE) const {
0 commit comments