clang: lib/StaticAnalyzer/Core/ExprEngineObjC.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
17
18using namespace clang;
19using namespace ento;
20
26 SVal baseVal = state->getSVal(Ex->getBase(), LCtx);
27 SVal location = state->getLValue(Ex->getDecl(), baseVal);
28
31 Bldr.generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, location));
32
33
34
36}
37
43
44
45
51
55
58
60 if (const auto *R = dyn_cast(MV->getRegion())) {
61
62
63
66
68 if (hasElements) {
72 } else {
74 }
75
76 nextState = nextState->bindLoc(elementV, V, LCtx);
77 }
78
80 }
81}
82
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
116
117 SVal elementV;
118 if (const auto *DS = dyn_cast(elem)) {
120 assert(elemD->getInit() == nullptr);
122 } else {
124 }
125
126 bool isContainerNull = state->isNull(collectionV).isConstrainedTrue();
127
128 ExplodedNodeSet DstLocation;
129 evalLocation(DstLocation, S, elem, Pred, state, elementV, false);
130
131 for (ExplodedNode *dstLocation : DstLocation) {
134
135 if (!isContainerNull)
137 elemRef, elementV, SymMgr, currBldrCtx,
138 Bldr,
139 true);
140
142 elementV, SymMgr, currBldrCtx, Bldr,
143 false);
144
145
146
148 }
149}
150
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200 if (Msg->isInstanceMessage()) {
201 SVal recVal = Msg->getReceiverSVal();
203
207
209 std::tie(notNilState, nilState) = State->assume(receiverVal);
210
211
212 if (nilState && !notNilState) {
216 Pred = Bldr.generateNode(ME, Pred, nilState, nullptr,
218 assert((Pred || HasTag) && "Should have cached out already!");
219 (void)HasTag;
220 if (!Pred)
221 return;
222
225 *Msg, *this);
226 for (auto *I : dstPostCheckers)
227 finishArgumentConstruction(Dst, I, *Msg);
228 return;
229 }
230
233
234
235 if (notNilState != State) {
237 Pred = Bldr.generateNode(ME, Pred, notNilState);
238 assert((Pred || HasTag) && "Should have cached out already!");
239 (void)HasTag;
240 if (!Pred)
241 return;
242 }
243 }
244 }
245
246
249 *Msg, *this);
252 *Msg, *this);
253
254
256 StmtNodeBuilder Bldr(dstGenericPrevisit, dstEval, *currBldrCtx);
257
259 DE = dstGenericPrevisit.end(); DI != DE; ++DI) {
263
264 if (UpdatedMsg->isInstanceMessage()) {
265 SVal recVal = UpdatedMsg->getReceiverSVal();
267 if (ObjCNoRet.isImplicitNoReturn(ME)) {
268
269
271 continue;
272 }
273 }
274 } else {
275
276
277 if (ObjCNoRet.isImplicitNoReturn(ME)) {
278
279
281 continue;
282 }
283 }
284
286 }
287
288
290 for (auto *I : dstEval)
291 finishArgumentConstruction(dstArgCleanup, I, *Msg);
292
295 *Msg, *this);
296
297
298
300 *Msg, *this);
301}
static void populateObjCForDestinationSet(ExplodedNodeSet &dstLocation, SValBuilder &svalBuilder, const ObjCForCollectionStmt *S, ConstCFGElementRef elem, SVal elementV, SymbolManager &SymMgr, const NodeBuilderContext *currBldrCtx, StmtNodeBuilder &Bldr, bool hasElements)
Generate a node in Bldr for an iteration statement using ObjC for-loop iterator.
Definition ExprEngineObjC.cpp:46
Defines the Objective-C statement AST node classes.
It wraps the AnalysisDeclContext to represent both the call stack with the help of StackFrameContext ...
Represents Objective-C's @synchronized statement.
Represents Objective-C's collection statement.
ObjCIvarRefExpr - A reference to an ObjC instance variable.
const Expr * getBase() const
An expression that sends a message to the given Objective-C object or class.
const ProgramPointTag * getTag() const
A (possibly-)qualified type.
Stmt - This represents one statement.
Represents a variable declaration or definition.
const Expr * getInit() const
Manages the lifetime of CallEvent objects.
CallEventRef< ObjCMethodCall > getObjCMethodCall(const ObjCMessageExpr *E, ProgramStateRef State, const LocationContext *LCtx, CFGBlock::ConstCFGElementRef ElemRef)
CallEventRef< T > cloneWithState(ProgramStateRef State) const
void runCheckersForPreObjCMessage(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const ObjCMethodCall &msg, ExprEngine &Eng)
Run checkers for pre-visiting obj-c messages.
void runCheckersForPreCall(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const CallEvent &Call, ExprEngine &Eng)
Run checkers for pre-visiting obj-c messages.
void runCheckersForPostObjCMessage(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const ObjCMethodCall &msg, ExprEngine &Eng, bool wasInlined=false)
Run checkers for post-visiting obj-c messages.
void runCheckersForPostStmt(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const Stmt *S, ExprEngine &Eng, bool wasInlined=false)
Run checkers for post-visiting Stmts.
void runCheckersForPreStmt(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const Stmt *S, ExprEngine &Eng)
Run checkers for pre-visiting Stmts.
void runCheckersForObjCMessageNil(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const ObjCMethodCall &msg, ExprEngine &Eng)
Run checkers for visiting an obj-c message to nil.
void runCheckersForPostCall(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const CallEvent &Call, ExprEngine &Eng, bool wasInlined=false)
Run checkers for post-visiting obj-c messages.
ImplTy::iterator iterator
const ProgramStateRef & getState() const
ProgramPoint getLocation() const
getLocation - Returns the edge associated with the given node.
const LocationContext * getLocationContext() const
ProgramStateManager & getStateManager()
void VisitObjCMessage(const ObjCMessageExpr *ME, ExplodedNode *Pred, ExplodedNodeSet &Dst)
Definition ExprEngineObjC.cpp:151
void VisitObjCAtSynchronizedStmt(const ObjCAtSynchronizedStmt *S, ExplodedNode *Pred, ExplodedNodeSet &Dst)
Transfer function logic for ObjCAtSynchronizedStmts.
Definition ExprEngineObjC.cpp:38
void VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitObjCForCollectionStmt - Transfer function logic for ObjCForCollectionStmt.
Definition ExprEngineObjC.cpp:83
void VisitLvalObjCIvarRefExpr(const ObjCIvarRefExpr *DR, ExplodedNode *Pred, ExplodedNodeSet &Dst)
Transfer function logic for computing the lvalue of an Objective-C ivar.
Definition ExprEngineObjC.cpp:21
ConstCFGElementRef getCFGElementRef() const
CheckerManager & getCheckerManager() const
void defaultEvalCall(NodeBuilder &B, ExplodedNode *Pred, const CallEvent &Call, const EvalCallOptions &CallOpts={})
Default implementation of call evaluation.
static ProgramStateRef setWhetherHasMoreIteration(ProgramStateRef State, const ObjCForCollectionStmt *O, const LocationContext *LC, bool HasMoreIteraton)
Note whether this loop has any more iterations to model. These methods.
static bool isLocType(QualType T)
unsigned blockCount() const
Returns the number of times the current basic block has been visited on the exploded graph path.
CallEventManager & getCallEventManager()
nonloc::ConcreteInt makeIntVal(const IntegerLiteral *integer)
loc::MemRegionVal makeLoc(SymbolRef sym)
SVal - This represents a symbolic expression, which can be either an L-value or an R-value.
std::optional< T > getAs() const
Convert to the specified SVal type, returning std::nullopt if this SVal is not of the desired type.
T castAs() const
Convert to the specified SVal type, asserting that this SVal is of the desired type.
This builder class is useful for generating nodes that resulted from visiting a statement.
ExplodedNode * generateNode(const Stmt *S, ExplodedNode *Pred, ProgramStateRef St, const ProgramPointTag *tag=nullptr, ProgramPoint::Kind K=ProgramPoint::PostStmtKind)
ExplodedNode * generateSink(const Stmt *S, ExplodedNode *Pred, ProgramStateRef St, const ProgramPointTag *tag=nullptr, ProgramPoint::Kind K=ProgramPoint::PostStmtKind)
const SymbolConjured * conjureSymbol(ConstCFGElementRef Elem, const LocationContext *LCtx, QualType T, unsigned VisitCount, const void *SymbolTag=nullptr)
IntrusiveRefCntPtr< const ProgramState > ProgramStateRef
const SymExpr * SymbolRef
The JSON file list parser is used to communicate input to InstallAPI.
CFGBlock::ConstCFGElementRef ConstCFGElementRef
const FunctionProtoType * T
U cast(CodeGen::Address addr)