/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/StaticAnalyzer/Core/CallEvent.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===- CallEvent.cpp - Wrapper for all function and method calls ----------===// |
2 | | // |
3 | | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | | // See https://llvm.org/LICENSE.txt for license information. |
5 | | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | | // |
7 | | //===----------------------------------------------------------------------===// |
8 | | // |
9 | | /// \file This file defines CallEvent and its subclasses, which represent path- |
10 | | /// sensitive instances of different kinds of function and method calls |
11 | | /// (C, C++, and Objective-C). |
12 | | // |
13 | | //===----------------------------------------------------------------------===// |
14 | | |
15 | | #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" |
16 | | #include "clang/AST/ASTContext.h" |
17 | | #include "clang/AST/Attr.h" |
18 | | #include "clang/AST/Decl.h" |
19 | | #include "clang/AST/DeclBase.h" |
20 | | #include "clang/AST/DeclCXX.h" |
21 | | #include "clang/AST/DeclObjC.h" |
22 | | #include "clang/AST/Expr.h" |
23 | | #include "clang/AST/ExprCXX.h" |
24 | | #include "clang/AST/ExprObjC.h" |
25 | | #include "clang/AST/ParentMap.h" |
26 | | #include "clang/AST/Stmt.h" |
27 | | #include "clang/AST/Type.h" |
28 | | #include "clang/Analysis/AnalysisDeclContext.h" |
29 | | #include "clang/Analysis/CFG.h" |
30 | | #include "clang/Analysis/CFGStmtMap.h" |
31 | | #include "clang/Analysis/PathDiagnostic.h" |
32 | | #include "clang/Analysis/ProgramPoint.h" |
33 | | #include "clang/Basic/IdentifierTable.h" |
34 | | #include "clang/Basic/LLVM.h" |
35 | | #include "clang/Basic/SourceLocation.h" |
36 | | #include "clang/Basic/SourceManager.h" |
37 | | #include "clang/Basic/Specifiers.h" |
38 | | #include "clang/CrossTU/CrossTranslationUnit.h" |
39 | | #include "clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h" |
40 | | #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" |
41 | | #include "clang/StaticAnalyzer/Core/PathSensitive/DynamicType.h" |
42 | | #include "clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeInfo.h" |
43 | | #include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h" |
44 | | #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h" |
45 | | #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h" |
46 | | #include "clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h" |
47 | | #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h" |
48 | | #include "clang/StaticAnalyzer/Core/PathSensitive/Store.h" |
49 | | #include "llvm/ADT/ArrayRef.h" |
50 | | #include "llvm/ADT/DenseMap.h" |
51 | | #include "llvm/ADT/ImmutableList.h" |
52 | | #include "llvm/ADT/PointerIntPair.h" |
53 | | #include "llvm/ADT/SmallSet.h" |
54 | | #include "llvm/ADT/SmallVector.h" |
55 | | #include "llvm/ADT/StringExtras.h" |
56 | | #include "llvm/ADT/StringRef.h" |
57 | | #include "llvm/Support/Casting.h" |
58 | | #include "llvm/Support/Compiler.h" |
59 | | #include "llvm/Support/Debug.h" |
60 | | #include "llvm/Support/ErrorHandling.h" |
61 | | #include "llvm/Support/raw_ostream.h" |
62 | | #include <cassert> |
63 | | #include <optional> |
64 | | #include <utility> |
65 | | |
66 | | #define DEBUG_TYPE "static-analyzer-call-event" |
67 | | |
68 | | using namespace clang; |
69 | | using namespace ento; |
70 | | |
71 | 56.6k | QualType CallEvent::getResultType() const { |
72 | 56.6k | ASTContext &Ctx = getState()->getStateManager().getContext(); |
73 | 56.6k | const Expr *E = getOriginExpr(); |
74 | 56.6k | if (!E) |
75 | 4 | return Ctx.VoidTy; |
76 | 56.6k | return Ctx.getReferenceQualifiedType(E); |
77 | 56.6k | } |
78 | | |
79 | 32.1k | static bool isCallback(QualType T) { |
80 | | // If a parameter is a block or a callback, assume it can modify pointer. |
81 | 32.1k | if (T->isBlockPointerType() || |
82 | 32.1k | T->isFunctionPointerType()31.9k || |
83 | 32.1k | T->isObjCSelType()31.9k ) |
84 | 270 | return true; |
85 | | |
86 | | // Check if a callback is passed inside a struct (for both, struct passed by |
87 | | // reference and by value). Dig just one level into the struct for now. |
88 | | |
89 | 31.8k | if (T->isAnyPointerType() || T->isReferenceType()19.3k ) |
90 | 15.3k | T = T->getPointeeType(); |
91 | | |
92 | 31.8k | if (const RecordType *RT = T->getAsStructureType()) { |
93 | 14.5k | const RecordDecl *RD = RT->getDecl(); |
94 | 15.1k | for (const auto *I : RD->fields()) { |
95 | 15.1k | QualType FieldT = I->getType(); |
96 | 15.1k | if (FieldT->isBlockPointerType() || FieldT->isFunctionPointerType()) |
97 | 9 | return true; |
98 | 15.1k | } |
99 | 14.5k | } |
100 | 31.8k | return false; |
101 | 31.8k | } |
102 | | |
103 | 27.3k | static bool isVoidPointerToNonConst(QualType T) { |
104 | 27.3k | if (const auto *PT = T->getAs<PointerType>()) { |
105 | 9.68k | QualType PointeeTy = PT->getPointeeType(); |
106 | 9.68k | if (PointeeTy.isConstQualified()) |
107 | 4.55k | return false; |
108 | 5.13k | return PointeeTy->isVoidType(); |
109 | 9.68k | } else |
110 | 17.6k | return false; |
111 | 27.3k | } |
112 | | |
113 | 71.4k | bool CallEvent::hasNonNullArgumentsWithType(bool (*Condition)(QualType)) const { |
114 | 71.4k | unsigned NumOfArgs = getNumArgs(); |
115 | | |
116 | | // If calling using a function pointer, assume the function does not |
117 | | // satisfy the callback. |
118 | | // TODO: We could check the types of the arguments here. |
119 | 71.4k | if (!getDecl()) |
120 | 103 | return false; |
121 | | |
122 | 71.3k | unsigned Idx = 0; |
123 | 71.3k | for (CallEvent::param_type_iterator I = param_type_begin(), |
124 | 71.3k | E = param_type_end(); |
125 | 132k | I != E && Idx < NumOfArgs62.8k ; ++I, ++Idx60.9k ) { |
126 | | // If the parameter is 0, it's harmless. |
127 | 62.8k | if (getArgSVal(Idx).isZeroConstant()) |
128 | 3.38k | continue; |
129 | | |
130 | 59.4k | if (Condition(*I)) |
131 | 1.86k | return true; |
132 | 59.4k | } |
133 | 69.5k | return false; |
134 | 71.3k | } |
135 | | |
136 | 39.9k | bool CallEvent::hasNonZeroCallbackArg() const { |
137 | 39.9k | return hasNonNullArgumentsWithType(isCallback); |
138 | 39.9k | } |
139 | | |
140 | 31.5k | bool CallEvent::hasVoidPointerToNonConstArg() const { |
141 | 31.5k | return hasNonNullArgumentsWithType(isVoidPointerToNonConst); |
142 | 31.5k | } |
143 | | |
144 | 125k | bool CallEvent::isGlobalCFunction(StringRef FunctionName) const { |
145 | 125k | const auto *FD = dyn_cast_or_null<FunctionDecl>(getDecl()); |
146 | 125k | if (!FD) |
147 | 7.38k | return false; |
148 | | |
149 | 118k | return CheckerContext::isCLibraryFunction(FD, FunctionName); |
150 | 125k | } |
151 | | |
152 | 34.7k | AnalysisDeclContext *CallEvent::getCalleeAnalysisDeclContext() const { |
153 | 34.7k | const Decl *D = getDecl(); |
154 | 34.7k | if (!D) |
155 | 0 | return nullptr; |
156 | | |
157 | 34.7k | AnalysisDeclContext *ADC = |
158 | 34.7k | LCtx->getAnalysisDeclContext()->getManager()->getContext(D); |
159 | | |
160 | 34.7k | return ADC; |
161 | 34.7k | } |
162 | | |
163 | | const StackFrameContext * |
164 | 34.7k | CallEvent::getCalleeStackFrame(unsigned BlockCount) const { |
165 | 34.7k | AnalysisDeclContext *ADC = getCalleeAnalysisDeclContext(); |
166 | 34.7k | if (!ADC) |
167 | 0 | return nullptr; |
168 | | |
169 | 34.7k | const Expr *E = getOriginExpr(); |
170 | 34.7k | if (!E) |
171 | 0 | return nullptr; |
172 | | |
173 | | // Recover CFG block via reverse lookup. |
174 | | // TODO: If we were to keep CFG element information as part of the CallEvent |
175 | | // instead of doing this reverse lookup, we would be able to build the stack |
176 | | // frame for non-expression-based calls, and also we wouldn't need the reverse |
177 | | // lookup. |
178 | 34.7k | CFGStmtMap *Map = LCtx->getAnalysisDeclContext()->getCFGStmtMap(); |
179 | 34.7k | const CFGBlock *B = Map->getBlock(E); |
180 | 34.7k | assert(B); |
181 | | |
182 | | // Also recover CFG index by scanning the CFG block. |
183 | 34.7k | unsigned Idx = 0, Sz = B->size(); |
184 | 470k | for (; Idx < Sz; ++Idx435k ) |
185 | 470k | if (auto StmtElem = (*B)[Idx].getAs<CFGStmt>()) |
186 | 470k | if (StmtElem->getStmt() == E) |
187 | 34.7k | break; |
188 | 34.7k | assert(Idx < Sz); |
189 | | |
190 | 34.7k | return ADC->getManager()->getStackFrame(ADC, LCtx, E, B, BlockCount, Idx); |
191 | 34.7k | } |
192 | | |
193 | | const ParamVarRegion |
194 | 20.9k | *CallEvent::getParameterLocation(unsigned Index, unsigned BlockCount) const { |
195 | 20.9k | const StackFrameContext *SFC = getCalleeStackFrame(BlockCount); |
196 | | // We cannot construct a VarRegion without a stack frame. |
197 | 20.9k | if (!SFC) |
198 | 0 | return nullptr; |
199 | | |
200 | 20.9k | const ParamVarRegion *PVR = |
201 | 20.9k | State->getStateManager().getRegionManager().getParamVarRegion( |
202 | 20.9k | getOriginExpr(), Index, SFC); |
203 | 20.9k | return PVR; |
204 | 20.9k | } |
205 | | |
206 | | /// Returns true if a type is a pointer-to-const or reference-to-const |
207 | | /// with no further indirection. |
208 | 27.6k | static bool isPointerToConst(QualType Ty) { |
209 | 27.6k | QualType PointeeTy = Ty->getPointeeType(); |
210 | 27.6k | if (PointeeTy == QualType()) |
211 | 15.4k | return false; |
212 | 12.1k | if (!PointeeTy.isConstQualified()) |
213 | 5.35k | return false; |
214 | 6.81k | if (PointeeTy->isAnyPointerType()) |
215 | 43 | return false; |
216 | 6.76k | return true; |
217 | 6.81k | } |
218 | | |
219 | | // Try to retrieve the function declaration and find the function parameter |
220 | | // types which are pointers/references to a non-pointer const. |
221 | | // We will not invalidate the corresponding argument regions. |
222 | | static void findPtrToConstParams(llvm::SmallSet<unsigned, 4> &PreserveArgs, |
223 | 33.4k | const CallEvent &Call) { |
224 | 33.4k | unsigned Idx = 0; |
225 | 33.4k | for (CallEvent::param_type_iterator I = Call.param_type_begin(), |
226 | 33.4k | E = Call.param_type_end(); |
227 | 61.0k | I != E; ++I, ++Idx27.6k ) { |
228 | 27.6k | if (isPointerToConst(*I)) |
229 | 6.76k | PreserveArgs.insert(Idx); |
230 | 27.6k | } |
231 | 33.4k | } |
232 | | |
233 | | ProgramStateRef CallEvent::invalidateRegions(unsigned BlockCount, |
234 | 35.4k | ProgramStateRef Orig) const { |
235 | 35.4k | ProgramStateRef Result = (Orig ? Orig35.4k : getState()7 ); |
236 | | |
237 | | // Don't invalidate anything if the callee is marked pure/const. |
238 | 35.4k | if (const Decl *callee = getDecl()) |
239 | 35.3k | if (callee->hasAttr<PureAttr>() || callee->hasAttr<ConstAttr>()35.2k ) |
240 | 90 | return Result; |
241 | | |
242 | 35.3k | SmallVector<SVal, 8> ValuesToInvalidate; |
243 | 35.3k | RegionAndSymbolInvalidationTraits ETraits; |
244 | | |
245 | 35.3k | getExtraInvalidatedValues(ValuesToInvalidate, &ETraits); |
246 | | |
247 | | // Indexes of arguments whose values will be preserved by the call. |
248 | 35.3k | llvm::SmallSet<unsigned, 4> PreserveArgs; |
249 | 35.3k | if (!argumentsMayEscape()) |
250 | 33.4k | findPtrToConstParams(PreserveArgs, *this); |
251 | | |
252 | 67.5k | for (unsigned Idx = 0, Count = getNumArgs(); Idx != Count; ++Idx32.2k ) { |
253 | | // Mark this region for invalidation. We batch invalidate regions |
254 | | // below for efficiency. |
255 | 32.2k | if (PreserveArgs.count(Idx)) |
256 | 6.76k | if (const MemRegion *MR = getArgSVal(Idx).getAsRegion()) |
257 | 6.45k | ETraits.setTrait(MR->getBaseRegion(), |
258 | 6.45k | RegionAndSymbolInvalidationTraits::TK_PreserveContents); |
259 | | // TODO: Factor this out + handle the lower level const pointers. |
260 | | |
261 | 32.2k | ValuesToInvalidate.push_back(getArgSVal(Idx)); |
262 | | |
263 | | // If a function accepts an object by argument (which would of course be a |
264 | | // temporary that isn't lifetime-extended), invalidate the object itself, |
265 | | // not only other objects reachable from it. This is necessary because the |
266 | | // destructor has access to the temporary object after the call. |
267 | | // TODO: Support placement arguments once we start |
268 | | // constructing them directly. |
269 | | // TODO: This is unnecessary when there's no destructor, but that's |
270 | | // currently hard to figure out. |
271 | 32.2k | if (getKind() != CE_CXXAllocator) |
272 | 31.3k | if (isArgumentConstructedDirectly(Idx)) |
273 | 9.91k | if (auto AdjIdx = getAdjustedParameterIndex(Idx)) |
274 | 9.91k | if (const TypedValueRegion *TVR = |
275 | 9.91k | getParameterLocation(*AdjIdx, BlockCount)) |
276 | 9.91k | ValuesToInvalidate.push_back(loc::MemRegionVal(TVR)); |
277 | 32.2k | } |
278 | | |
279 | | // Invalidate designated regions using the batch invalidation API. |
280 | | // NOTE: Even if RegionsToInvalidate is empty, we may still invalidate |
281 | | // global variables. |
282 | 35.3k | return Result->invalidateRegions(ValuesToInvalidate, getOriginExpr(), |
283 | 35.3k | BlockCount, getLocationContext(), |
284 | 35.3k | /*CausedByPointerEscape*/ true, |
285 | 35.3k | /*Symbols=*/nullptr, this, &ETraits); |
286 | 35.4k | } |
287 | | |
288 | | ProgramPoint CallEvent::getProgramPoint(bool IsPreVisit, |
289 | 1.11M | const ProgramPointTag *Tag) const { |
290 | | |
291 | 1.11M | if (const Expr *E = getOriginExpr()) { |
292 | 1.10M | if (IsPreVisit) |
293 | 665k | return PreStmt(E, getLocationContext(), Tag); |
294 | 437k | return PostStmt(E, getLocationContext(), Tag); |
295 | 1.10M | } |
296 | | |
297 | 16.8k | const Decl *D = getDecl(); |
298 | 16.8k | assert(D && "Cannot get a program point without a statement or decl"); |
299 | 16.8k | assert(ElemRef.getParent() && |
300 | 16.8k | "Cannot get a program point without a CFGElementRef"); |
301 | | |
302 | 16.8k | SourceLocation Loc = getSourceRange().getBegin(); |
303 | 16.8k | if (IsPreVisit) |
304 | 10.9k | return PreImplicitCall(D, Loc, getLocationContext(), ElemRef, Tag); |
305 | 5.93k | return PostImplicitCall(D, Loc, getLocationContext(), ElemRef, Tag); |
306 | 16.8k | } |
307 | | |
308 | 339k | SVal CallEvent::getArgSVal(unsigned Index) const { |
309 | 339k | const Expr *ArgE = getArgExpr(Index); |
310 | 339k | if (!ArgE) |
311 | 4.64k | return UnknownVal(); |
312 | 335k | return getSVal(ArgE); |
313 | 339k | } |
314 | | |
315 | 90.4k | SourceRange CallEvent::getArgSourceRange(unsigned Index) const { |
316 | 90.4k | const Expr *ArgE = getArgExpr(Index); |
317 | 90.4k | if (!ArgE) |
318 | 1.04k | return {}; |
319 | 89.3k | return ArgE->getSourceRange(); |
320 | 90.4k | } |
321 | | |
322 | 32.1k | SVal CallEvent::getReturnValue() const { |
323 | 32.1k | const Expr *E = getOriginExpr(); |
324 | 32.1k | if (!E) |
325 | 13 | return UndefinedVal(); |
326 | 32.1k | return getSVal(E); |
327 | 32.1k | } |
328 | | |
329 | 0 | LLVM_DUMP_METHOD void CallEvent::dump() const { dump(llvm::errs()); } |
330 | | |
331 | 16 | void CallEvent::dump(raw_ostream &Out) const { |
332 | 16 | ASTContext &Ctx = getState()->getStateManager().getContext(); |
333 | 16 | if (const Expr *E = getOriginExpr()) { |
334 | 16 | E->printPretty(Out, nullptr, Ctx.getPrintingPolicy()); |
335 | 16 | return; |
336 | 16 | } |
337 | | |
338 | 0 | if (const Decl *D = getDecl()) { |
339 | 0 | Out << "Call to "; |
340 | 0 | D->print(Out, Ctx.getPrintingPolicy()); |
341 | 0 | return; |
342 | 0 | } |
343 | | |
344 | 0 | Out << "Unknown call (type " << getKindAsString() << ")"; |
345 | 0 | } |
346 | | |
347 | 1.73M | bool CallEvent::isCallStmt(const Stmt *S) { |
348 | 1.73M | return isa<CallExpr, ObjCMessageExpr, CXXConstructExpr, CXXNewExpr>(S); |
349 | 1.73M | } |
350 | | |
351 | 20.3k | QualType CallEvent::getDeclaredResultType(const Decl *D) { |
352 | 20.3k | assert(D); |
353 | 20.3k | if (const auto *FD = dyn_cast<FunctionDecl>(D)) |
354 | 19.2k | return FD->getReturnType(); |
355 | 1.06k | if (const auto *MD = dyn_cast<ObjCMethodDecl>(D)) |
356 | 1.02k | return MD->getReturnType(); |
357 | 36 | if (const auto *BD = dyn_cast<BlockDecl>(D)) { |
358 | | // Blocks are difficult because the return type may not be stored in the |
359 | | // BlockDecl itself. The AST should probably be enhanced, but for now we |
360 | | // just do what we can. |
361 | | // If the block is declared without an explicit argument list, the |
362 | | // signature-as-written just includes the return type, not the entire |
363 | | // function type. |
364 | | // FIXME: All blocks should have signatures-as-written, even if the return |
365 | | // type is inferred. (That's signified with a dependent result type.) |
366 | 36 | if (const TypeSourceInfo *TSI = BD->getSignatureAsWritten()) { |
367 | 32 | QualType Ty = TSI->getType(); |
368 | 32 | if (const FunctionType *FT = Ty->getAs<FunctionType>()) |
369 | 28 | Ty = FT->getReturnType(); |
370 | 32 | if (!Ty->isDependentType()) |
371 | 15 | return Ty; |
372 | 32 | } |
373 | | |
374 | 21 | return {}; |
375 | 36 | } |
376 | | |
377 | 0 | llvm_unreachable("unknown callable kind"); |
378 | 0 | } |
379 | | |
380 | 17.0k | bool CallEvent::isVariadic(const Decl *D) { |
381 | 17.0k | assert(D); |
382 | | |
383 | 17.0k | if (const auto *FD = dyn_cast<FunctionDecl>(D)) |
384 | 16.1k | return FD->isVariadic(); |
385 | 912 | if (const auto *MD = dyn_cast<ObjCMethodDecl>(D)) |
386 | 774 | return MD->isVariadic(); |
387 | 138 | if (const auto *BD = dyn_cast<BlockDecl>(D)) |
388 | 138 | return BD->isVariadic(); |
389 | | |
390 | 0 | llvm_unreachable("unknown callable kind"); |
391 | 0 | } |
392 | | |
393 | 23.1k | static bool isTransparentUnion(QualType T) { |
394 | 23.1k | const RecordType *UT = T->getAsUnionType(); |
395 | 23.1k | return UT && UT->getDecl()->hasAttr<TransparentUnionAttr>()4 ; |
396 | 23.1k | } |
397 | | |
398 | | // In some cases, symbolic cases should be transformed before we associate |
399 | | // them with parameters. This function incapsulates such cases. |
400 | | static SVal processArgument(SVal Value, const Expr *ArgumentExpr, |
401 | 23.1k | const ParmVarDecl *Parameter, SValBuilder &SVB) { |
402 | 23.1k | QualType ParamType = Parameter->getType(); |
403 | 23.1k | QualType ArgumentType = ArgumentExpr->getType(); |
404 | | |
405 | | // Transparent unions allow users to easily convert values of union field |
406 | | // types into union-typed objects. |
407 | | // |
408 | | // Also, more importantly, they allow users to define functions with different |
409 | | // different parameter types, substituting types matching transparent union |
410 | | // field types with the union type itself. |
411 | | // |
412 | | // Here, we check specifically for latter cases and prevent binding |
413 | | // field-typed values to union-typed regions. |
414 | 23.1k | if (isTransparentUnion(ParamType) && |
415 | | // Let's check that we indeed trying to bind different types. |
416 | 23.1k | !isTransparentUnion(ArgumentType)3 ) { |
417 | 2 | BasicValueFactory &BVF = SVB.getBasicValueFactory(); |
418 | | |
419 | 2 | llvm::ImmutableList<SVal> CompoundSVals = BVF.getEmptySValList(); |
420 | 2 | CompoundSVals = BVF.prependSVal(Value, CompoundSVals); |
421 | | |
422 | | // Wrap it with compound value. |
423 | 2 | return SVB.makeCompoundVal(ParamType, CompoundSVals); |
424 | 2 | } |
425 | | |
426 | 23.1k | return Value; |
427 | 23.1k | } |
428 | | |
429 | | /// Cast the argument value to the type of the parameter at the function |
430 | | /// declaration. |
431 | | /// Returns the argument value if it didn't need a cast. |
432 | | /// Or returns the cast argument if it needed a cast. |
433 | | /// Or returns 'Unknown' if it would need a cast but the callsite and the |
434 | | /// runtime definition don't match in terms of argument and parameter count. |
435 | | static SVal castArgToParamTypeIfNeeded(const CallEvent &Call, unsigned ArgIdx, |
436 | 23.1k | SVal ArgVal, SValBuilder &SVB) { |
437 | 23.1k | const FunctionDecl *RTDecl = |
438 | 23.1k | Call.getRuntimeDefinition().getDecl()->getAsFunction(); |
439 | 23.1k | const auto *CallExprDecl = dyn_cast_or_null<FunctionDecl>(Call.getDecl()); |
440 | | |
441 | 23.1k | if (!RTDecl || !CallExprDecl22.9k ) |
442 | 147 | return ArgVal; |
443 | | |
444 | | // The function decl of the Call (in the AST) will not have any parameter |
445 | | // declarations, if it was 'only' declared without a prototype. However, the |
446 | | // engine will find the appropriate runtime definition - basically a |
447 | | // redeclaration, which has a function body (and a function prototype). |
448 | 22.9k | if (CallExprDecl->hasPrototype() || !RTDecl->hasPrototype()6 ) |
449 | 22.9k | return ArgVal; |
450 | | |
451 | | // Only do this cast if the number arguments at the callsite matches with |
452 | | // the parameters at the runtime definition. |
453 | 6 | if (Call.getNumArgs() != RTDecl->getNumParams()) |
454 | 1 | return UnknownVal(); |
455 | | |
456 | 5 | const Expr *ArgExpr = Call.getArgExpr(ArgIdx); |
457 | 5 | const ParmVarDecl *Param = RTDecl->getParamDecl(ArgIdx); |
458 | 5 | return SVB.evalCast(ArgVal, Param->getType(), ArgExpr->getType()); |
459 | 6 | } |
460 | | |
461 | | static void addParameterValuesToBindings(const StackFrameContext *CalleeCtx, |
462 | | CallEvent::BindingsTy &Bindings, |
463 | | SValBuilder &SVB, |
464 | | const CallEvent &Call, |
465 | 35.1k | ArrayRef<ParmVarDecl*> parameters) { |
466 | 35.1k | MemRegionManager &MRMgr = SVB.getRegionManager(); |
467 | | |
468 | | // If the function has fewer parameters than the call has arguments, we simply |
469 | | // do not bind any values to them. |
470 | 35.1k | unsigned NumArgs = Call.getNumArgs(); |
471 | 35.1k | unsigned Idx = 0; |
472 | 35.1k | ArrayRef<ParmVarDecl*>::iterator I = parameters.begin(), E = parameters.end(); |
473 | 61.2k | for (; I != E && Idx < NumArgs26.0k ; ++I, ++Idx26.0k ) { |
474 | 26.0k | assert(*I && "Formal parameter has no decl?"); |
475 | | |
476 | | // TODO: Support allocator calls. |
477 | 26.0k | if (Call.getKind() != CE_CXXAllocator) |
478 | 25.6k | if (Call.isArgumentConstructedDirectly(Call.getASTArgumentIndex(Idx))) |
479 | 962 | continue; |
480 | | |
481 | | // TODO: Allocators should receive the correct size and possibly alignment, |
482 | | // determined in compile-time but not represented as arg-expressions, |
483 | | // which makes getArgSVal() fail and return UnknownVal. |
484 | 25.0k | SVal ArgVal = Call.getArgSVal(Idx); |
485 | 25.0k | const Expr *ArgExpr = Call.getArgExpr(Idx); |
486 | | |
487 | 25.0k | if (ArgVal.isUnknown()) |
488 | 1.94k | continue; |
489 | | |
490 | | // Cast the argument value to match the type of the parameter in some |
491 | | // edge-cases. |
492 | 23.1k | ArgVal = castArgToParamTypeIfNeeded(Call, Idx, ArgVal, SVB); |
493 | | |
494 | 23.1k | Loc ParamLoc = SVB.makeLoc( |
495 | 23.1k | MRMgr.getParamVarRegion(Call.getOriginExpr(), Idx, CalleeCtx)); |
496 | 23.1k | Bindings.push_back( |
497 | 23.1k | std::make_pair(ParamLoc, processArgument(ArgVal, ArgExpr, *I, SVB))); |
498 | 23.1k | } |
499 | | |
500 | | // FIXME: Variadic arguments are not handled at all right now. |
501 | 35.1k | } |
502 | | |
503 | 22 | const ConstructionContext *CallEvent::getConstructionContext() const { |
504 | 22 | const StackFrameContext *StackFrame = getCalleeStackFrame(0); |
505 | 22 | if (!StackFrame) |
506 | 0 | return nullptr; |
507 | | |
508 | 22 | const CFGElement Element = StackFrame->getCallSiteCFGElement(); |
509 | 22 | if (const auto Ctor = Element.getAs<CFGConstructor>()) { |
510 | 9 | return Ctor->getConstructionContext(); |
511 | 9 | } |
512 | | |
513 | 13 | if (const auto RecCall = Element.getAs<CFGCXXRecordTypedCall>()) { |
514 | 13 | return RecCall->getConstructionContext(); |
515 | 13 | } |
516 | | |
517 | 0 | return nullptr; |
518 | 13 | } |
519 | | |
520 | 17 | std::optional<SVal> CallEvent::getReturnValueUnderConstruction() const { |
521 | 17 | const auto *CC = getConstructionContext(); |
522 | 17 | if (!CC) |
523 | 0 | return std::nullopt; |
524 | | |
525 | 17 | EvalCallOptions CallOpts; |
526 | 17 | ExprEngine &Engine = getState()->getStateManager().getOwningEngine(); |
527 | 17 | SVal RetVal = Engine.computeObjectUnderConstruction( |
528 | 17 | getOriginExpr(), getState(), &Engine.getBuilderContext(), |
529 | 17 | getLocationContext(), CC, CallOpts); |
530 | 17 | return RetVal; |
531 | 17 | } |
532 | | |
533 | 3.14M | ArrayRef<ParmVarDecl*> AnyFunctionCall::parameters() const { |
534 | 3.14M | const FunctionDecl *D = getDecl(); |
535 | 3.14M | if (!D) |
536 | 35 | return std::nullopt; |
537 | 3.14M | return D->parameters(); |
538 | 3.14M | } |
539 | | |
540 | 88.9k | RuntimeDefinition AnyFunctionCall::getRuntimeDefinition() const { |
541 | 88.9k | const FunctionDecl *FD = getDecl(); |
542 | 88.9k | if (!FD) |
543 | 34 | return {}; |
544 | | |
545 | | // Note that the AnalysisDeclContext will have the FunctionDecl with |
546 | | // the definition (if one exists). |
547 | 88.8k | AnalysisDeclContext *AD = |
548 | 88.8k | getLocationContext()->getAnalysisDeclContext()-> |
549 | 88.8k | getManager()->getContext(FD); |
550 | 88.8k | bool IsAutosynthesized; |
551 | 88.8k | Stmt* Body = AD->getBody(IsAutosynthesized); |
552 | 88.8k | LLVM_DEBUG({ |
553 | 88.8k | if (IsAutosynthesized) |
554 | 88.8k | llvm::dbgs() << "Using autosynthesized body for " << FD->getName() |
555 | 88.8k | << "\n"; |
556 | 88.8k | }); |
557 | | |
558 | 88.8k | ExprEngine &Engine = getState()->getStateManager().getOwningEngine(); |
559 | 88.8k | cross_tu::CrossTranslationUnitContext &CTUCtx = |
560 | 88.8k | *Engine.getCrossTranslationUnitContext(); |
561 | | |
562 | 88.8k | AnalyzerOptions &Opts = Engine.getAnalysisManager().options; |
563 | | |
564 | 88.8k | if (Body) { |
565 | 60.0k | const Decl* Decl = AD->getDecl(); |
566 | 60.0k | if (Opts.IsNaiveCTUEnabled && CTUCtx.isImportedAsNew(Decl)210 ) { |
567 | | // A newly created definition, but we had error(s) during the import. |
568 | 168 | if (CTUCtx.hasError(Decl)) |
569 | 0 | return {}; |
570 | 168 | return RuntimeDefinition(Decl, /*Foreign=*/true); |
571 | 168 | } |
572 | 59.8k | return RuntimeDefinition(Decl, /*Foreign=*/false); |
573 | 60.0k | } |
574 | | |
575 | | // Try to get CTU definition only if CTUDir is provided. |
576 | 28.8k | if (!Opts.IsNaiveCTUEnabled) |
577 | 28.7k | return {}; |
578 | | |
579 | 98 | llvm::Expected<const FunctionDecl *> CTUDeclOrError = |
580 | 98 | CTUCtx.getCrossTUDefinition(FD, Opts.CTUDir, Opts.CTUIndexName, |
581 | 98 | Opts.DisplayCTUProgress); |
582 | | |
583 | 98 | if (!CTUDeclOrError) { |
584 | 16 | handleAllErrors(CTUDeclOrError.takeError(), |
585 | 16 | [&](const cross_tu::IndexError &IE) { |
586 | 16 | CTUCtx.emitCrossTUDiagnostics(IE); |
587 | 16 | }); |
588 | 16 | return {}; |
589 | 16 | } |
590 | | |
591 | 82 | return RuntimeDefinition(*CTUDeclOrError, /*Foreign=*/true); |
592 | 98 | } |
593 | | |
594 | | void AnyFunctionCall::getInitialStackFrameContents( |
595 | | const StackFrameContext *CalleeCtx, |
596 | 34.4k | BindingsTy &Bindings) const { |
597 | 34.4k | const auto *D = cast<FunctionDecl>(CalleeCtx->getDecl()); |
598 | 34.4k | SValBuilder &SVB = getState()->getStateManager().getSValBuilder(); |
599 | 34.4k | addParameterValuesToBindings(CalleeCtx, Bindings, SVB, *this, |
600 | 34.4k | D->parameters()); |
601 | 34.4k | } |
602 | | |
603 | 31.7k | bool AnyFunctionCall::argumentsMayEscape() const { |
604 | 31.7k | if (CallEvent::argumentsMayEscape() || hasVoidPointerToNonConstArg()31.5k ) |
605 | 1.75k | return true; |
606 | | |
607 | 29.9k | const FunctionDecl *D = getDecl(); |
608 | 29.9k | if (!D) |
609 | 36 | return true; |
610 | | |
611 | 29.9k | const IdentifierInfo *II = D->getIdentifier(); |
612 | 29.9k | if (!II) |
613 | 4.31k | return false; |
614 | | |
615 | | // This set of "escaping" APIs is |
616 | | |
617 | | // - 'int pthread_setspecific(ptheread_key k, const void *)' stores a |
618 | | // value into thread local storage. The value can later be retrieved with |
619 | | // 'void *ptheread_getspecific(pthread_key)'. So even thought the |
620 | | // parameter is 'const void *', the region escapes through the call. |
621 | 25.6k | if (II->isStr("pthread_setspecific")) |
622 | 5 | return true; |
623 | | |
624 | | // - xpc_connection_set_context stores a value which can be retrieved later |
625 | | // with xpc_connection_get_context. |
626 | 25.6k | if (II->isStr("xpc_connection_set_context")) |
627 | 0 | return true; |
628 | | |
629 | | // - funopen - sets a buffer for future IO calls. |
630 | 25.6k | if (II->isStr("funopen")) |
631 | 1 | return true; |
632 | | |
633 | | // - __cxa_demangle - can reallocate memory and can return the pointer to |
634 | | // the input buffer. |
635 | 25.6k | if (II->isStr("__cxa_demangle")) |
636 | 8 | return true; |
637 | | |
638 | 25.5k | StringRef FName = II->getName(); |
639 | | |
640 | | // - CoreFoundation functions that end with "NoCopy" can free a passed-in |
641 | | // buffer even if it is const. |
642 | 25.5k | if (FName.endswith("NoCopy")) |
643 | 10 | return true; |
644 | | |
645 | | // - NSXXInsertXX, for example NSMapInsertIfAbsent, since they can |
646 | | // be deallocated by NSMapRemove. |
647 | 25.5k | if (FName.startswith("NS") && FName.contains("Insert")78 ) |
648 | 4 | return true; |
649 | | |
650 | | // - Many CF containers allow objects to escape through custom |
651 | | // allocators/deallocators upon container construction. (PR12101) |
652 | 25.5k | if (FName.startswith("CF") || FName.startswith("CG")24.9k ) { |
653 | 677 | return StrInStrNoCase(FName, "InsertValue") != StringRef::npos || |
654 | 677 | StrInStrNoCase(FName, "AddValue") != StringRef::npos || |
655 | 677 | StrInStrNoCase(FName, "SetValue") != StringRef::npos || |
656 | 677 | StrInStrNoCase(FName, "WithData") != StringRef::npos675 || |
657 | 677 | StrInStrNoCase(FName, "AppendValue") != StringRef::npos669 || |
658 | 677 | StrInStrNoCase(FName, "SetAttribute") != StringRef::npos663 ; |
659 | 677 | } |
660 | | |
661 | 24.9k | return false; |
662 | 25.5k | } |
663 | | |
664 | 5.19M | const FunctionDecl *SimpleFunctionCall::getDecl() const { |
665 | 5.19M | const FunctionDecl *D = getOriginExpr()->getDirectCallee(); |
666 | 5.19M | if (D) |
667 | 5.17M | return D; |
668 | | |
669 | 25.6k | return getSVal(getOriginExpr()->getCallee()).getAsFunctionDecl(); |
670 | 5.19M | } |
671 | | |
672 | 1.12M | const FunctionDecl *CXXInstanceCall::getDecl() const { |
673 | 1.12M | const auto *CE = cast_or_null<CallExpr>(getOriginExpr()); |
674 | 1.12M | if (!CE) |
675 | 52.8k | return AnyFunctionCall::getDecl(); |
676 | | |
677 | 1.07M | const FunctionDecl *D = CE->getDirectCallee(); |
678 | 1.07M | if (D) |
679 | 1.07M | return D; |
680 | | |
681 | 438 | return getSVal(CE->getCallee()).getAsFunctionDecl(); |
682 | 1.07M | } |
683 | | |
684 | | void CXXInstanceCall::getExtraInvalidatedValues( |
685 | 5.81k | ValueList &Values, RegionAndSymbolInvalidationTraits *ETraits) const { |
686 | 5.81k | SVal ThisVal = getCXXThisVal(); |
687 | 5.81k | Values.push_back(ThisVal); |
688 | | |
689 | | // Don't invalidate if the method is const and there are no mutable fields. |
690 | 5.81k | if (const auto *D = cast_or_null<CXXMethodDecl>(getDecl())) { |
691 | 5.81k | if (!D->isConst()) |
692 | 3.14k | return; |
693 | | // Get the record decl for the class of 'This'. D->getParent() may return a |
694 | | // base class decl, rather than the class of the instance which needs to be |
695 | | // checked for mutable fields. |
696 | | // TODO: We might as well look at the dynamic type of the object. |
697 | 2.67k | const Expr *Ex = getCXXThisExpr()->IgnoreParenBaseCasts(); |
698 | 2.67k | QualType T = Ex->getType(); |
699 | 2.67k | if (T->isPointerType()) // Arrow or implicit-this syntax? |
700 | 40 | T = T->getPointeeType(); |
701 | 2.67k | const CXXRecordDecl *ParentRecord = T->getAsCXXRecordDecl(); |
702 | 2.67k | assert(ParentRecord); |
703 | 2.67k | if (ParentRecord->hasMutableFields()) |
704 | 3 | return; |
705 | | // Preserve CXXThis. |
706 | 2.67k | const MemRegion *ThisRegion = ThisVal.getAsRegion(); |
707 | 2.67k | if (!ThisRegion) |
708 | 1 | return; |
709 | | |
710 | 2.67k | ETraits->setTrait(ThisRegion->getBaseRegion(), |
711 | 2.67k | RegionAndSymbolInvalidationTraits::TK_PreserveContents); |
712 | 2.67k | } |
713 | 5.81k | } |
714 | | |
715 | 54.3k | SVal CXXInstanceCall::getCXXThisVal() const { |
716 | 54.3k | const Expr *Base = getCXXThisExpr(); |
717 | | // FIXME: This doesn't handle an overloaded ->* operator. |
718 | 54.3k | if (!Base) |
719 | 0 | return UnknownVal(); |
720 | | |
721 | 54.3k | SVal ThisVal = getSVal(Base); |
722 | 54.3k | assert(ThisVal.isUnknownOrUndef() || isa<Loc>(ThisVal)); |
723 | 54.3k | return ThisVal; |
724 | 54.3k | } |
725 | | |
726 | 15.9k | RuntimeDefinition CXXInstanceCall::getRuntimeDefinition() const { |
727 | | // Do we have a decl at all? |
728 | 15.9k | const Decl *D = getDecl(); |
729 | 15.9k | if (!D) |
730 | 2 | return {}; |
731 | | |
732 | | // If the method is non-virtual, we know we can inline it. |
733 | 15.9k | const auto *MD = cast<CXXMethodDecl>(D); |
734 | 15.9k | if (!MD->isVirtual()) |
735 | 15.6k | return AnyFunctionCall::getRuntimeDefinition(); |
736 | | |
737 | | // Do we know the implicit 'this' object being called? |
738 | 309 | const MemRegion *R = getCXXThisVal().getAsRegion(); |
739 | 309 | if (!R) |
740 | 0 | return {}; |
741 | | |
742 | | // Do we know anything about the type of 'this'? |
743 | 309 | DynamicTypeInfo DynType = getDynamicTypeInfo(getState(), R); |
744 | 309 | if (!DynType.isValid()) |
745 | 0 | return {}; |
746 | | |
747 | | // Is the type a C++ class? (This is mostly a defensive check.) |
748 | 309 | QualType RegionType = DynType.getType()->getPointeeType(); |
749 | 309 | assert(!RegionType.isNull() && "DynamicTypeInfo should always be a pointer."); |
750 | | |
751 | 309 | const CXXRecordDecl *RD = RegionType->getAsCXXRecordDecl(); |
752 | 309 | if (!RD || !RD->hasDefinition()) |
753 | 0 | return {}; |
754 | | |
755 | | // Find the decl for this method in that class. |
756 | 309 | const CXXMethodDecl *Result = MD->getCorrespondingMethodInClass(RD, true); |
757 | 309 | if (!Result) { |
758 | | // We might not even get the original statically-resolved method due to |
759 | | // some particularly nasty casting (e.g. casts to sister classes). |
760 | | // However, we should at least be able to search up and down our own class |
761 | | // hierarchy, and some real bugs have been caught by checking this. |
762 | 3 | assert(!RD->isDerivedFrom(MD->getParent()) && "Couldn't find known method"); |
763 | | |
764 | | // FIXME: This is checking that our DynamicTypeInfo is at least as good as |
765 | | // the static type. However, because we currently don't update |
766 | | // DynamicTypeInfo when an object is cast, we can't actually be sure the |
767 | | // DynamicTypeInfo is up to date. This assert should be re-enabled once |
768 | | // this is fixed. |
769 | | // |
770 | | // assert(!MD->getParent()->isDerivedFrom(RD) && "Bad DynamicTypeInfo"); |
771 | | |
772 | 3 | return {}; |
773 | 3 | } |
774 | | |
775 | | // Does the decl that we found have an implementation? |
776 | 306 | const FunctionDecl *Definition; |
777 | 306 | if (!Result->hasBody(Definition)) { |
778 | 171 | if (!DynType.canBeASubClass()) |
779 | 148 | return AnyFunctionCall::getRuntimeDefinition(); |
780 | 23 | return {}; |
781 | 171 | } |
782 | | |
783 | | // We found a definition. If we're not sure that this devirtualization is |
784 | | // actually what will happen at runtime, make sure to provide the region so |
785 | | // that ExprEngine can decide what to do with it. |
786 | 135 | if (DynType.canBeASubClass()) |
787 | 14 | return RuntimeDefinition(Definition, R->StripCasts()); |
788 | 121 | return RuntimeDefinition(Definition, /*DispatchRegion=*/nullptr); |
789 | 135 | } |
790 | | |
791 | | void CXXInstanceCall::getInitialStackFrameContents( |
792 | | const StackFrameContext *CalleeCtx, |
793 | 7.31k | BindingsTy &Bindings) const { |
794 | 7.31k | AnyFunctionCall::getInitialStackFrameContents(CalleeCtx, Bindings); |
795 | | |
796 | | // Handle the binding of 'this' in the new stack frame. |
797 | 7.31k | SVal ThisVal = getCXXThisVal(); |
798 | 7.31k | if (!ThisVal.isUnknown()) { |
799 | 7.31k | ProgramStateManager &StateMgr = getState()->getStateManager(); |
800 | 7.31k | SValBuilder &SVB = StateMgr.getSValBuilder(); |
801 | | |
802 | 7.31k | const auto *MD = cast<CXXMethodDecl>(CalleeCtx->getDecl()); |
803 | 7.31k | Loc ThisLoc = SVB.getCXXThis(MD, CalleeCtx); |
804 | | |
805 | | // If we devirtualized to a different member function, we need to make sure |
806 | | // we have the proper layering of CXXBaseObjectRegions. |
807 | 7.31k | if (MD->getCanonicalDecl() != getDecl()->getCanonicalDecl()) { |
808 | 31 | ASTContext &Ctx = SVB.getContext(); |
809 | 31 | const CXXRecordDecl *Class = MD->getParent(); |
810 | 31 | QualType Ty = Ctx.getPointerType(Ctx.getRecordType(Class)); |
811 | | |
812 | | // FIXME: CallEvent maybe shouldn't be directly accessing StoreManager. |
813 | 31 | std::optional<SVal> V = |
814 | 31 | StateMgr.getStoreManager().evalBaseToDerived(ThisVal, Ty); |
815 | 31 | if (!V) { |
816 | | // We might have suffered some sort of placement new earlier, so |
817 | | // we're constructing in a completely unexpected storage. |
818 | | // Fall back to a generic pointer cast for this-value. |
819 | 2 | const CXXMethodDecl *StaticMD = cast<CXXMethodDecl>(getDecl()); |
820 | 2 | const CXXRecordDecl *StaticClass = StaticMD->getParent(); |
821 | 2 | QualType StaticTy = Ctx.getPointerType(Ctx.getRecordType(StaticClass)); |
822 | 2 | ThisVal = SVB.evalCast(ThisVal, Ty, StaticTy); |
823 | 2 | } else |
824 | 29 | ThisVal = *V; |
825 | 31 | } |
826 | | |
827 | 7.31k | if (!ThisVal.isUnknown()) |
828 | 7.31k | Bindings.push_back(std::make_pair(ThisLoc, ThisVal)); |
829 | 7.31k | } |
830 | 7.31k | } |
831 | | |
832 | 43.6k | const Expr *CXXMemberCall::getCXXThisExpr() const { |
833 | 43.6k | return getOriginExpr()->getImplicitObjectArgument(); |
834 | 43.6k | } |
835 | | |
836 | 9.05k | RuntimeDefinition CXXMemberCall::getRuntimeDefinition() const { |
837 | | // C++11 [expr.call]p1: ...If the selected function is non-virtual, or if the |
838 | | // id-expression in the class member access expression is a qualified-id, |
839 | | // that function is called. Otherwise, its final overrider in the dynamic type |
840 | | // of the object expression is called. |
841 | 9.05k | if (const auto *ME = dyn_cast<MemberExpr>(getOriginExpr()->getCallee())) |
842 | 9.03k | if (ME->hasQualifier()) |
843 | 251 | return AnyFunctionCall::getRuntimeDefinition(); |
844 | | |
845 | 8.80k | return CXXInstanceCall::getRuntimeDefinition(); |
846 | 9.05k | } |
847 | | |
848 | 17.0k | const Expr *CXXMemberOperatorCall::getCXXThisExpr() const { |
849 | 17.0k | return getOriginExpr()->getArg(0); |
850 | 17.0k | } |
851 | | |
852 | 3.73k | const BlockDataRegion *BlockCall::getBlockRegion() const { |
853 | 3.73k | const Expr *Callee = getOriginExpr()->getCallee(); |
854 | 3.73k | const MemRegion *DataReg = getSVal(Callee).getAsRegion(); |
855 | | |
856 | 3.73k | return dyn_cast_or_null<BlockDataRegion>(DataReg); |
857 | 3.73k | } |
858 | | |
859 | 697 | ArrayRef<ParmVarDecl*> BlockCall::parameters() const { |
860 | 697 | const BlockDecl *D = getDecl(); |
861 | 697 | if (!D) |
862 | 11 | return std::nullopt; |
863 | 686 | return D->parameters(); |
864 | 697 | } |
865 | | |
866 | | void BlockCall::getExtraInvalidatedValues(ValueList &Values, |
867 | 18 | RegionAndSymbolInvalidationTraits *ETraits) const { |
868 | | // FIXME: This also needs to invalidate captured globals. |
869 | 18 | if (const MemRegion *R = getBlockRegion()) |
870 | 8 | Values.push_back(loc::MemRegionVal(R)); |
871 | 18 | } |
872 | | |
873 | | void BlockCall::getInitialStackFrameContents(const StackFrameContext *CalleeCtx, |
874 | 188 | BindingsTy &Bindings) const { |
875 | 188 | SValBuilder &SVB = getState()->getStateManager().getSValBuilder(); |
876 | 188 | ArrayRef<ParmVarDecl*> Params; |
877 | 188 | if (isConversionFromLambda()) { |
878 | 7 | auto *LambdaOperatorDecl = cast<CXXMethodDecl>(CalleeCtx->getDecl()); |
879 | 7 | Params = LambdaOperatorDecl->parameters(); |
880 | | |
881 | | // For blocks converted from a C++ lambda, the callee declaration is the |
882 | | // operator() method on the lambda so we bind "this" to |
883 | | // the lambda captured by the block. |
884 | 7 | const VarRegion *CapturedLambdaRegion = getRegionStoringCapturedLambda(); |
885 | 7 | SVal ThisVal = loc::MemRegionVal(CapturedLambdaRegion); |
886 | 7 | Loc ThisLoc = SVB.getCXXThis(LambdaOperatorDecl, CalleeCtx); |
887 | 7 | Bindings.push_back(std::make_pair(ThisLoc, ThisVal)); |
888 | 181 | } else { |
889 | 181 | Params = cast<BlockDecl>(CalleeCtx->getDecl())->parameters(); |
890 | 181 | } |
891 | | |
892 | 188 | addParameterValuesToBindings(CalleeCtx, Bindings, SVB, *this, |
893 | 188 | Params); |
894 | 188 | } |
895 | | |
896 | 55.5k | SVal AnyCXXConstructorCall::getCXXThisVal() const { |
897 | 55.5k | if (Data) |
898 | 55.5k | return loc::MemRegionVal(static_cast<const MemRegion *>(Data)); |
899 | 0 | return UnknownVal(); |
900 | 55.5k | } |
901 | | |
902 | | void AnyCXXConstructorCall::getExtraInvalidatedValues(ValueList &Values, |
903 | 1.53k | RegionAndSymbolInvalidationTraits *ETraits) const { |
904 | 1.53k | SVal V = getCXXThisVal(); |
905 | 1.53k | if (SymbolRef Sym = V.getAsSymbol(true)) |
906 | 92 | ETraits->setTrait(Sym, |
907 | 92 | RegionAndSymbolInvalidationTraits::TK_SuppressEscape); |
908 | 1.53k | Values.push_back(V); |
909 | 1.53k | } |
910 | | |
911 | | void AnyCXXConstructorCall::getInitialStackFrameContents( |
912 | | const StackFrameContext *CalleeCtx, |
913 | 9.36k | BindingsTy &Bindings) const { |
914 | 9.36k | AnyFunctionCall::getInitialStackFrameContents(CalleeCtx, Bindings); |
915 | | |
916 | 9.36k | SVal ThisVal = getCXXThisVal(); |
917 | 9.36k | if (!ThisVal.isUnknown()) { |
918 | 9.36k | SValBuilder &SVB = getState()->getStateManager().getSValBuilder(); |
919 | 9.36k | const auto *MD = cast<CXXMethodDecl>(CalleeCtx->getDecl()); |
920 | 9.36k | Loc ThisLoc = SVB.getCXXThis(MD, CalleeCtx); |
921 | 9.36k | Bindings.push_back(std::make_pair(ThisLoc, ThisVal)); |
922 | 9.36k | } |
923 | 9.36k | } |
924 | | |
925 | | const StackFrameContext * |
926 | 90 | CXXInheritedConstructorCall::getInheritingStackFrame() const { |
927 | 90 | const StackFrameContext *SFC = getLocationContext()->getStackFrame(); |
928 | 103 | while (isa<CXXInheritedCtorInitExpr>(SFC->getCallSite())) |
929 | 13 | SFC = SFC->getParent()->getStackFrame(); |
930 | 90 | return SFC; |
931 | 90 | } |
932 | | |
933 | 5.83k | SVal CXXDestructorCall::getCXXThisVal() const { |
934 | 5.83k | if (Data) |
935 | 5.83k | return loc::MemRegionVal(DtorDataTy::getFromOpaqueValue(Data).getPointer()); |
936 | 0 | return UnknownVal(); |
937 | 5.83k | } |
938 | | |
939 | 1.77k | RuntimeDefinition CXXDestructorCall::getRuntimeDefinition() const { |
940 | | // Base destructors are always called non-virtually. |
941 | | // Skip CXXInstanceCall's devirtualization logic in this case. |
942 | 1.77k | if (isBaseDestructor()) |
943 | 128 | return AnyFunctionCall::getRuntimeDefinition(); |
944 | | |
945 | 1.64k | return CXXInstanceCall::getRuntimeDefinition(); |
946 | 1.77k | } |
947 | | |
948 | 31.0k | ArrayRef<ParmVarDecl*> ObjCMethodCall::parameters() const { |
949 | 31.0k | const ObjCMethodDecl *D = getDecl(); |
950 | 31.0k | if (!D) |
951 | 42 | return std::nullopt; |
952 | 30.9k | return D->parameters(); |
953 | 31.0k | } |
954 | | |
955 | | void ObjCMethodCall::getExtraInvalidatedValues( |
956 | 3.64k | ValueList &Values, RegionAndSymbolInvalidationTraits *ETraits) const { |
957 | | |
958 | | // If the method call is a setter for property known to be backed by |
959 | | // an instance variable, don't invalidate the entire receiver, just |
960 | | // the storage for that instance variable. |
961 | 3.64k | if (const ObjCPropertyDecl *PropDecl = getAccessedProperty()) { |
962 | 219 | if (const ObjCIvarDecl *PropIvar = PropDecl->getPropertyIvarDecl()) { |
963 | 62 | SVal IvarLVal = getState()->getLValue(PropIvar, getReceiverSVal()); |
964 | 62 | if (const MemRegion *IvarRegion = IvarLVal.getAsRegion()) { |
965 | 61 | ETraits->setTrait( |
966 | 61 | IvarRegion, |
967 | 61 | RegionAndSymbolInvalidationTraits::TK_DoNotInvalidateSuperRegion); |
968 | 61 | ETraits->setTrait( |
969 | 61 | IvarRegion, |
970 | 61 | RegionAndSymbolInvalidationTraits::TK_SuppressEscape); |
971 | 61 | Values.push_back(IvarLVal); |
972 | 61 | } |
973 | 62 | return; |
974 | 62 | } |
975 | 219 | } |
976 | | |
977 | 3.57k | Values.push_back(getReceiverSVal()); |
978 | 3.57k | } |
979 | | |
980 | 29.7k | SVal ObjCMethodCall::getReceiverSVal() const { |
981 | | // FIXME: Is this the best way to handle class receivers? |
982 | 29.7k | if (!isInstanceMessage()) |
983 | 4.33k | return UnknownVal(); |
984 | | |
985 | 25.3k | if (const Expr *RecE = getOriginExpr()->getInstanceReceiver()) |
986 | 23.4k | return getSVal(RecE); |
987 | | |
988 | | // An instance message with no expression means we are sending to super. |
989 | | // In this case the object reference is the same as 'self'. |
990 | 1.91k | assert(getOriginExpr()->getReceiverKind() == ObjCMessageExpr::SuperInstance); |
991 | 1.91k | SVal SelfVal = getState()->getSelfSVal(getLocationContext()); |
992 | 1.91k | assert(SelfVal.isValid() && "Calling super but not in ObjC method"); |
993 | 1.91k | return SelfVal; |
994 | 1.91k | } |
995 | | |
996 | 864 | bool ObjCMethodCall::isReceiverSelfOrSuper() const { |
997 | 864 | if (getOriginExpr()->getReceiverKind() == ObjCMessageExpr::SuperInstance || |
998 | 864 | getOriginExpr()->getReceiverKind() == ObjCMessageExpr::SuperClass653 ) |
999 | 211 | return true; |
1000 | | |
1001 | 653 | if (!isInstanceMessage()) |
1002 | 26 | return false; |
1003 | | |
1004 | 627 | SVal RecVal = getSVal(getOriginExpr()->getInstanceReceiver()); |
1005 | 627 | SVal SelfVal = getState()->getSelfSVal(getLocationContext()); |
1006 | | |
1007 | 627 | return (RecVal == SelfVal); |
1008 | 653 | } |
1009 | | |
1010 | 13 | SourceRange ObjCMethodCall::getSourceRange() const { |
1011 | 13 | switch (getMessageKind()) { |
1012 | 13 | case OCM_Message: |
1013 | 13 | return getOriginExpr()->getSourceRange(); |
1014 | 0 | case OCM_PropertyAccess: |
1015 | 0 | case OCM_Subscript: |
1016 | 0 | return getContainingPseudoObjectExpr()->getSourceRange(); |
1017 | 13 | } |
1018 | 0 | llvm_unreachable("unknown message kind"); |
1019 | 0 | } |
1020 | | |
1021 | | using ObjCMessageDataTy = llvm::PointerIntPair<const PseudoObjectExpr *, 2>; |
1022 | | |
1023 | 189 | const PseudoObjectExpr *ObjCMethodCall::getContainingPseudoObjectExpr() const { |
1024 | 189 | assert(Data && "Lazy lookup not yet performed."); |
1025 | 189 | assert(getMessageKind() != OCM_Message && "Explicit message send."); |
1026 | 189 | return ObjCMessageDataTy::getFromOpaqueValue(Data).getPointer(); |
1027 | 189 | } |
1028 | | |
1029 | | static const Expr * |
1030 | 468 | getSyntacticFromForPseudoObjectExpr(const PseudoObjectExpr *POE) { |
1031 | 468 | const Expr *Syntactic = POE->getSyntacticForm()->IgnoreParens(); |
1032 | | |
1033 | | // This handles the funny case of assigning to the result of a getter. |
1034 | | // This can happen if the getter returns a non-const reference. |
1035 | 468 | if (const auto *BO = dyn_cast<BinaryOperator>(Syntactic)) |
1036 | 140 | Syntactic = BO->getLHS()->IgnoreParens(); |
1037 | | |
1038 | 468 | return Syntactic; |
1039 | 468 | } |
1040 | | |
1041 | 8.39k | ObjCMessageKind ObjCMethodCall::getMessageKind() const { |
1042 | 8.39k | if (!Data) { |
1043 | | // Find the parent, ignoring implicit casts. |
1044 | 3.99k | const ParentMap &PM = getLocationContext()->getParentMap(); |
1045 | 3.99k | const Stmt *S = PM.getParentIgnoreParenCasts(getOriginExpr()); |
1046 | | |
1047 | | // Check if parent is a PseudoObjectExpr. |
1048 | 3.99k | if (const auto *POE = dyn_cast_or_null<PseudoObjectExpr>(S)) { |
1049 | 279 | const Expr *Syntactic = getSyntacticFromForPseudoObjectExpr(POE); |
1050 | | |
1051 | 279 | ObjCMessageKind K; |
1052 | 279 | switch (Syntactic->getStmtClass()) { |
1053 | 238 | case Stmt::ObjCPropertyRefExprClass: |
1054 | 238 | K = OCM_PropertyAccess; |
1055 | 238 | break; |
1056 | 40 | case Stmt::ObjCSubscriptRefExprClass: |
1057 | 40 | K = OCM_Subscript; |
1058 | 40 | break; |
1059 | 1 | default: |
1060 | | // FIXME: Can this ever happen? |
1061 | 1 | K = OCM_Message; |
1062 | 1 | break; |
1063 | 279 | } |
1064 | | |
1065 | 279 | if (K != OCM_Message) { |
1066 | 278 | const_cast<ObjCMethodCall *>(this)->Data |
1067 | 278 | = ObjCMessageDataTy(POE, K).getOpaqueValue(); |
1068 | 278 | assert(getMessageKind() == K); |
1069 | 278 | return K; |
1070 | 278 | } |
1071 | 279 | } |
1072 | | |
1073 | 3.71k | const_cast<ObjCMethodCall *>(this)->Data |
1074 | 3.71k | = ObjCMessageDataTy(nullptr, 1).getOpaqueValue(); |
1075 | 3.71k | assert(getMessageKind() == OCM_Message); |
1076 | 3.71k | return OCM_Message; |
1077 | 3.71k | } |
1078 | | |
1079 | 4.39k | ObjCMessageDataTy Info = ObjCMessageDataTy::getFromOpaqueValue(Data); |
1080 | 4.39k | if (!Info.getPointer()) |
1081 | 3.88k | return OCM_Message; |
1082 | 517 | return static_cast<ObjCMessageKind>(Info.getInt()); |
1083 | 4.39k | } |
1084 | | |
1085 | 3.65k | const ObjCPropertyDecl *ObjCMethodCall::getAccessedProperty() const { |
1086 | | // Look for properties accessed with property syntax (foo.bar = ...) |
1087 | 3.65k | if (getMessageKind() == OCM_PropertyAccess) { |
1088 | 189 | const PseudoObjectExpr *POE = getContainingPseudoObjectExpr(); |
1089 | 189 | assert(POE && "Property access without PseudoObjectExpr?"); |
1090 | | |
1091 | 189 | const Expr *Syntactic = getSyntacticFromForPseudoObjectExpr(POE); |
1092 | 189 | auto *RefExpr = cast<ObjCPropertyRefExpr>(Syntactic); |
1093 | | |
1094 | 189 | if (RefExpr->isExplicitProperty()) |
1095 | 171 | return RefExpr->getExplicitProperty(); |
1096 | 189 | } |
1097 | | |
1098 | | // Look for properties accessed with method syntax ([foo setBar:...]). |
1099 | 3.48k | const ObjCMethodDecl *MD = getDecl(); |
1100 | 3.48k | if (!MD || !MD->isPropertyAccessor()3.46k ) |
1101 | 3.42k | return nullptr; |
1102 | | |
1103 | | // Note: This is potentially quite slow. |
1104 | 65 | return MD->findPropertyDecl(); |
1105 | 3.48k | } |
1106 | | |
1107 | | bool ObjCMethodCall::canBeOverridenInSubclass(ObjCInterfaceDecl *IDecl, |
1108 | 1.46k | Selector Sel) const { |
1109 | 1.46k | assert(IDecl); |
1110 | 1.46k | AnalysisManager &AMgr = |
1111 | 1.46k | getState()->getStateManager().getOwningEngine().getAnalysisManager(); |
1112 | | // If the class interface is declared inside the main file, assume it is not |
1113 | | // subcassed. |
1114 | | // TODO: It could actually be subclassed if the subclass is private as well. |
1115 | | // This is probably very rare. |
1116 | 1.46k | SourceLocation InterfLoc = IDecl->getEndOfDefinitionLoc(); |
1117 | 1.46k | if (InterfLoc.isValid() && AMgr.isInCodeFile(InterfLoc)) |
1118 | 1.33k | return false; |
1119 | | |
1120 | | // Assume that property accessors are not overridden. |
1121 | 138 | if (getMessageKind() == OCM_PropertyAccess) |
1122 | 9 | return false; |
1123 | | |
1124 | | // We assume that if the method is public (declared outside of main file) or |
1125 | | // has a parent which publicly declares the method, the method could be |
1126 | | // overridden in a subclass. |
1127 | | |
1128 | | // Find the first declaration in the class hierarchy that declares |
1129 | | // the selector. |
1130 | 129 | ObjCMethodDecl *D = nullptr; |
1131 | 132 | while (true) { |
1132 | 132 | D = IDecl->lookupMethod(Sel, true); |
1133 | | |
1134 | | // Cannot find a public definition. |
1135 | 132 | if (!D) |
1136 | 2 | return false; |
1137 | | |
1138 | | // If outside the main file, |
1139 | 130 | if (D->getLocation().isValid() && !AMgr.isInCodeFile(D->getLocation())) |
1140 | 124 | return true; |
1141 | | |
1142 | 6 | if (D->isOverriding()) { |
1143 | | // Search in the superclass on the next iteration. |
1144 | 3 | IDecl = D->getClassInterface(); |
1145 | 3 | if (!IDecl) |
1146 | 0 | return false; |
1147 | | |
1148 | 3 | IDecl = IDecl->getSuperClass(); |
1149 | 3 | if (!IDecl) |
1150 | 0 | return false; |
1151 | | |
1152 | 3 | continue; |
1153 | 3 | } |
1154 | | |
1155 | 3 | return false; |
1156 | 6 | }; |
1157 | |
|
1158 | 0 | llvm_unreachable("The while loop should always terminate."); |
1159 | 0 | } |
1160 | | |
1161 | 29 | static const ObjCMethodDecl *findDefiningRedecl(const ObjCMethodDecl *MD) { |
1162 | 29 | if (!MD) |
1163 | 0 | return MD; |
1164 | | |
1165 | | // Find the redeclaration that defines the method. |
1166 | 29 | if (!MD->hasBody()) { |
1167 | 21 | for (auto *I : MD->redecls()) |
1168 | 28 | if (I->hasBody()) |
1169 | 7 | MD = cast<ObjCMethodDecl>(I); |
1170 | 21 | } |
1171 | 29 | return MD; |
1172 | 29 | } |
1173 | | |
1174 | | struct PrivateMethodKey { |
1175 | | const ObjCInterfaceDecl *Interface; |
1176 | | Selector LookupSelector; |
1177 | | bool IsClassMethod; |
1178 | | }; |
1179 | | |
1180 | | namespace llvm { |
1181 | | template <> struct DenseMapInfo<PrivateMethodKey> { |
1182 | | using InterfaceInfo = DenseMapInfo<const ObjCInterfaceDecl *>; |
1183 | | using SelectorInfo = DenseMapInfo<Selector>; |
1184 | | |
1185 | 4.30k | static inline PrivateMethodKey getEmptyKey() { |
1186 | 4.30k | return {InterfaceInfo::getEmptyKey(), SelectorInfo::getEmptyKey(), false}; |
1187 | 4.30k | } |
1188 | | |
1189 | 3.19k | static inline PrivateMethodKey getTombstoneKey() { |
1190 | 3.19k | return {InterfaceInfo::getTombstoneKey(), SelectorInfo::getTombstoneKey(), |
1191 | 3.19k | true}; |
1192 | 3.19k | } |
1193 | | |
1194 | 3.06k | static unsigned getHashValue(const PrivateMethodKey &Key) { |
1195 | 3.06k | return llvm::hash_combine( |
1196 | 3.06k | llvm::hash_code(InterfaceInfo::getHashValue(Key.Interface)), |
1197 | 3.06k | llvm::hash_code(SelectorInfo::getHashValue(Key.LookupSelector)), |
1198 | 3.06k | Key.IsClassMethod); |
1199 | 3.06k | } |
1200 | | |
1201 | | static bool isEqual(const PrivateMethodKey &LHS, |
1202 | 23.2k | const PrivateMethodKey &RHS) { |
1203 | 23.2k | return InterfaceInfo::isEqual(LHS.Interface, RHS.Interface) && |
1204 | 23.2k | SelectorInfo::isEqual(LHS.LookupSelector, RHS.LookupSelector)11.6k && |
1205 | 23.2k | LHS.IsClassMethod == RHS.IsClassMethod11.6k ; |
1206 | 23.2k | } |
1207 | | }; |
1208 | | } // end namespace llvm |
1209 | | |
1210 | | static const ObjCMethodDecl * |
1211 | | lookupRuntimeDefinition(const ObjCInterfaceDecl *Interface, |
1212 | 2.86k | Selector LookupSelector, bool InstanceMethod) { |
1213 | | // Repeatedly calling lookupPrivateMethod() is expensive, especially |
1214 | | // when in many cases it returns null. We cache the results so |
1215 | | // that repeated queries on the same ObjCIntefaceDecl and Selector |
1216 | | // don't incur the same cost. On some test cases, we can see the |
1217 | | // same query being issued thousands of times. |
1218 | | // |
1219 | | // NOTE: This cache is essentially a "global" variable, but it |
1220 | | // only gets lazily created when we get here. The value of the |
1221 | | // cache probably comes from it being global across ExprEngines, |
1222 | | // where the same queries may get issued. If we are worried about |
1223 | | // concurrency, or possibly loading/unloading ASTs, etc., we may |
1224 | | // need to revisit this someday. In terms of memory, this table |
1225 | | // stays around until clang quits, which also may be bad if we |
1226 | | // need to release memory. |
1227 | 2.86k | using PrivateMethodCache = |
1228 | 2.86k | llvm::DenseMap<PrivateMethodKey, std::optional<const ObjCMethodDecl *>>; |
1229 | | |
1230 | 2.86k | static PrivateMethodCache PMC; |
1231 | 2.86k | std::optional<const ObjCMethodDecl *> &Val = |
1232 | 2.86k | PMC[{Interface, LookupSelector, InstanceMethod}]; |
1233 | | |
1234 | | // Query lookupPrivateMethod() if the cache does not hit. |
1235 | 2.86k | if (!Val) { |
1236 | 982 | Val = Interface->lookupPrivateMethod(LookupSelector, InstanceMethod); |
1237 | | |
1238 | 982 | if (!*Val) { |
1239 | | // Query 'lookupMethod' as a backup. |
1240 | 693 | Val = Interface->lookupMethod(LookupSelector, InstanceMethod); |
1241 | 693 | } |
1242 | 982 | } |
1243 | | |
1244 | 2.86k | return *Val; |
1245 | 2.86k | } |
1246 | | |
1247 | 4.29k | RuntimeDefinition ObjCMethodCall::getRuntimeDefinition() const { |
1248 | 4.29k | const ObjCMessageExpr *E = getOriginExpr(); |
1249 | 4.29k | assert(E); |
1250 | 4.29k | Selector Sel = E->getSelector(); |
1251 | | |
1252 | 4.29k | if (E->isInstanceMessage()) { |
1253 | | // Find the receiver type. |
1254 | 3.25k | const ObjCObjectType *ReceiverT = nullptr; |
1255 | 3.25k | bool CanBeSubClassed = false; |
1256 | 3.25k | bool LookingForInstanceMethod = true; |
1257 | 3.25k | QualType SupersType = E->getSuperType(); |
1258 | 3.25k | const MemRegion *Receiver = nullptr; |
1259 | | |
1260 | 3.25k | if (!SupersType.isNull()) { |
1261 | | // The receiver is guaranteed to be 'super' in this case. |
1262 | | // Super always means the type of immediate predecessor to the method |
1263 | | // where the call occurs. |
1264 | 330 | ReceiverT = cast<ObjCObjectPointerType>(SupersType)->getObjectType(); |
1265 | 2.92k | } else { |
1266 | 2.92k | Receiver = getReceiverSVal().getAsRegion(); |
1267 | 2.92k | if (!Receiver) |
1268 | 4 | return {}; |
1269 | | |
1270 | 2.92k | DynamicTypeInfo DTI = getDynamicTypeInfo(getState(), Receiver); |
1271 | 2.92k | if (!DTI.isValid()) { |
1272 | 1 | assert(isa<AllocaRegion>(Receiver) && |
1273 | 1 | "Unhandled untyped region class!"); |
1274 | 1 | return {}; |
1275 | 1 | } |
1276 | | |
1277 | 2.92k | QualType DynType = DTI.getType(); |
1278 | 2.92k | CanBeSubClassed = DTI.canBeASubClass(); |
1279 | | |
1280 | 2.92k | const auto *ReceiverDynT = |
1281 | 2.92k | dyn_cast<ObjCObjectPointerType>(DynType.getCanonicalType()); |
1282 | | |
1283 | 2.92k | if (ReceiverDynT) { |
1284 | 2.79k | ReceiverT = ReceiverDynT->getObjectType(); |
1285 | | |
1286 | | // It can be actually class methods called with Class object as a |
1287 | | // receiver. This type of messages is treated by the compiler as |
1288 | | // instance (not class). |
1289 | 2.79k | if (ReceiverT->isObjCClass()) { |
1290 | | |
1291 | 58 | SVal SelfVal = getState()->getSelfSVal(getLocationContext()); |
1292 | | // For [self classMethod], return compiler visible declaration. |
1293 | 58 | if (Receiver == SelfVal.getAsRegion()) { |
1294 | 29 | return RuntimeDefinition(findDefiningRedecl(E->getMethodDecl())); |
1295 | 29 | } |
1296 | | |
1297 | | // Otherwise, let's check if we know something about the type |
1298 | | // inside of this class object. |
1299 | 29 | if (SymbolRef ReceiverSym = getReceiverSVal().getAsSymbol()) { |
1300 | 29 | DynamicTypeInfo DTI = |
1301 | 29 | getClassObjectDynamicTypeInfo(getState(), ReceiverSym); |
1302 | 29 | if (DTI.isValid()) { |
1303 | | // Let's use this type for lookup. |
1304 | 28 | ReceiverT = |
1305 | 28 | cast<ObjCObjectType>(DTI.getType().getCanonicalType()); |
1306 | | |
1307 | 28 | CanBeSubClassed = DTI.canBeASubClass(); |
1308 | | // And it should be a class method instead. |
1309 | 28 | LookingForInstanceMethod = false; |
1310 | 28 | } |
1311 | 29 | } |
1312 | 29 | } |
1313 | | |
1314 | 2.76k | if (CanBeSubClassed) |
1315 | 1.69k | if (ObjCInterfaceDecl *IDecl = ReceiverT->getInterface()) |
1316 | | // Even if `DynamicTypeInfo` told us that it can be |
1317 | | // not necessarily this type, but its descendants, we still want |
1318 | | // to check again if this selector can be actually overridden. |
1319 | 1.46k | CanBeSubClassed = canBeOverridenInSubclass(IDecl, Sel); |
1320 | 2.76k | } |
1321 | 2.92k | } |
1322 | | |
1323 | | // Lookup the instance method implementation. |
1324 | 3.22k | if (ReceiverT) |
1325 | 3.09k | if (ObjCInterfaceDecl *IDecl = ReceiverT->getInterface()) { |
1326 | 2.86k | const ObjCMethodDecl *MD = |
1327 | 2.86k | lookupRuntimeDefinition(IDecl, Sel, LookingForInstanceMethod); |
1328 | | |
1329 | 2.86k | if (MD && !MD->hasBody()2.84k ) |
1330 | 2.46k | MD = MD->getCanonicalDecl(); |
1331 | | |
1332 | 2.86k | if (CanBeSubClassed) |
1333 | 124 | return RuntimeDefinition(MD, Receiver); |
1334 | 2.74k | else |
1335 | 2.74k | return RuntimeDefinition(MD, nullptr); |
1336 | 2.86k | } |
1337 | 3.22k | } else { |
1338 | | // This is a class method. |
1339 | | // If we have type info for the receiver class, we are calling via |
1340 | | // class name. |
1341 | 1.04k | if (ObjCInterfaceDecl *IDecl = E->getReceiverInterface()) { |
1342 | | // Find/Return the method implementation. |
1343 | 1.04k | return RuntimeDefinition(IDecl->lookupPrivateClassMethod(Sel)); |
1344 | 1.04k | } |
1345 | 1.04k | } |
1346 | | |
1347 | 352 | return {}; |
1348 | 4.29k | } |
1349 | | |
1350 | 3.69k | bool ObjCMethodCall::argumentsMayEscape() const { |
1351 | 3.69k | if (isInSystemHeader() && !isInstanceMessage()456 ) { |
1352 | 119 | Selector Sel = getSelector(); |
1353 | 119 | if (Sel.getNumArgs() == 1 && |
1354 | 119 | Sel.getIdentifierInfoForSlot(0)->isStr("valueWithPointer")5 ) |
1355 | 2 | return true; |
1356 | 119 | } |
1357 | | |
1358 | 3.69k | return CallEvent::argumentsMayEscape(); |
1359 | 3.69k | } |
1360 | | |
1361 | | void ObjCMethodCall::getInitialStackFrameContents( |
1362 | | const StackFrameContext *CalleeCtx, |
1363 | 572 | BindingsTy &Bindings) const { |
1364 | 572 | const auto *D = cast<ObjCMethodDecl>(CalleeCtx->getDecl()); |
1365 | 572 | SValBuilder &SVB = getState()->getStateManager().getSValBuilder(); |
1366 | 572 | addParameterValuesToBindings(CalleeCtx, Bindings, SVB, *this, |
1367 | 572 | D->parameters()); |
1368 | | |
1369 | 572 | SVal SelfVal = getReceiverSVal(); |
1370 | 572 | if (!SelfVal.isUnknown()) { |
1371 | 520 | const VarDecl *SelfD = CalleeCtx->getAnalysisDeclContext()->getSelfDecl(); |
1372 | 520 | MemRegionManager &MRMgr = SVB.getRegionManager(); |
1373 | 520 | Loc SelfLoc = SVB.makeLoc(MRMgr.getVarRegion(SelfD, CalleeCtx)); |
1374 | 520 | Bindings.push_back(std::make_pair(SelfLoc, SelfVal)); |
1375 | 520 | } |
1376 | 572 | } |
1377 | | |
1378 | | CallEventRef<> |
1379 | | CallEventManager::getSimpleCall(const CallExpr *CE, ProgramStateRef State, |
1380 | | const LocationContext *LCtx, |
1381 | 156k | CFGBlock::ConstCFGElementRef ElemRef) { |
1382 | 156k | if (const auto *MCE = dyn_cast<CXXMemberCallExpr>(CE)) |
1383 | 17.4k | return create<CXXMemberCall>(MCE, State, LCtx, ElemRef); |
1384 | | |
1385 | 139k | if (const auto *OpCE = dyn_cast<CXXOperatorCallExpr>(CE)) { |
1386 | 9.26k | const FunctionDecl *DirectCallee = OpCE->getDirectCallee(); |
1387 | 9.26k | if (const auto *MD = dyn_cast<CXXMethodDecl>(DirectCallee)) |
1388 | 9.07k | if (MD->isInstance()) |
1389 | 9.07k | return create<CXXMemberOperatorCall>(OpCE, State, LCtx, ElemRef); |
1390 | | |
1391 | 130k | } else if (CE->getCallee()->getType()->isBlockPointerType()) { |
1392 | 618 | return create<BlockCall>(CE, State, LCtx, ElemRef); |
1393 | 618 | } |
1394 | | |
1395 | | // Otherwise, it's a normal function call, static member function call, or |
1396 | | // something we can't reason about. |
1397 | 129k | return create<SimpleFunctionCall>(CE, State, LCtx, ElemRef); |
1398 | 139k | } |
1399 | | |
1400 | | CallEventRef<> |
1401 | | CallEventManager::getCaller(const StackFrameContext *CalleeCtx, |
1402 | 88.2k | ProgramStateRef State) { |
1403 | 88.2k | const LocationContext *ParentCtx = CalleeCtx->getParent(); |
1404 | 88.2k | const LocationContext *CallerCtx = ParentCtx->getStackFrame(); |
1405 | 88.2k | CFGBlock::ConstCFGElementRef ElemRef = {CalleeCtx->getCallSiteBlock(), |
1406 | 88.2k | CalleeCtx->getIndex()}; |
1407 | 88.2k | assert(CallerCtx && "This should not be used for top-level stack frames"); |
1408 | | |
1409 | 88.2k | const Stmt *CallSite = CalleeCtx->getCallSite(); |
1410 | | |
1411 | 88.2k | if (CallSite) { |
1412 | 86.2k | if (CallEventRef<> Out = getCall(CallSite, State, CallerCtx, ElemRef)) |
1413 | 66.9k | return Out; |
1414 | | |
1415 | 19.3k | SValBuilder &SVB = State->getStateManager().getSValBuilder(); |
1416 | 19.3k | const auto *Ctor = cast<CXXMethodDecl>(CalleeCtx->getDecl()); |
1417 | 19.3k | Loc ThisPtr = SVB.getCXXThis(Ctor, CalleeCtx); |
1418 | 19.3k | SVal ThisVal = State->getSVal(ThisPtr); |
1419 | | |
1420 | 19.3k | if (const auto *CE = dyn_cast<CXXConstructExpr>(CallSite)) |
1421 | 19.3k | return getCXXConstructorCall(CE, ThisVal.getAsRegion(), State, CallerCtx, |
1422 | 19.3k | ElemRef); |
1423 | 8 | else if (const auto *CIE = dyn_cast<CXXInheritedCtorInitExpr>(CallSite)) |
1424 | 8 | return getCXXInheritedConstructorCall(CIE, ThisVal.getAsRegion(), State, |
1425 | 8 | CallerCtx, ElemRef); |
1426 | 0 | else { |
1427 | | // All other cases are handled by getCall. |
1428 | 0 | llvm_unreachable("This is not an inlineable statement"); |
1429 | 0 | } |
1430 | 19.3k | } |
1431 | | |
1432 | | // Fall back to the CFG. The only thing we haven't handled yet is |
1433 | | // destructors, though this could change in the future. |
1434 | 1.93k | const CFGBlock *B = CalleeCtx->getCallSiteBlock(); |
1435 | 1.93k | CFGElement E = (*B)[CalleeCtx->getIndex()]; |
1436 | 1.93k | assert((E.getAs<CFGImplicitDtor>() || E.getAs<CFGTemporaryDtor>()) && |
1437 | 1.93k | "All other CFG elements should have exprs"); |
1438 | | |
1439 | 1.93k | SValBuilder &SVB = State->getStateManager().getSValBuilder(); |
1440 | 1.93k | const auto *Dtor = cast<CXXDestructorDecl>(CalleeCtx->getDecl()); |
1441 | 1.93k | Loc ThisPtr = SVB.getCXXThis(Dtor, CalleeCtx); |
1442 | 1.93k | SVal ThisVal = State->getSVal(ThisPtr); |
1443 | | |
1444 | 1.93k | const Stmt *Trigger; |
1445 | 1.93k | if (std::optional<CFGAutomaticObjDtor> AutoDtor = |
1446 | 1.93k | E.getAs<CFGAutomaticObjDtor>()) |
1447 | 1.01k | Trigger = AutoDtor->getTriggerStmt(); |
1448 | 918 | else if (std::optional<CFGDeleteDtor> DeleteDtor = E.getAs<CFGDeleteDtor>()) |
1449 | 204 | Trigger = DeleteDtor->getDeleteExpr(); |
1450 | 714 | else |
1451 | 714 | Trigger = Dtor->getBody(); |
1452 | | |
1453 | 1.93k | return getCXXDestructorCall(Dtor, Trigger, ThisVal.getAsRegion(), |
1454 | 1.93k | E.getAs<CFGBaseDtor>().has_value(), State, |
1455 | 1.93k | CallerCtx, ElemRef); |
1456 | 1.93k | } |
1457 | | |
1458 | | CallEventRef<> CallEventManager::getCall(const Stmt *S, ProgramStateRef State, |
1459 | | const LocationContext *LC, |
1460 | 86.8k | CFGBlock::ConstCFGElementRef ElemRef) { |
1461 | 86.8k | if (const auto *CE = dyn_cast<CallExpr>(S)) { |
1462 | 65.0k | return getSimpleCall(CE, State, LC, ElemRef); |
1463 | 65.0k | } else if (const auto *21.7k NE21.7k = dyn_cast<CXXNewExpr>(S)) { |
1464 | 557 | return getCXXAllocatorCall(NE, State, LC, ElemRef); |
1465 | 21.2k | } else if (const auto *DE = dyn_cast<CXXDeleteExpr>(S)) { |
1466 | 6 | return getCXXDeallocatorCall(DE, State, LC, ElemRef); |
1467 | 21.2k | } else if (const auto *ME = dyn_cast<ObjCMessageExpr>(S)) { |
1468 | 1.89k | return getObjCMethodCall(ME, State, LC, ElemRef); |
1469 | 19.3k | } else { |
1470 | 19.3k | return nullptr; |
1471 | 19.3k | } |
1472 | 86.8k | } |