clang 23.0.0git
CallEvent.cpp
Go to the documentation of this file.
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
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"
29#include "clang/Analysis/CFG.h"
34#include "clang/Basic/LLVM.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/Compiler.h"
58#include "llvm/Support/Debug.h"
59#include "llvm/Support/ErrorHandling.h"
60#include "llvm/Support/raw_ostream.h"
61#include <cassert>
62#include <optional>
63#include <utility>
64
65#define DEBUG_TYPE "static-analyzer-call-event"
66
67using namespace clang;
68using namespace ento;
69
71 ASTContext &Ctx = getState()->getStateManager().getContext();
72 const Expr *E = getOriginExpr();
73 if (!E)
74 return Ctx.VoidTy;
75 return Ctx.getReferenceQualifiedType(E);
76}
77
78static bool isCallback(QualType T) {
79 // If a parameter is a block or a callback, assume it can modify pointer.
80 if (T->isBlockPointerType() ||
81 T->isFunctionPointerType() ||
82 T->isObjCSelType())
83 return true;
84
85 // Check if a callback is passed inside a struct (for both, struct passed by
86 // reference and by value). Dig just one level into the struct for now.
87
88 if (T->isAnyPointerType() || T->isReferenceType())
89 T = T->getPointeeType();
90
91 if (const RecordType *RT = T->getAsStructureType()) {
92 const RecordDecl *RD = RT->getDecl()->getDefinitionOrSelf();
93 for (const auto *I : RD->fields()) {
94 QualType FieldT = I->getType();
95 if (FieldT->isBlockPointerType() || FieldT->isFunctionPointerType())
96 return true;
97 }
98 }
99 return false;
100}
101
103 if (const auto *PT = T->getAs<PointerType>()) {
104 QualType PointeeTy = PT->getPointeeType();
105 if (PointeeTy.isConstQualified())
106 return false;
107 return PointeeTy->isVoidType();
108 } else
109 return false;
110}
111
113 unsigned NumOfArgs = getNumArgs();
114
115 // If calling using a function pointer, assume the function does not
116 // satisfy the callback.
117 // TODO: We could check the types of the arguments here.
118 if (!getDecl())
119 return false;
120
121 unsigned Idx = 0;
123 E = param_type_end();
124 I != E && Idx < NumOfArgs; ++I, ++Idx) {
125 // If the parameter is 0, it's harmless.
126 if (getArgSVal(Idx).isZeroConstant())
127 continue;
128
129 if (Condition(*I))
130 return true;
131 }
132 return false;
133}
134
138
142
143bool CallEvent::isGlobalCFunction(StringRef FunctionName) const {
144 const auto *FD = dyn_cast_or_null<FunctionDecl>(getDecl());
145 if (!FD)
146 return false;
147
148 return CheckerContext::isCLibraryFunction(FD, FunctionName);
149}
150
152 const Decl *D = getDecl();
153 if (!D)
154 return nullptr;
155
157 LCtx->getAnalysisDeclContext()->getManager()->getContext(D);
158
159 return ADC;
160}
161
162const StackFrameContext *
163CallEvent::getCalleeStackFrame(unsigned BlockCount) const {
165 if (!ADC)
166 return nullptr;
167
168 const Expr *E = getOriginExpr();
169 if (!E)
170 return nullptr;
171
172 // Recover CFG block via reverse lookup.
173 // TODO: If we were to keep CFG element information as part of the CallEvent
174 // instead of doing this reverse lookup, we would be able to build the stack
175 // frame for non-expression-based calls, and also we wouldn't need the reverse
176 // lookup.
177 const CFGStmtMap *Map = LCtx->getAnalysisDeclContext()->getCFGStmtMap();
178 const CFGBlock *B = Map->getBlock(E);
179 assert(B);
180
181 // Also recover CFG index by scanning the CFG block.
182 unsigned Idx = 0, Sz = B->size();
183 for (; Idx < Sz; ++Idx)
184 if (auto StmtElem = (*B)[Idx].getAs<CFGStmt>())
185 if (StmtElem->getStmt() == E)
186 break;
187 assert(Idx < Sz);
188
189 return ADC->getManager()->getStackFrame(ADC, LCtx, E, B, BlockCount, Idx);
190}
191
192const ParamVarRegion
193*CallEvent::getParameterLocation(unsigned Index, unsigned BlockCount) const {
194 const StackFrameContext *SFC = getCalleeStackFrame(BlockCount);
195 // We cannot construct a VarRegion without a stack frame.
196 if (!SFC)
197 return nullptr;
198
199 const ParamVarRegion *PVR =
200 State->getStateManager().getRegionManager().getParamVarRegion(
201 getOriginExpr(), Index, SFC);
202 return PVR;
203}
204
205/// Returns true if a type is a pointer-to-const or reference-to-const
206/// with no further indirection.
207static bool isPointerToConst(QualType Ty) {
208 QualType PointeeTy = Ty->getPointeeType();
209 if (PointeeTy == QualType())
210 return false;
211 if (!PointeeTy.isConstQualified())
212 return false;
213 if (PointeeTy->isAnyPointerType())
214 return false;
215 return true;
216}
217
218// Try to retrieve the function declaration and find the function parameter
219// types which are pointers/references to a non-pointer const.
220// We will not invalidate the corresponding argument regions.
221static void findPtrToConstParams(llvm::SmallSet<unsigned, 4> &PreserveArgs,
222 const CallEvent &Call) {
223 unsigned Idx = 0;
224 for (CallEvent::param_type_iterator I = Call.param_type_begin(),
225 E = Call.param_type_end();
226 I != E; ++I, ++Idx) {
227 if (isPointerToConst(*I))
228 PreserveArgs.insert(Idx);
229 }
230}
231
233 if (const auto *CtorCall = dyn_cast<CXXConstructorCall>(&Call)) {
234 if (const MemRegion *R = CtorCall->getCXXThisVal().getAsRegion())
235 return R->getBaseRegion();
236 }
237 return nullptr;
238}
239
241 ProgramStateRef State) const {
242 // Don't invalidate anything if the callee is marked pure/const.
243 if (const Decl *Callee = getDecl())
244 if (Callee->hasAttr<PureAttr>() || Callee->hasAttr<ConstAttr>())
245 return State;
246
247 SmallVector<SVal, 8> ValuesToInvalidate;
249
250 getExtraInvalidatedValues(ValuesToInvalidate, &ETraits);
251
252 // Indexes of arguments whose values will be preserved by the call.
253 llvm::SmallSet<unsigned, 4> PreserveArgs;
254 if (!argumentsMayEscape())
255 findPtrToConstParams(PreserveArgs, *this);
256
257 // We should not preserve the contents of the region pointed by "this" when
258 // constructing the object, even if an argument refers to it.
259 const auto *ThisRegionBaseOrNull = getThisRegionBaseOrNull(*this);
260
261 for (unsigned Idx = 0, Count = getNumArgs(); Idx != Count; ++Idx) {
262 // Mark this region for invalidation. We batch invalidate regions
263 // below for efficiency.
264 if (PreserveArgs.count(Idx)) {
265 if (const MemRegion *ArgBaseR = getArgSVal(Idx).getAsRegion()) {
266 ArgBaseR = ArgBaseR->getBaseRegion();
267
268 // Preserve the contents of the pointee of the argument - except if it
269 // refers to the object under construction (ctor call).
270 if (ArgBaseR != ThisRegionBaseOrNull) {
271 ETraits.setTrait(
273 // TODO: Factor this out + handle the lower level const pointers.
274 }
275 }
276 }
277
278 ValuesToInvalidate.push_back(getArgSVal(Idx));
279
280 // If a function accepts an object by argument (which would of course be a
281 // temporary that isn't lifetime-extended), invalidate the object itself,
282 // not only other objects reachable from it. This is necessary because the
283 // destructor has access to the temporary object after the call.
284 // TODO: Support placement arguments once we start
285 // constructing them directly.
286 // TODO: This is unnecessary when there's no destructor, but that's
287 // currently hard to figure out.
288 if (getKind() != CE_CXXAllocator)
290 if (auto AdjIdx = getAdjustedParameterIndex(Idx))
291 if (const TypedValueRegion *TVR =
292 getParameterLocation(*AdjIdx, BlockCount))
293 ValuesToInvalidate.push_back(loc::MemRegionVal(TVR));
294 }
295
296 // Invalidate designated regions using the batch invalidation API.
297 // NOTE: Even if RegionsToInvalidate is empty, we may still invalidate
298 // global variables.
299 return State->invalidateRegions(ValuesToInvalidate, getCFGElementRef(),
300 BlockCount, getLocationContext(),
301 /*CausedByPointerEscape*/ true,
302 /*Symbols=*/nullptr, this, &ETraits);
303}
304
306 const ProgramPointTag *Tag) const {
307
308 if (const Expr *E = getOriginExpr()) {
309 if (IsPreVisit)
310 return PreStmt(E, getLocationContext(), Tag);
311 return PostStmt(E, getLocationContext(), Tag);
312 }
313
314 const Decl *D = getDecl();
315 assert(D && "Cannot get a program point without a statement or decl");
316 assert(ElemRef.getParent() &&
317 "Cannot get a program point without a CFGElementRef");
318
320 if (IsPreVisit)
321 return PreImplicitCall(D, Loc, getLocationContext(), ElemRef, Tag);
322 return PostImplicitCall(D, Loc, getLocationContext(), ElemRef, Tag);
323}
324
325SVal CallEvent::getArgSVal(unsigned Index) const {
326 const Expr *ArgE = getArgExpr(Index);
327 if (!ArgE)
328 return UnknownVal();
329 return getSVal(ArgE);
330}
331
333 const Expr *ArgE = getArgExpr(Index);
334 if (!ArgE)
335 return {};
336 return ArgE->getSourceRange();
337}
338
340 const Expr *E = getOriginExpr();
341 if (!E)
342 return UndefinedVal();
343 return getSVal(E);
344}
345
346LLVM_DUMP_METHOD void CallEvent::dump() const { dump(llvm::errs()); }
347
348void CallEvent::dump(raw_ostream &Out) const {
349 ASTContext &Ctx = getState()->getStateManager().getContext();
350 if (const Expr *E = getOriginExpr()) {
351 E->printPretty(Out, nullptr, Ctx.getPrintingPolicy());
352 return;
353 }
354
355 if (const Decl *D = getDecl()) {
356 Out << "Call to ";
357 D->print(Out, Ctx.getPrintingPolicy());
358 return;
359 }
360
361 Out << "Unknown call (type " << getKindAsString() << ")";
362}
363
367
369 assert(D);
370 if (const auto *FD = dyn_cast<FunctionDecl>(D))
371 return FD->getReturnType();
372 if (const auto *MD = dyn_cast<ObjCMethodDecl>(D))
373 return MD->getReturnType();
374 if (const auto *BD = dyn_cast<BlockDecl>(D)) {
375 // Blocks are difficult because the return type may not be stored in the
376 // BlockDecl itself. The AST should probably be enhanced, but for now we
377 // just do what we can.
378 // If the block is declared without an explicit argument list, the
379 // signature-as-written just includes the return type, not the entire
380 // function type.
381 // FIXME: All blocks should have signatures-as-written, even if the return
382 // type is inferred. (That's signified with a dependent result type.)
383 if (const TypeSourceInfo *TSI = BD->getSignatureAsWritten()) {
384 QualType Ty = TSI->getType();
385 if (const FunctionType *FT = Ty->getAs<FunctionType>())
386 Ty = FT->getReturnType();
387 if (!Ty->isDependentType())
388 return Ty;
389 }
390
391 return {};
392 }
393
394 llvm_unreachable("unknown callable kind");
395}
396
398 assert(D);
399
400 if (const auto *FD = dyn_cast<FunctionDecl>(D))
401 return FD->isVariadic();
402 if (const auto *MD = dyn_cast<ObjCMethodDecl>(D))
403 return MD->isVariadic();
404 if (const auto *BD = dyn_cast<BlockDecl>(D))
405 return BD->isVariadic();
406
407 llvm_unreachable("unknown callable kind");
408}
409
411 const RecordType *UT = T->getAsUnionType();
412 return UT &&
413 UT->getDecl()->getMostRecentDecl()->hasAttr<TransparentUnionAttr>();
414}
415
416// In some cases, symbolic cases should be transformed before we associate
417// them with parameters. This function incapsulates such cases.
418static SVal processArgument(SVal Value, const Expr *ArgumentExpr,
419 const ParmVarDecl *Parameter, SValBuilder &SVB) {
420 QualType ParamType = Parameter->getType();
421 QualType ArgumentType = ArgumentExpr->getType();
422
423 // Transparent unions allow users to easily convert values of union field
424 // types into union-typed objects.
425 //
426 // Also, more importantly, they allow users to define functions with different
427 // different parameter types, substituting types matching transparent union
428 // field types with the union type itself.
429 //
430 // Here, we check specifically for latter cases and prevent binding
431 // field-typed values to union-typed regions.
432 if (isTransparentUnion(ParamType) &&
433 // Let's check that we indeed trying to bind different types.
434 !isTransparentUnion(ArgumentType)) {
436
437 llvm::ImmutableList<SVal> CompoundSVals = BVF.getEmptySValList();
438 CompoundSVals = BVF.prependSVal(Value, CompoundSVals);
439
440 // Wrap it with compound value.
441 return SVB.makeCompoundVal(ParamType, CompoundSVals);
442 }
443
444 return Value;
445}
446
447/// Cast the argument value to the type of the parameter at the function
448/// declaration.
449/// Returns the argument value if it didn't need a cast.
450/// Or returns the cast argument if it needed a cast.
451/// Or returns 'Unknown' if it would need a cast but the callsite and the
452/// runtime definition don't match in terms of argument and parameter count.
453static SVal castArgToParamTypeIfNeeded(const CallEvent &Call, unsigned ArgIdx,
454 SVal ArgVal, SValBuilder &SVB) {
455 const auto *CallExprDecl = dyn_cast_or_null<FunctionDecl>(Call.getDecl());
456 if (!CallExprDecl)
457 return ArgVal;
458
459 const FunctionDecl *Definition = CallExprDecl;
460 Definition->hasBody(Definition);
461
462 // The function decl of the Call (in the AST) will not have any parameter
463 // declarations, if it was 'only' declared without a prototype. However, the
464 // engine will find the appropriate runtime definition - basically a
465 // redeclaration, which has a function body (and a function prototype).
466 if (CallExprDecl->hasPrototype() || !Definition->hasPrototype())
467 return ArgVal;
468
469 // Only do this cast if the number arguments at the callsite matches with
470 // the parameters at the runtime definition.
471 if (Call.getNumArgs() != Definition->getNumParams())
472 return UnknownVal();
473
474 const Expr *ArgExpr = Call.getArgExpr(ArgIdx);
475 const ParmVarDecl *Param = Definition->getParamDecl(ArgIdx);
476 return SVB.evalCast(ArgVal, Param->getType(), ArgExpr->getType());
477}
478
481 SValBuilder &SVB,
482 const CallEvent &Call,
483 ArrayRef<ParmVarDecl*> parameters) {
484 MemRegionManager &MRMgr = SVB.getRegionManager();
485
486 // If the function has fewer parameters than the call has arguments, we simply
487 // do not bind any values to them.
488 unsigned NumArgs = Call.getNumArgs();
489 unsigned Idx = 0;
490 ArrayRef<ParmVarDecl*>::iterator I = parameters.begin(), E = parameters.end();
491 for (; I != E && Idx < NumArgs; ++I, ++Idx) {
492 assert(*I && "Formal parameter has no decl?");
493
494 // TODO: Support allocator calls.
495 if (Call.getKind() != CE_CXXAllocator)
496 if (Call.isArgumentConstructedDirectly(Call.getASTArgumentIndex(Idx)))
497 continue;
498
499 // TODO: Allocators should receive the correct size and possibly alignment,
500 // determined in compile-time but not represented as arg-expressions,
501 // which makes getArgSVal() fail and return UnknownVal.
502 SVal ArgVal = Call.getArgSVal(Idx);
503 const Expr *ArgExpr = Call.getArgExpr(Idx);
504
505 if (ArgVal.isUnknown())
506 continue;
507
508 // Cast the argument value to match the type of the parameter in some
509 // edge-cases.
510 ArgVal = castArgToParamTypeIfNeeded(Call, Idx, ArgVal, SVB);
511
512 Loc ParamLoc = SVB.makeLoc(
513 MRMgr.getParamVarRegion(Call.getOriginExpr(), Idx, CalleeCtx));
514 Bindings.push_back(
515 std::make_pair(ParamLoc, processArgument(ArgVal, ArgExpr, *I, SVB)));
516 }
517
518 // FIXME: Variadic arguments are not handled at all right now.
519}
520
522 const StackFrameContext *StackFrame = getCalleeStackFrame(0);
523 if (!StackFrame)
524 return nullptr;
525
526 const CFGElement Element = StackFrame->getCallSiteCFGElement();
527 if (const auto Ctor = Element.getAs<CFGConstructor>()) {
528 return Ctor->getConstructionContext();
529 }
530
531 if (const auto RecCall = Element.getAs<CFGCXXRecordTypedCall>()) {
532 return RecCall->getConstructionContext();
533 }
534
535 return nullptr;
536}
537
539 const auto *CallLocationContext = this->getLocationContext();
540 if (!CallLocationContext || CallLocationContext->inTopFrame())
541 return nullptr;
542
543 const auto *CallStackFrameContext = CallLocationContext->getStackFrame();
544 if (!CallStackFrameContext)
545 return nullptr;
546
547 CallEventManager &CEMgr = State->getStateManager().getCallEventManager();
548 return CEMgr.getCaller(CallStackFrameContext, State);
549}
550
552 if (const CallEventRef<> Caller = getCaller())
553 return Caller->isInSystemHeader();
554
555 return false;
556}
557
559 const auto *CC = getConstructionContext();
560 if (!CC)
561 return std::nullopt;
562
563 EvalCallOptions CallOpts;
564 ExprEngine &Engine = getState()->getStateManager().getOwningEngine();
565 unsigned NumVisitedCall = Engine.getNumVisited(
566 getLocationContext(), getCFGElementRef().getParent());
567 SVal RetVal = Engine.computeObjectUnderConstruction(
568 getOriginExpr(), getState(), NumVisitedCall, getLocationContext(), CC,
569 CallOpts);
570 return RetVal;
571}
572
574 const FunctionDecl *D = getDecl();
575 if (!D)
576 return {};
577 return D->parameters();
578}
579
581 const FunctionDecl *FD = getDecl();
582 if (!FD)
583 return {};
584
585 // Note that the AnalysisDeclContext will have the FunctionDecl with
586 // the definition (if one exists).
589 getManager()->getContext(FD);
590 bool IsAutosynthesized;
591 Stmt* Body = AD->getBody(IsAutosynthesized);
592 LLVM_DEBUG({
593 if (IsAutosynthesized)
594 llvm::dbgs() << "Using autosynthesized body for " << FD->getName()
595 << "\n";
596 });
597
598 ExprEngine &Engine = getState()->getStateManager().getOwningEngine();
600 *Engine.getCrossTranslationUnitContext();
601
602 AnalyzerOptions &Opts = Engine.getAnalysisManager().options;
603
604 if (Body) {
605 const Decl* Decl = AD->getDecl();
606 if (Opts.IsNaiveCTUEnabled && CTUCtx.isImportedAsNew(Decl)) {
607 // A newly created definition, but we had error(s) during the import.
608 if (CTUCtx.hasError(Decl))
609 return {};
610 return RuntimeDefinition(Decl, /*Foreign=*/true);
611 }
612 return RuntimeDefinition(Decl, /*Foreign=*/false);
613 }
614
615 // Try to get CTU definition only if CTUDir is provided.
616 if (!Opts.IsNaiveCTUEnabled)
617 return {};
618
620 CTUCtx.getCrossTUDefinition(FD, Opts.CTUDir, Opts.CTUIndexName,
621 Opts.DisplayCTUProgress);
622
623 if (!CTUDeclOrError) {
624 handleAllErrors(CTUDeclOrError.takeError(),
625 [&](const cross_tu::IndexError &IE) {
626 auto Loc = getOriginExpr() ? getOriginExpr()->getExprLoc()
627 : FD->getLocation();
628 CTUCtx.emitCrossTUDiagnostics(IE, Loc);
629 });
630 return {};
631 }
632
633 return RuntimeDefinition(*CTUDeclOrError, /*Foreign=*/true);
634}
635
637 const StackFrameContext *CalleeCtx,
638 BindingsTy &Bindings) const {
639 const auto *D = cast<FunctionDecl>(CalleeCtx->getDecl());
640 SValBuilder &SVB = getState()->getStateManager().getSValBuilder();
641 addParameterValuesToBindings(CalleeCtx, Bindings, SVB, *this,
642 D->parameters());
643}
644
647 return true;
648
649 const FunctionDecl *D = getDecl();
650 if (!D)
651 return true;
652
653 const IdentifierInfo *II = D->getIdentifier();
654 if (!II)
655 return false;
656
657 // This set of "escaping" APIs is
658
659 // - 'int pthread_setspecific(ptheread_key k, const void *)' stores a
660 // value into thread local storage. The value can later be retrieved with
661 // 'void *ptheread_getspecific(pthread_key)'. So even thought the
662 // parameter is 'const void *', the region escapes through the call.
663 if (II->isStr("pthread_setspecific"))
664 return true;
665
666 // - xpc_connection_set_context stores a value which can be retrieved later
667 // with xpc_connection_get_context.
668 if (II->isStr("xpc_connection_set_context"))
669 return true;
670
671 // - funopen - sets a buffer for future IO calls.
672 if (II->isStr("funopen"))
673 return true;
674
675 // - __cxa_demangle - can reallocate memory and can return the pointer to
676 // the input buffer.
677 if (II->isStr("__cxa_demangle"))
678 return true;
679
680 StringRef FName = II->getName();
681
682 // - CoreFoundation functions that end with "NoCopy" can free a passed-in
683 // buffer even if it is const.
684 if (FName.ends_with("NoCopy"))
685 return true;
686
687 // - NSXXInsertXX, for example NSMapInsertIfAbsent, since they can
688 // be deallocated by NSMapRemove.
689 if (FName.starts_with("NS") && FName.contains("Insert"))
690 return true;
691
692 // - Many CF containers allow objects to escape through custom
693 // allocators/deallocators upon container construction. (PR12101)
694 if (FName.starts_with("CF") || FName.starts_with("CG")) {
695 return FName.contains_insensitive("InsertValue") ||
696 FName.contains_insensitive("AddValue") ||
697 FName.contains_insensitive("SetValue") ||
698 FName.contains_insensitive("WithData") ||
699 FName.contains_insensitive("AppendValue") ||
700 FName.contains_insensitive("SetAttribute");
701 }
702
703 return false;
704}
705
708 if (D)
709 return D;
710
712}
713
715 // Clang converts lambdas to function pointers using an implicit conversion
716 // operator, which returns the lambda's '__invoke' method. However, Sema
717 // leaves the body of '__invoke' empty (it is generated later in CodeGen), so
718 // we need to skip '__invoke' and access the lambda's operator() directly.
719 if (const auto *CMD = dyn_cast_if_present<CXXMethodDecl>(getDecl());
720 CMD && CMD->isLambdaStaticInvoker())
721 return RuntimeDefinition{CMD->getParent()->getLambdaCallOperator()};
722
724}
725
727 const auto *CE = cast_or_null<CallExpr>(getOriginExpr());
728 if (!CE)
730
731 const FunctionDecl *D = CE->getDirectCallee();
732 if (D)
733 return D;
734
735 return getSVal(CE->getCallee()).getAsFunctionDecl();
736}
737
739 ValueList &Values, RegionAndSymbolInvalidationTraits *ETraits) const {
740 SVal ThisVal = getCXXThisVal();
741 Values.push_back(ThisVal);
742
743 // Don't invalidate if the method is const and there are no mutable fields.
744 if (const auto *D = cast_or_null<CXXMethodDecl>(getDecl())) {
745 if (!D->isConst())
746 return;
747
748 // Get the record decl for the class of 'This'. D->getParent() may return
749 // a base class decl, rather than the class of the instance which needs to
750 // be checked for mutable fields.
751 const CXXRecordDecl *ParentRecord = getDeclForDynamicType().first;
752 if (!ParentRecord || !ParentRecord->hasDefinition())
753 return;
754
755 if (ParentRecord->hasMutableFields())
756 return;
757
758 // Preserve CXXThis.
759 const MemRegion *ThisRegion = ThisVal.getAsRegion();
760 if (!ThisRegion)
761 return;
762
763 ETraits->setTrait(ThisRegion->getBaseRegion(),
765 }
766}
767
769 const Expr *Base = getCXXThisExpr();
770 // FIXME: This doesn't handle an overloaded ->* operator.
771 SVal ThisVal = Base ? getSVal(Base) : UnknownVal();
772
773 if (isa<NonLoc>(ThisVal)) {
774 SValBuilder &SVB = getState()->getStateManager().getSValBuilder();
775 QualType OriginalTy = ThisVal.getType(SVB.getContext());
776 return SVB.evalCast(ThisVal, Base->getType(), OriginalTy);
777 }
778
779 assert(ThisVal.isUnknownOrUndef() || isa<Loc>(ThisVal));
780 return ThisVal;
781}
782
783std::pair<const CXXRecordDecl *, bool>
785 const MemRegion *R = getCXXThisVal().getAsRegion();
786 if (!R)
787 return {};
788
790 if (!DynType.isValid())
791 return {};
792
793 assert(!DynType.getType()->getPointeeType().isNull());
794 return {DynType.getType()->getPointeeCXXRecordDecl(),
795 DynType.canBeASubClass()};
796}
797
799 // Do we have a decl at all?
800 const Decl *D = getDecl();
801 if (!D)
802 return {};
803
804 // If the method is non-virtual, we know we can inline it.
805 const auto *MD = cast<CXXMethodDecl>(D);
806 if (!MD->isVirtual())
808
809 auto [RD, CanBeSubClass] = getDeclForDynamicType();
810 if (!RD || !RD->hasDefinition())
811 return {};
812
813 // Find the decl for this method in that class.
814 const CXXMethodDecl *Result = MD->getCorrespondingMethodInClass(RD, true);
815 if (!Result) {
816 // We might not even get the original statically-resolved method due to
817 // some particularly nasty casting (e.g. casts to sister classes).
818 // However, we should at least be able to search up and down our own class
819 // hierarchy, and some real bugs have been caught by checking this.
820 assert(!RD->isDerivedFrom(MD->getParent()) && "Couldn't find known method");
821
822 // FIXME: This is checking that our DynamicTypeInfo is at least as good as
823 // the static type. However, because we currently don't update
824 // DynamicTypeInfo when an object is cast, we can't actually be sure the
825 // DynamicTypeInfo is up to date. This assert should be re-enabled once
826 // this is fixed.
827 //
828 // assert(!MD->getParent()->isDerivedFrom(RD) && "Bad DynamicTypeInfo");
829
830 return {};
831 }
832
833 // Does the decl that we found have an implementation?
835 if (!Result->hasBody(Definition)) {
836 if (!CanBeSubClass)
838 return {};
839 }
840
841 // We found a definition. If we're not sure that this devirtualization is
842 // actually what will happen at runtime, make sure to provide the region so
843 // that ExprEngine can decide what to do with it.
844 if (CanBeSubClass)
846 getCXXThisVal().getAsRegion()->StripCasts());
847 return RuntimeDefinition(Definition, /*DispatchRegion=*/nullptr);
848}
849
851 const StackFrameContext *CalleeCtx,
852 BindingsTy &Bindings) const {
854
855 // Handle the binding of 'this' in the new stack frame.
856 SVal ThisVal = getCXXThisVal();
857 if (!ThisVal.isUnknown()) {
858 ProgramStateManager &StateMgr = getState()->getStateManager();
859 SValBuilder &SVB = StateMgr.getSValBuilder();
860
861 const auto *MD = cast<CXXMethodDecl>(CalleeCtx->getDecl());
862 Loc ThisLoc = SVB.getCXXThis(MD, CalleeCtx);
863
864 // If we devirtualized to a different member function, we need to make sure
865 // we have the proper layering of CXXBaseObjectRegions.
866 if (MD->getCanonicalDecl() != getDecl()->getCanonicalDecl()) {
867 ASTContext &Ctx = SVB.getContext();
868 const CXXRecordDecl *Class = MD->getParent();
870
871 // FIXME: CallEvent maybe shouldn't be directly accessing StoreManager.
872 std::optional<SVal> V =
873 StateMgr.getStoreManager().evalBaseToDerived(ThisVal, Ty);
874 if (!V) {
875 // We might have suffered some sort of placement new earlier, so
876 // we're constructing in a completely unexpected storage.
877 // Fall back to a generic pointer cast for this-value.
878 const CXXMethodDecl *StaticMD = cast<CXXMethodDecl>(getDecl());
879 const CXXRecordDecl *StaticClass = StaticMD->getParent();
880 CanQualType StaticTy =
881 Ctx.getPointerType(Ctx.getCanonicalTagType(StaticClass));
882 ThisVal = SVB.evalCast(ThisVal, Ty, StaticTy);
883 } else
884 ThisVal = *V;
885 }
886
887 if (!ThisVal.isUnknown())
888 Bindings.push_back(std::make_pair(ThisLoc, ThisVal));
889 }
890}
891
895
897 // C++11 [expr.call]p1: ...If the selected function is non-virtual, or if the
898 // id-expression in the class member access expression is a qualified-id,
899 // that function is called. Otherwise, its final overrider in the dynamic type
900 // of the object expression is called.
901 if (const auto *ME = dyn_cast<MemberExpr>(getOriginExpr()->getCallee()))
902 if (ME->hasQualifier())
904
906}
907
909 return getOriginExpr()->getArg(0);
910}
911
913 const Expr *Callee = getOriginExpr()->getCallee();
914 const MemRegion *DataReg = getSVal(Callee).getAsRegion();
915
916 return dyn_cast_or_null<BlockDataRegion>(DataReg);
917}
918
920 const BlockDecl *D = getDecl();
921 if (!D)
922 return {};
923 return D->parameters();
924}
925
927 RegionAndSymbolInvalidationTraits *ETraits) const {
928 // FIXME: This also needs to invalidate captured globals.
929 if (const MemRegion *R = getBlockRegion())
930 Values.push_back(loc::MemRegionVal(R));
931}
932
934 BindingsTy &Bindings) const {
935 SValBuilder &SVB = getState()->getStateManager().getSValBuilder();
938 auto *LambdaOperatorDecl = cast<CXXMethodDecl>(CalleeCtx->getDecl());
939 Params = LambdaOperatorDecl->parameters();
940
941 // For blocks converted from a C++ lambda, the callee declaration is the
942 // operator() method on the lambda so we bind "this" to
943 // the lambda captured by the block.
944 const VarRegion *CapturedLambdaRegion = getRegionStoringCapturedLambda();
945 SVal ThisVal = loc::MemRegionVal(CapturedLambdaRegion);
946 Loc ThisLoc = SVB.getCXXThis(LambdaOperatorDecl, CalleeCtx);
947 Bindings.push_back(std::make_pair(ThisLoc, ThisVal));
948 } else {
949 Params = cast<BlockDecl>(CalleeCtx->getDecl())->parameters();
950 }
951
952 addParameterValuesToBindings(CalleeCtx, Bindings, SVB, *this,
953 Params);
954}
955
957 if (Data)
958 return loc::MemRegionVal(static_cast<const MemRegion *>(Data));
959 return UnknownVal();
960}
961
963 RegionAndSymbolInvalidationTraits *ETraits) const {
964 SVal V = getCXXThisVal();
965 if (SymbolRef Sym = V.getAsSymbol(true))
966 ETraits->setTrait(Sym,
968
969 // Standard classes don't reinterpret-cast and modify super regions.
970 const bool IsStdClassCtor = isWithinStdNamespace(getDecl());
971 if (const MemRegion *Obj = V.getAsRegion(); Obj && IsStdClassCtor) {
972 ETraits->setTrait(
974 }
975
976 Values.push_back(V);
977}
978
980 const StackFrameContext *CalleeCtx,
981 BindingsTy &Bindings) const {
983
984 SVal ThisVal = getCXXThisVal();
985 if (!ThisVal.isUnknown()) {
986 SValBuilder &SVB = getState()->getStateManager().getSValBuilder();
987 const auto *MD = cast<CXXMethodDecl>(CalleeCtx->getDecl());
988 Loc ThisLoc = SVB.getCXXThis(MD, CalleeCtx);
989 Bindings.push_back(std::make_pair(ThisLoc, ThisVal));
990 }
991}
992
993const StackFrameContext *
1000
1002 if (Data)
1003 return loc::MemRegionVal(DtorDataTy::getFromOpaqueValue(Data).getPointer());
1004 return UnknownVal();
1005}
1006
1008 // Base destructors are always called non-virtually.
1009 // Skip CXXInstanceCall's devirtualization logic in this case.
1010 if (isBaseDestructor())
1012
1014}
1015
1017 const ObjCMethodDecl *D = getDecl();
1018 if (!D)
1019 return {};
1020 return D->parameters();
1021}
1022
1024 ValueList &Values, RegionAndSymbolInvalidationTraits *ETraits) const {
1025
1026 // If the method call is a setter for property known to be backed by
1027 // an instance variable, don't invalidate the entire receiver, just
1028 // the storage for that instance variable.
1029 if (const ObjCPropertyDecl *PropDecl = getAccessedProperty()) {
1030 if (const ObjCIvarDecl *PropIvar = PropDecl->getPropertyIvarDecl()) {
1031 SVal IvarLVal = getState()->getLValue(PropIvar, getReceiverSVal());
1032 if (const MemRegion *IvarRegion = IvarLVal.getAsRegion()) {
1033 ETraits->setTrait(
1034 IvarRegion,
1036 ETraits->setTrait(
1037 IvarRegion,
1039 Values.push_back(IvarLVal);
1040 }
1041 return;
1042 }
1043 }
1044
1045 Values.push_back(getReceiverSVal());
1046}
1047
1049 // FIXME: Is this the best way to handle class receivers?
1050 if (!isInstanceMessage())
1051 return UnknownVal();
1052
1053 if (const Expr *RecE = getOriginExpr()->getInstanceReceiver())
1054 return getSVal(RecE);
1055
1056 // An instance message with no expression means we are sending to super.
1057 // In this case the object reference is the same as 'self'.
1058 assert(getOriginExpr()->getReceiverKind() == ObjCMessageExpr::SuperInstance);
1059 SVal SelfVal = getState()->getSelfSVal(getLocationContext());
1060 assert(SelfVal.isValid() && "Calling super but not in ObjC method");
1061 return SelfVal;
1062}
1063
1065 if (getOriginExpr()->getReceiverKind() == ObjCMessageExpr::SuperInstance ||
1066 getOriginExpr()->getReceiverKind() == ObjCMessageExpr::SuperClass)
1067 return true;
1068
1069 if (!isInstanceMessage())
1070 return false;
1071
1072 SVal RecVal = getSVal(getOriginExpr()->getInstanceReceiver());
1073 SVal SelfVal = getState()->getSelfSVal(getLocationContext());
1074
1075 return (RecVal == SelfVal);
1076}
1077
1079 switch (getMessageKind()) {
1080 case OCM_Message:
1081 return getOriginExpr()->getSourceRange();
1082 case OCM_PropertyAccess:
1083 case OCM_Subscript:
1084 return getContainingPseudoObjectExpr()->getSourceRange();
1085 }
1086 llvm_unreachable("unknown message kind");
1087}
1088
1089using ObjCMessageDataTy = llvm::PointerIntPair<const PseudoObjectExpr *, 2>;
1090
1091const PseudoObjectExpr *ObjCMethodCall::getContainingPseudoObjectExpr() const {
1092 assert(Data && "Lazy lookup not yet performed.");
1093 assert(getMessageKind() != OCM_Message && "Explicit message send.");
1094 return ObjCMessageDataTy::getFromOpaqueValue(Data).getPointer();
1095}
1096
1097static const Expr *
1099 const Expr *Syntactic = POE->getSyntacticForm()->IgnoreParens();
1100
1101 // This handles the funny case of assigning to the result of a getter.
1102 // This can happen if the getter returns a non-const reference.
1103 if (const auto *BO = dyn_cast<BinaryOperator>(Syntactic))
1104 Syntactic = BO->getLHS()->IgnoreParens();
1105
1106 return Syntactic;
1107}
1108
1110 if (!Data) {
1111 // Find the parent, ignoring implicit casts.
1112 const ParentMap &PM = getLocationContext()->getParentMap();
1114
1115 // Check if parent is a PseudoObjectExpr.
1116 if (const auto *POE = dyn_cast_or_null<PseudoObjectExpr>(S)) {
1117 const Expr *Syntactic = getSyntacticFromForPseudoObjectExpr(POE);
1118
1120 switch (Syntactic->getStmtClass()) {
1121 case Stmt::ObjCPropertyRefExprClass:
1123 break;
1124 case Stmt::ObjCSubscriptRefExprClass:
1125 K = OCM_Subscript;
1126 break;
1127 default:
1128 // FIXME: Can this ever happen?
1129 K = OCM_Message;
1130 break;
1131 }
1132
1133 if (K != OCM_Message) {
1134 const_cast<ObjCMethodCall *>(this)->Data
1135 = ObjCMessageDataTy(POE, K).getOpaqueValue();
1136 assert(getMessageKind() == K);
1137 return K;
1138 }
1139 }
1140
1141 const_cast<ObjCMethodCall *>(this)->Data
1142 = ObjCMessageDataTy(nullptr, 1).getOpaqueValue();
1143 assert(getMessageKind() == OCM_Message);
1144 return OCM_Message;
1145 }
1146
1147 ObjCMessageDataTy Info = ObjCMessageDataTy::getFromOpaqueValue(Data);
1148 if (!Info.getPointer())
1149 return OCM_Message;
1150 return static_cast<ObjCMessageKind>(Info.getInt());
1151}
1152
1154 // Look for properties accessed with property syntax (foo.bar = ...)
1156 const PseudoObjectExpr *POE = getContainingPseudoObjectExpr();
1157 assert(POE && "Property access without PseudoObjectExpr?");
1158
1159 const Expr *Syntactic = getSyntacticFromForPseudoObjectExpr(POE);
1160 auto *RefExpr = cast<ObjCPropertyRefExpr>(Syntactic);
1161
1162 if (RefExpr->isExplicitProperty())
1163 return RefExpr->getExplicitProperty();
1164 }
1165
1166 // Look for properties accessed with method syntax ([foo setBar:...]).
1167 const ObjCMethodDecl *MD = getDecl();
1168 if (!MD || !MD->isPropertyAccessor())
1169 return nullptr;
1170
1171 // Note: This is potentially quite slow.
1172 return MD->findPropertyDecl();
1173}
1174
1176 Selector Sel) const {
1177 assert(IDecl);
1178 AnalysisManager &AMgr =
1179 getState()->getStateManager().getOwningEngine().getAnalysisManager();
1180 // If the class interface is declared inside the main file, assume it is not
1181 // subcassed.
1182 // TODO: It could actually be subclassed if the subclass is private as well.
1183 // This is probably very rare.
1184 SourceLocation InterfLoc = IDecl->getEndOfDefinitionLoc();
1185 if (InterfLoc.isValid() && AMgr.isInCodeFile(InterfLoc))
1186 return false;
1187
1188 // Assume that property accessors are not overridden.
1190 return false;
1191
1192 // We assume that if the method is public (declared outside of main file) or
1193 // has a parent which publicly declares the method, the method could be
1194 // overridden in a subclass.
1195
1196 // Find the first declaration in the class hierarchy that declares
1197 // the selector.
1198 ObjCMethodDecl *D = nullptr;
1199 while (true) {
1200 D = IDecl->lookupMethod(Sel, true);
1201
1202 // Cannot find a public definition.
1203 if (!D)
1204 return false;
1205
1206 // If outside the main file,
1207 if (D->getLocation().isValid() && !AMgr.isInCodeFile(D->getLocation()))
1208 return true;
1209
1210 if (D->isOverriding()) {
1211 // Search in the superclass on the next iteration.
1212 IDecl = D->getClassInterface();
1213 if (!IDecl)
1214 return false;
1215
1216 IDecl = IDecl->getSuperClass();
1217 if (!IDecl)
1218 return false;
1219
1220 continue;
1221 }
1222
1223 return false;
1224 };
1225
1226 llvm_unreachable("The while loop should always terminate.");
1227}
1228
1230 if (!MD)
1231 return MD;
1232
1233 // Find the redeclaration that defines the method.
1234 if (!MD->hasBody()) {
1235 for (auto *I : MD->redecls())
1236 if (I->hasBody())
1237 MD = cast<ObjCMethodDecl>(I);
1238 }
1239 return MD;
1240}
1241
1247
1248namespace llvm {
1249template <> struct DenseMapInfo<PrivateMethodKey> {
1250 using InterfaceInfo = DenseMapInfo<const ObjCInterfaceDecl *>;
1251 using SelectorInfo = DenseMapInfo<Selector>;
1252
1254 return {InterfaceInfo::getEmptyKey(), SelectorInfo::getEmptyKey(), false};
1255 }
1256
1258 return {InterfaceInfo::getTombstoneKey(), SelectorInfo::getTombstoneKey(),
1259 true};
1260 }
1261
1262 static unsigned getHashValue(const PrivateMethodKey &Key) {
1263 return llvm::hash_combine(
1264 llvm::hash_code(InterfaceInfo::getHashValue(Key.Interface)),
1265 llvm::hash_code(SelectorInfo::getHashValue(Key.LookupSelector)),
1266 Key.IsClassMethod);
1267 }
1268
1269 static bool isEqual(const PrivateMethodKey &LHS,
1270 const PrivateMethodKey &RHS) {
1271 return InterfaceInfo::isEqual(LHS.Interface, RHS.Interface) &&
1272 SelectorInfo::isEqual(LHS.LookupSelector, RHS.LookupSelector) &&
1273 LHS.IsClassMethod == RHS.IsClassMethod;
1274 }
1275};
1276} // end namespace llvm
1277
1278// NOTE: This cache is a "global" variable, and it is cleared by
1279// CallEventManager's constructor so we do not keep old entries when
1280// loading/unloading ASTs. If we are worried about concurrency, we may need to
1281// revisit this someday. In terms of memory, this table stays around until clang
1282// quits, which also may be bad if we need to release memory.
1284 llvm::DenseMap<PrivateMethodKey, std::optional<const ObjCMethodDecl *>>;
1286
1287static const ObjCMethodDecl *
1289 Selector LookupSelector, bool InstanceMethod) {
1290 // Repeatedly calling lookupPrivateMethod() is expensive, especially
1291 // when in many cases it returns null. We cache the results so
1292 // that repeated queries on the same ObjCIntefaceDecl and Selector
1293 // don't incur the same cost. On some test cases, we can see the
1294 // same query being issued thousands of times.
1295 std::optional<const ObjCMethodDecl *> &Val =
1296 PrivateMethodCache[{Interface, LookupSelector, InstanceMethod}];
1297
1298 // Query lookupPrivateMethod() if the cache does not hit.
1299 if (!Val) {
1300 Val = Interface->lookupPrivateMethod(LookupSelector, InstanceMethod);
1301
1302 if (!*Val) {
1303 // Query 'lookupMethod' as a backup.
1304 Val = Interface->lookupMethod(LookupSelector, InstanceMethod);
1305 }
1306 }
1307
1308 return *Val;
1309}
1310
1312 const ObjCMessageExpr *E = getOriginExpr();
1313 assert(E);
1314 Selector Sel = E->getSelector();
1315
1316 if (E->isInstanceMessage()) {
1317 // Find the receiver type.
1318 const ObjCObjectType *ReceiverT = nullptr;
1319 bool CanBeSubClassed = false;
1320 bool LookingForInstanceMethod = true;
1321 QualType SupersType = E->getSuperType();
1322 const MemRegion *Receiver = nullptr;
1323
1324 if (!SupersType.isNull()) {
1325 // The receiver is guaranteed to be 'super' in this case.
1326 // Super always means the type of immediate predecessor to the method
1327 // where the call occurs.
1328 ReceiverT = cast<ObjCObjectPointerType>(SupersType)->getObjectType();
1329 } else {
1330 Receiver = getReceiverSVal().getAsRegion();
1331 if (!Receiver)
1332 return {};
1333
1334 DynamicTypeInfo DTI = getDynamicTypeInfo(getState(), Receiver);
1335 if (!DTI.isValid()) {
1336 assert(isa<AllocaRegion>(Receiver) &&
1337 "Unhandled untyped region class!");
1338 return {};
1339 }
1340
1341 QualType DynType = DTI.getType();
1342 CanBeSubClassed = DTI.canBeASubClass();
1343
1344 const auto *ReceiverDynT =
1345 dyn_cast<ObjCObjectPointerType>(DynType.getCanonicalType());
1346
1347 if (ReceiverDynT) {
1348 ReceiverT = ReceiverDynT->getObjectType();
1349
1350 // It can be actually class methods called with Class object as a
1351 // receiver. This type of messages is treated by the compiler as
1352 // instance (not class).
1353 if (ReceiverT->isObjCClass()) {
1354
1355 SVal SelfVal = getState()->getSelfSVal(getLocationContext());
1356 // For [self classMethod], return compiler visible declaration.
1357 if (Receiver == SelfVal.getAsRegion()) {
1359 }
1360
1361 // Otherwise, let's check if we know something about the type
1362 // inside of this class object.
1363 if (SymbolRef ReceiverSym = getReceiverSVal().getAsSymbol()) {
1364 DynamicTypeInfo DTI =
1366 if (DTI.isValid()) {
1367 // Let's use this type for lookup.
1368 ReceiverT =
1370
1371 CanBeSubClassed = DTI.canBeASubClass();
1372 // And it should be a class method instead.
1373 LookingForInstanceMethod = false;
1374 }
1375 }
1376 }
1377
1378 if (CanBeSubClassed)
1379 if (ObjCInterfaceDecl *IDecl = ReceiverT->getInterface())
1380 // Even if `DynamicTypeInfo` told us that it can be
1381 // not necessarily this type, but its descendants, we still want
1382 // to check again if this selector can be actually overridden.
1383 CanBeSubClassed = canBeOverridenInSubclass(IDecl, Sel);
1384 }
1385 }
1386
1387 // Lookup the instance method implementation.
1388 if (ReceiverT)
1389 if (ObjCInterfaceDecl *IDecl = ReceiverT->getInterface()) {
1390 const ObjCMethodDecl *MD =
1391 lookupRuntimeDefinition(IDecl, Sel, LookingForInstanceMethod);
1392
1393 if (MD && !MD->hasBody())
1394 MD = MD->getCanonicalDecl();
1395
1396 if (CanBeSubClassed)
1397 return RuntimeDefinition(MD, Receiver);
1398 else
1399 return RuntimeDefinition(MD, nullptr);
1400 }
1401 } else {
1402 // This is a class method.
1403 // If we have type info for the receiver class, we are calling via
1404 // class name.
1405 if (ObjCInterfaceDecl *IDecl = E->getReceiverInterface()) {
1406 // Find/Return the method implementation.
1407 return RuntimeDefinition(IDecl->lookupPrivateClassMethod(Sel));
1408 }
1409 }
1410
1411 return {};
1412}
1413
1415 if (isInSystemHeader() && !isInstanceMessage()) {
1416 Selector Sel = getSelector();
1417 if (Sel.getNumArgs() == 1 &&
1418 Sel.getIdentifierInfoForSlot(0)->isStr("valueWithPointer"))
1419 return true;
1420 }
1421
1423}
1424
1426 const StackFrameContext *CalleeCtx,
1427 BindingsTy &Bindings) const {
1428 const auto *D = cast<ObjCMethodDecl>(CalleeCtx->getDecl());
1429 SValBuilder &SVB = getState()->getStateManager().getSValBuilder();
1430 addParameterValuesToBindings(CalleeCtx, Bindings, SVB, *this,
1431 D->parameters());
1432
1433 SVal SelfVal = getReceiverSVal();
1434 if (!SelfVal.isUnknown()) {
1435 const VarDecl *SelfD = CalleeCtx->getAnalysisDeclContext()->getSelfDecl();
1436 MemRegionManager &MRMgr = SVB.getRegionManager();
1437 Loc SelfLoc = SVB.makeLoc(MRMgr.getVarRegion(SelfD, CalleeCtx));
1438 Bindings.push_back(std::make_pair(SelfLoc, SelfVal));
1439 }
1440}
1441
1442CallEventManager::CallEventManager(llvm::BumpPtrAllocator &alloc)
1443 : Alloc(alloc) {
1444 // Clear the method cache to avoid hits when multiple AST are loaded/unloaded
1445 // within a single process. This can happen with unit tests, for instance.
1446 PrivateMethodCache.clear();
1447}
1448
1451 const LocationContext *LCtx,
1453 if (const auto *MCE = dyn_cast<CXXMemberCallExpr>(CE))
1454 return create<CXXMemberCall>(MCE, State, LCtx, ElemRef);
1455
1456 if (const auto *OpCE = dyn_cast<CXXOperatorCallExpr>(CE)) {
1457 const FunctionDecl *DirectCallee = OpCE->getDirectCallee();
1458 if (const auto *MD = dyn_cast<CXXMethodDecl>(DirectCallee)) {
1459 if (MD->isImplicitObjectMemberFunction())
1460 return create<CXXMemberOperatorCall>(OpCE, State, LCtx, ElemRef);
1461 if (MD->isStatic())
1462 return create<CXXStaticOperatorCall>(OpCE, State, LCtx, ElemRef);
1463 }
1464
1465 } else if (CE->getCallee()->getType()->isBlockPointerType()) {
1466 return create<BlockCall>(CE, State, LCtx, ElemRef);
1467 }
1468
1469 // Otherwise, it's a normal function call, static member function call, or
1470 // something we can't reason about.
1471 return create<SimpleFunctionCall>(CE, State, LCtx, ElemRef);
1472}
1473
1476 ProgramStateRef State) {
1477 const LocationContext *ParentCtx = CalleeCtx->getParent();
1478 const LocationContext *CallerCtx = ParentCtx->getStackFrame();
1479 CFGBlock::ConstCFGElementRef ElemRef = {CalleeCtx->getCallSiteBlock(),
1480 CalleeCtx->getIndex()};
1481 assert(CallerCtx && "This should not be used for top-level stack frames");
1482
1483 const Stmt *CallSite = CalleeCtx->getCallSite();
1484
1485 if (CallSite) {
1486 if (CallEventRef<> Out = getCall(CallSite, State, CallerCtx, ElemRef))
1487 return Out;
1488
1489 SValBuilder &SVB = State->getStateManager().getSValBuilder();
1490 const auto *Ctor = cast<CXXMethodDecl>(CalleeCtx->getDecl());
1491 Loc ThisPtr = SVB.getCXXThis(Ctor, CalleeCtx);
1492 SVal ThisVal = State->getSVal(ThisPtr);
1493
1494 if (const auto *CE = dyn_cast<CXXConstructExpr>(CallSite))
1495 return getCXXConstructorCall(CE, ThisVal.getAsRegion(), State, CallerCtx,
1496 ElemRef);
1497 else if (const auto *CIE = dyn_cast<CXXInheritedCtorInitExpr>(CallSite))
1498 return getCXXInheritedConstructorCall(CIE, ThisVal.getAsRegion(), State,
1499 CallerCtx, ElemRef);
1500 else {
1501 // All other cases are handled by getCall.
1502 llvm_unreachable("This is not an inlineable statement");
1503 }
1504 }
1505
1506 // Fall back to the CFG. The only thing we haven't handled yet is
1507 // destructors, though this could change in the future.
1508 const CFGBlock *B = CalleeCtx->getCallSiteBlock();
1509 CFGElement E = (*B)[CalleeCtx->getIndex()];
1510 assert((E.getAs<CFGImplicitDtor>() || E.getAs<CFGTemporaryDtor>()) &&
1511 "All other CFG elements should have exprs");
1512
1513 SValBuilder &SVB = State->getStateManager().getSValBuilder();
1514 const auto *Dtor = cast<CXXDestructorDecl>(CalleeCtx->getDecl());
1515 Loc ThisPtr = SVB.getCXXThis(Dtor, CalleeCtx);
1516 SVal ThisVal = State->getSVal(ThisPtr);
1517
1518 const Stmt *Trigger;
1519 if (std::optional<CFGAutomaticObjDtor> AutoDtor =
1521 Trigger = AutoDtor->getTriggerStmt();
1522 else if (std::optional<CFGDeleteDtor> DeleteDtor = E.getAs<CFGDeleteDtor>())
1523 Trigger = DeleteDtor->getDeleteExpr();
1524 else
1525 Trigger = Dtor->getBody();
1526
1527 return getCXXDestructorCall(Dtor, Trigger, ThisVal.getAsRegion(),
1528 E.getAs<CFGBaseDtor>().has_value(), State,
1529 CallerCtx, ElemRef);
1530}
1531
1533 const LocationContext *LC,
1535 if (const auto *CE = dyn_cast<CallExpr>(S)) {
1536 return getSimpleCall(CE, State, LC, ElemRef);
1537 } else if (const auto *NE = dyn_cast<CXXNewExpr>(S)) {
1538 return getCXXAllocatorCall(NE, State, LC, ElemRef);
1539 } else if (const auto *DE = dyn_cast<CXXDeleteExpr>(S)) {
1540 return getCXXDeallocatorCall(DE, State, LC, ElemRef);
1541 } else if (const auto *ME = dyn_cast<ObjCMessageExpr>(S)) {
1542 return getObjCMethodCall(ME, State, LC, ElemRef);
1543 } else {
1544 return nullptr;
1545 }
1546}
Defines the clang::ASTContext interface.
#define V(N, I)
This file defines AnalysisDeclContext, a class that manages the analysis context data for context sen...
static bool isZeroConstant(const llvm::Value *Value)
static bool isVoidPointerToNonConst(QualType T)
static const ObjCMethodDecl * findDefiningRedecl(const ObjCMethodDecl *MD)
static const ObjCMethodDecl * lookupRuntimeDefinition(const ObjCInterfaceDecl *Interface, Selector LookupSelector, bool InstanceMethod)
static const MemRegion * getThisRegionBaseOrNull(const CallEvent &Call)
static void addParameterValuesToBindings(const StackFrameContext *CalleeCtx, CallEvent::BindingsTy &Bindings, SValBuilder &SVB, const CallEvent &Call, ArrayRef< ParmVarDecl * > parameters)
static const Expr * getSyntacticFromForPseudoObjectExpr(const PseudoObjectExpr *POE)
static bool isTransparentUnion(QualType T)
llvm::PointerIntPair< const PseudoObjectExpr *, 2 > ObjCMessageDataTy
static bool isCallback(QualType T)
Definition CallEvent.cpp:78
static SVal castArgToParamTypeIfNeeded(const CallEvent &Call, unsigned ArgIdx, SVal ArgVal, SValBuilder &SVB)
Cast the argument value to the type of the parameter at the function declaration.
llvm::DenseMap< PrivateMethodKey, std::optional< const ObjCMethodDecl * > > PrivateMethodCacheTy
static SVal processArgument(SVal Value, const Expr *ArgumentExpr, const ParmVarDecl *Parameter, SValBuilder &SVB)
static PrivateMethodCacheTy PrivateMethodCache
static void findPtrToConstParams(llvm::SmallSet< unsigned, 4 > &PreserveArgs, const CallEvent &Call)
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the clang::Expr interface and subclasses for C++ expressions.
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
static const Decl * getCanonicalDecl(const Decl *D)
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
llvm::SmallVector< std::pair< const MemRegion *, SVal >, 4 > Bindings
Defines the clang::SourceLocation class and associated facilities.
Defines various enumerations that describe declaration and type specifiers.
C Language Family Type Representation.
static bool isPointerToConst(const QualType &QT)
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition ASTContext.h:226
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
QualType getReferenceQualifiedType(const Expr *e) const
getReferenceQualifiedType - Given an expr, will return the type for that expression,...
const clang::PrintingPolicy & getPrintingPolicy() const
Definition ASTContext.h:851
CanQualType VoidTy
CanQualType getCanonicalTagType(const TagDecl *TD) const
AnalysisDeclContext * getContext(const Decl *D)
const StackFrameContext * getStackFrame(const Decl *D)
Obtain the beginning context of the analysis.
AnalysisDeclContext contains the context data for the function, method or block under analysis.
const ImplicitParamDecl * getSelfDecl() const
AnalysisDeclContextManager * getManager() const
Stores options for the analyzer from the command line.
Represents a block literal declaration, which is like an unnamed FunctionDecl.
Definition Decl.h:4689
ArrayRef< ParmVarDecl * > parameters() const
Definition Decl.h:4775
Represents C++ object destructor implicitly generated for automatic object or temporary bound to cons...
Definition CFG.h:445
Represents C++ object destructor implicitly generated for base object in destructor.
Definition CFG.h:496
Represents a single basic block in a source-level CFG.
Definition CFG.h:632
unsigned size() const
Definition CFG.h:979
ElementRefImpl< true > ConstCFGElementRef
Definition CFG.h:948
Represents a function call that returns a C++ object by value.
Definition CFG.h:187
Represents C++ constructor call.
Definition CFG.h:158
Represents C++ object destructor generated from a call to delete.
Definition CFG.h:470
Represents a top-level expression in a basic block.
Definition CFG.h:55
std::optional< T > getAs() const
Convert to the specified CFGElement type, returning std::nullopt if this CFGElement is not of the des...
Definition CFG.h:110
Represents C++ object destructor implicitly generated by compiler on various occasions.
Definition CFG.h:394
const CFGBlock * getBlock(const Stmt *S) const
Returns the CFGBlock the specified Stmt* appears in.
Represents C++ object destructor implicitly generated at the end of full expression for temporary obj...
Definition CFG.h:538
Expr * getImplicitObjectArgument() const
Retrieve the implicit object argument for the member call.
Definition ExprCXX.cpp:722
Represents a static or instance method of a struct/union/class.
Definition DeclCXX.h:2136
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined.
Definition DeclCXX.h:2262
Represents a C++ struct/union/class.
Definition DeclCXX.h:258
bool hasMutableFields() const
Determine whether this class, or any of its class subobjects, contains a mutable field.
Definition DeclCXX.h:1233
bool hasDefinition() const
Definition DeclCXX.h:561
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Definition Expr.h:2946
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
Definition Expr.h:3150
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return null.
Definition Expr.h:3129
Expr * getCallee()
Definition Expr.h:3093
ConstructionContext's subclasses describe different ways of constructing an object in C++.
Decl - This represents one declaration (or definition), e.g.
Definition DeclBase.h:86
SourceLocation getLocation() const
Definition DeclBase.h:439
redecl_range redecls() const
Returns an iterator range for all the redeclarations of the same decl.
Definition DeclBase.h:1049
This represents one expression.
Definition Expr.h:112
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
Definition Expr.cpp:3086
QualType getType() const
Definition Expr.h:144
Represents a function declaration or definition.
Definition Decl.h:2015
ArrayRef< ParmVarDecl * > parameters() const
Definition Decl.h:2789
FunctionType - C99 6.7.5.3 - Function Declarators.
Definition TypeBase.h:4553
One of these records is kept for each identifier that is lexed.
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
StringRef getName() const
Return the actual identifier string.
It wraps the AnalysisDeclContext to represent both the call stack with the help of StackFrameContext ...
const Decl * getDecl() const
const ParentMap & getParentMap() const
LLVM_ATTRIBUTE_RETURNS_NONNULL AnalysisDeclContext * getAnalysisDeclContext() const
const LocationContext * getParent() const
It might return null.
const StackFrameContext * getStackFrame() const
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Definition Decl.h:295
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Definition Decl.h:301
Represents an ObjC class declaration.
Definition DeclObjC.h:1154
ObjCMethodDecl * lookupMethod(Selector Sel, bool isInstance, bool shallowCategoryLookup=false, bool followSuper=true, const ObjCCategoryDecl *C=nullptr) const
lookupMethod - This method returns an instance/class method by looking in the class,...
Definition DeclObjC.cpp:696
SourceLocation getEndOfDefinitionLoc() const
Definition DeclObjC.h:1878
ObjCInterfaceDecl * getSuperClass() const
Definition DeclObjC.cpp:349
ObjCIvarDecl - Represents an ObjC instance variable.
Definition DeclObjC.h:1952
An expression that sends a message to the given Objective-C object or class.
Definition ExprObjC.h:971
Selector getSelector() const
Definition ExprObjC.cpp:301
@ SuperInstance
The receiver is the instance of the superclass object.
Definition ExprObjC.h:985
@ SuperClass
The receiver is a superclass.
Definition ExprObjC.h:982
bool isInstanceMessage() const
Determine whether this is an instance message to either a computed object or to super.
Definition ExprObjC.h:1287
ObjCInterfaceDecl * getReceiverInterface() const
Retrieve the Objective-C interface to which this message is being directed, if known.
Definition ExprObjC.cpp:322
QualType getSuperType() const
Retrieve the type referred to by 'super'.
Definition ExprObjC.h:1375
const ObjCMethodDecl * getMethodDecl() const
Definition ExprObjC.h:1395
ObjCMethodDecl - Represents an instance or class method declaration.
Definition DeclObjC.h:140
bool hasBody() const override
Determine whether this method has a body.
Definition DeclObjC.h:523
bool isOverriding() const
Whether this method overrides any other in the class hierarchy.
Definition DeclObjC.h:462
ArrayRef< ParmVarDecl * > parameters() const
Definition DeclObjC.h:373
bool isPropertyAccessor() const
Definition DeclObjC.h:436
const ObjCPropertyDecl * findPropertyDecl(bool CheckOverrides=true) const
Returns the property associated with this method's selector.
ObjCMethodDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
ObjCInterfaceDecl * getClassInterface()
Represents one property declaration in an Objective-C interface.
Definition DeclObjC.h:731
Stmt * getParentIgnoreParenCasts(Stmt *) const
Represents a parameter to a function.
Definition Decl.h:1805
PointerType - C99 6.7.5.1 - Pointer Declarators.
Definition TypeBase.h:3378
Represents a program point just after an implicit call event.
Represents a program point just before an implicit call event.
ProgramPoints can be "tagged" as representing points specific to a given analysis entity.
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
Definition Expr.h:6803
Expr * getSyntacticForm()
Return the syntactic form of this expression, i.e.
Definition Expr.h:6840
A (possibly-)qualified type.
Definition TypeBase.h:937
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition TypeBase.h:1004
QualType getCanonicalType() const
Definition TypeBase.h:8483
bool isConstQualified() const
Determine whether this type is const-qualified.
Definition TypeBase.h:8504
Represents a struct/union/class.
Definition Decl.h:4342
field_range fields() const
Definition Decl.h:4545
RecordDecl * getDefinitionOrSelf() const
Definition Decl.h:4530
Smart pointer class that efficiently represents Objective-C method names.
const IdentifierInfo * getIdentifierInfoForSlot(unsigned argIndex) const
Retrieve the identifier at a given position in the selector.
unsigned getNumArgs() const
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
A trivial tuple used to represent a source range.
SourceLocation getBegin() const
It represents a stack frame of the call stack (based on CallEvent).
CFGElement getCallSiteCFGElement() const
const Stmt * getCallSite() const
const CFGBlock * getCallSiteBlock() const
Stmt - This represents one statement.
Definition Stmt.h:86
StmtClass getStmtClass() const
Definition Stmt.h:1494
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
Definition Stmt.cpp:343
A container of type source information.
Definition TypeBase.h:8402
bool isBlockPointerType() const
Definition TypeBase.h:8688
bool isVoidType() const
Definition TypeBase.h:9034
bool isFunctionPointerType() const
Definition TypeBase.h:8735
const CXXRecordDecl * getPointeeCXXRecordDecl() const
If this is a pointer or reference to a RecordType, return the CXXRecordDecl that the type refers to.
Definition Type.cpp:1923
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
Definition Type.cpp:754
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
Definition TypeBase.h:2832
bool isAnyPointerType() const
Definition TypeBase.h:8676
const T * getAs() const
Member-template getAs<specific type>'.
Definition TypeBase.h:9261
Represents a variable declaration or definition.
Definition Decl.h:926
This class is used for tools that requires cross translation unit capability.
llvm::Expected< const FunctionDecl * > getCrossTUDefinition(const FunctionDecl *FD, StringRef CrossTUDir, StringRef IndexName, bool DisplayCTUProgress=false)
This function loads a function or variable definition from an external AST file and merges it into th...
bool hasError(const Decl *ToDecl) const
Returns true if the given Decl is mapped (or created) during an import but there was an unrecoverable...
bool isImportedAsNew(const Decl *ToDecl) const
Returns true if the given Decl is newly created during the import.
static bool isInCodeFile(SourceLocation SL, const SourceManager &SM)
void getInitialStackFrameContents(const StackFrameContext *CalleeCtx, BindingsTy &Bindings) const override
Populates the given SmallVector with the bindings in the callee's stack frame at the start of this ca...
void getExtraInvalidatedValues(ValueList &Values, RegionAndSymbolInvalidationTraits *ETraits) const override
Used to specify non-argument regions that will be invalidated as a result of this call.
SVal getCXXThisVal() const
Returns the value of the implicit 'this' object.
const FunctionDecl * getDecl() const override
Returns the declaration of the function or method that will be called.
Definition CallEvent.h:525
ArrayRef< ParmVarDecl * > parameters() const override
Return call's formal parameters.
void getInitialStackFrameContents(const StackFrameContext *CalleeCtx, BindingsTy &Bindings) const override
Populates the given SmallVector with the bindings in the callee's stack frame at the start of this ca...
bool argumentsMayEscape() const override
Returns true if any of the arguments are known to escape to long- term storage, even if this method w...
RuntimeDefinition getRuntimeDefinition() const override
Returns the definition of the function or method that will be called.
llvm::ImmutableList< SVal > getEmptySValList()
llvm::ImmutableList< SVal > prependSVal(SVal X, llvm::ImmutableList< SVal > L)
const BlockDecl * getDecl() const override
Returns the declaration of the function or method that will be called.
Definition CallEvent.h:618
const BlockDataRegion * getBlockRegion() const
Returns the region associated with this instance of the block.
bool isConversionFromLambda() const
Definition CallEvent.h:625
ArrayRef< ParmVarDecl * > parameters() const override
Return call's formal parameters.
void getExtraInvalidatedValues(ValueList &Values, RegionAndSymbolInvalidationTraits *ETraits) const override
Used to specify non-argument regions that will be invalidated as a result of this call.
const VarRegion * getRegionStoringCapturedLambda() const
For a block converted from a C++ lambda, returns the block VarRegion for the variable holding the cap...
Definition CallEvent.h:635
void getInitialStackFrameContents(const StackFrameContext *CalleeCtx, BindingsTy &Bindings) const override
Populates the given SmallVector with the bindings in the callee's stack frame at the start of this ca...
const CallExpr * getOriginExpr() const override
Returns the expression whose value will be the result of this call.
Definition CallEvent.h:603
BlockDataRegion - A region that represents a block instance.
Definition MemRegion.h:706
SVal getCXXThisVal() const override
Returns the value of the implicit 'this' object.
RuntimeDefinition getRuntimeDefinition() const override
Returns the definition of the function or method that will be called.
bool isBaseDestructor() const
Returns true if this is a call to a base class destructor.
Definition CallEvent.h:952
const StackFrameContext * getInheritingStackFrame() const
Obtain the stack frame of the inheriting constructor.
std::pair< const CXXRecordDecl *, bool > getDeclForDynamicType() const
Returns the decl refered to by the "dynamic type" of the current object and if the class can be a sub...
void getExtraInvalidatedValues(ValueList &Values, RegionAndSymbolInvalidationTraits *ETraits) const override
Used to specify non-argument regions that will be invalidated as a result of this call.
virtual SVal getCXXThisVal() const
Returns the value of the implicit 'this' object.
RuntimeDefinition getRuntimeDefinition() const override
Returns the definition of the function or method that will be called.
virtual const Expr * getCXXThisExpr() const
Returns the expression representing the implicit 'this' object.
Definition CallEvent.h:713
const FunctionDecl * getDecl() const override
Returns the declaration of the function or method that will be called.
void getInitialStackFrameContents(const StackFrameContext *CalleeCtx, BindingsTy &Bindings) const override
Populates the given SmallVector with the bindings in the callee's stack frame at the start of this ca...
const CXXMemberCallExpr * getOriginExpr() const override
Returns the expression whose value will be the result of this call.
Definition CallEvent.h:818
const Expr * getCXXThisExpr() const override
Returns the expression representing the implicit 'this' object.
RuntimeDefinition getRuntimeDefinition() const override
Returns the definition of the function or method that will be called.
const Expr * getCXXThisExpr() const override
Returns the expression representing the implicit 'this' object.
const CXXOperatorCallExpr * getOriginExpr() const override
Returns the expression whose value will be the result of this call.
Definition CallEvent.h:863
CallEventRef< CXXDestructorCall > getCXXDestructorCall(const CXXDestructorDecl *DD, const Stmt *Trigger, const MemRegion *Target, bool IsBase, ProgramStateRef State, const LocationContext *LCtx, CFGBlock::ConstCFGElementRef ElemRef)
Definition CallEvent.h:1467
CallEventRef getCall(const Stmt *S, ProgramStateRef State, const LocationContext *LC, CFGBlock::ConstCFGElementRef ElemRef)
Gets a call event for a function call, Objective-C method call, a 'new', or a 'delete' call.
CallEventRef< CXXDeallocatorCall > getCXXDeallocatorCall(const CXXDeleteExpr *E, ProgramStateRef State, const LocationContext *LCtx, CFGBlock::ConstCFGElementRef ElemRef)
Definition CallEvent.h:1483
CallEventRef getSimpleCall(const CallExpr *E, ProgramStateRef State, const LocationContext *LCtx, CFGBlock::ConstCFGElementRef ElemRef)
CallEventRef< ObjCMethodCall > getObjCMethodCall(const ObjCMessageExpr *E, ProgramStateRef State, const LocationContext *LCtx, CFGBlock::ConstCFGElementRef ElemRef)
Definition CallEvent.h:1445
CallEventManager(llvm::BumpPtrAllocator &alloc)
CallEventRef< CXXAllocatorCall > getCXXAllocatorCall(const CXXNewExpr *E, ProgramStateRef State, const LocationContext *LCtx, CFGBlock::ConstCFGElementRef ElemRef)
Definition CallEvent.h:1476
CallEventRef< CXXConstructorCall > getCXXConstructorCall(const CXXConstructExpr *E, const MemRegion *Target, ProgramStateRef State, const LocationContext *LCtx, CFGBlock::ConstCFGElementRef ElemRef)
Definition CallEvent.h:1452
CallEventRef< CXXInheritedConstructorCall > getCXXInheritedConstructorCall(const CXXInheritedCtorInitExpr *E, const MemRegion *Target, ProgramStateRef State, const LocationContext *LCtx, CFGBlock::ConstCFGElementRef ElemRef)
Definition CallEvent.h:1459
CallEventRef getCaller(const StackFrameContext *CalleeCtx, ProgramStateRef State)
Gets an outside caller given a callee context.
Represents an abstract call to a function or method along a particular path.
Definition CallEvent.h:153
virtual SourceRange getArgSourceRange(unsigned Index) const
Returns the source range for errors associated with this argument.
virtual void getExtraInvalidatedValues(ValueList &Values, RegionAndSymbolInvalidationTraits *ETraits) const
Used to specify non-argument regions that will be invalidated as a result of this call.
Definition CallEvent.h:211
virtual StringRef getKindAsString() const =0
virtual const Expr * getOriginExpr() const
Returns the expression whose value will be the result of this call.
Definition CallEvent.h:263
ProgramStateRef getState() const
A state for looking up relevant Environment entries (arguments, return value), dynamic type informati...
Definition CallEvent.h:222
static bool isCallStmt(const Stmt *S)
Returns true if this is a statement is a function or method call of some kind.
const ConstructionContext * getConstructionContext() const
Returns the construction context of the call, if it is a C++ constructor call or a call of a function...
param_type_iterator param_type_end() const
Definition CallEvent.h:499
const ParamVarRegion * getParameterLocation(unsigned Index, unsigned BlockCount) const
Returns memory location for a parameter variable within the callee stack frame.
bool isCalledFromSystemHeader() const
AnalysisDeclContext * getCalleeAnalysisDeclContext() const
Returns AnalysisDeclContext for the callee stack frame.
virtual std::optional< unsigned > getAdjustedParameterIndex(unsigned ASTArgumentIndex) const
Some calls have parameter numbering mismatched from argument numbering.
Definition CallEvent.h:445
QualType getResultType() const
Returns the result type, adjusted for references.
Definition CallEvent.cpp:70
ProgramStateRef invalidateRegions(unsigned BlockCount, ProgramStateRef State) const
Invalidates the regions (arguments, globals, special regions like 'this') that may have been written ...
friend class CallEventManager
Definition CallEvent.h:182
llvm::mapped_iterator< ArrayRef< ParmVarDecl * >::iterator, GetTypeFn > param_type_iterator
Definition CallEvent.h:487
bool isInSystemHeader() const
Returns true if the callee is known to be from a system header.
Definition CallEvent.h:275
bool isGlobalCFunction(StringRef SpecificName=StringRef()) const
Returns true if the callee is an externally-visible function in the top-level namespace,...
virtual bool argumentsMayEscape() const
Returns true if any of the arguments are known to escape to long- term storage, even if this method w...
Definition CallEvent.h:337
param_type_iterator param_type_begin() const
Returns an iterator over the types of the call's formal parameters.
Definition CallEvent.h:495
ProgramPoint getProgramPoint(bool IsPreVisit=false, const ProgramPointTag *Tag=nullptr) const
Returns an appropriate ProgramPoint for this call.
const StackFrameContext * getCalleeStackFrame(unsigned BlockCount) const
Returns the callee stack frame.
static QualType getDeclaredResultType(const Decl *D)
Returns the result type of a function or method declaration.
SVal getSVal(const Stmt *S) const
Get the value of arbitrary expressions at this point in the path.
Definition CallEvent.h:202
static bool isVariadic(const Decl *D)
Returns true if the given decl is known to be variadic.
virtual SVal getArgSVal(unsigned Index) const
Returns the value of a given argument at the time of the call.
bool hasNonNullArgumentsWithType(bool(*Condition)(QualType)) const
Returns true if the type of any of the non-null arguments satisfies the condition.
std::optional< SVal > getReturnValueUnderConstruction() const
If the call returns a C++ record type then the region of its return value can be retrieved from its c...
virtual const Expr * getArgExpr(unsigned Index) const
Returns the expression associated with a given argument.
Definition CallEvent.h:306
virtual unsigned getNumArgs() const =0
Returns the number of arguments (explicit and implicit).
bool hasVoidPointerToNonConstArg() const
Returns true if any of the arguments is void*.
const CallEventRef getCaller() const
bool isArgumentConstructedDirectly(unsigned Index) const
Returns true if on the current path, the argument was constructed by calling a C++ constructor over i...
Definition CallEvent.h:433
SmallVectorImpl< FrameBindingTy > BindingsTy
Definition CallEvent.h:381
SVal getReturnValue() const
Returns the return value of the call.
virtual const Decl * getDecl() const
Returns the declaration of the function or method that will be called.
Definition CallEvent.h:234
const LocationContext * getLocationContext() const
The context in which the call is being evaluated.
Definition CallEvent.h:251
const CFGBlock::ConstCFGElementRef & getCFGElementRef() const
Definition CallEvent.h:253
bool hasNonZeroCallbackArg() const
Returns true if any of the arguments appear to represent callbacks.
virtual Kind getKind() const =0
Returns the kind of call this is.
SmallVectorImpl< SVal > ValueList
Definition CallEvent.h:206
virtual SourceRange getSourceRange() const
Returns a source range for the entire call, suitable for outputting in diagnostics.
Definition CallEvent.h:297
static bool isCLibraryFunction(const FunctionDecl *FD, StringRef Name=StringRef())
Returns true if the given function is an externally-visible function in the top-level namespace,...
Stores the currently inferred strictest bound on the runtime type of a region in a given state along ...
bool canBeASubClass() const
Returns false if the type information is precise (the type 'DynTy' is the only type in the lattice),...
QualType getType() const
Returns the currently inferred upper bound on the runtime type.
bool isValid() const
Returns true if the dynamic type info is available.
unsigned getNumVisited(const LocationContext *LC, const CFGBlock *Block) const
Definition ExprEngine.h:297
SVal computeObjectUnderConstruction(const Expr *E, ProgramStateRef State, unsigned NumVisitedCaller, const LocationContext *LCtx, const ConstructionContext *CC, EvalCallOptions &CallOpts, unsigned Idx=0)
Find location of the object that is being constructed by a given constructor.
const VarRegion * getVarRegion(const VarDecl *VD, const LocationContext *LC)
getVarRegion - Retrieve or create the memory region associated with a specified VarDecl and LocationC...
const ParamVarRegion * getParamVarRegion(const Expr *OriginExpr, unsigned Index, const LocationContext *LC)
getParamVarRegion - Retrieve or create the memory region associated with a specified CallExpr,...
MemRegion - The root abstract class for all memory regions.
Definition MemRegion.h:98
LLVM_ATTRIBUTE_RETURNS_NONNULL const MemRegion * getBaseRegion() const
const ObjCMethodDecl * getDecl() const override
Returns the declaration of the function or method that will be called.
Definition CallEvent.h:1291
void getExtraInvalidatedValues(ValueList &Values, RegionAndSymbolInvalidationTraits *ETraits) const override
Used to specify non-argument regions that will be invalidated as a result of this call.
ObjCMessageKind getMessageKind() const
Returns how the message was written in the source (property access, subscript, or explicit message se...
const ObjCMessageExpr * getOriginExpr() const override
Returns the expression whose value will be the result of this call.
Definition CallEvent.h:1287
ObjCMethodCall(const ObjCMessageExpr *Msg, ProgramStateRef St, const LocationContext *LCtx, CFGBlock::ConstCFGElementRef ElemRef)
Definition CallEvent.h:1267
ArrayRef< ParmVarDecl * > parameters() const override
Return call's formal parameters.
SourceRange getSourceRange() const override
Returns a source range for the entire call, suitable for outputting in diagnostics.
virtual bool canBeOverridenInSubclass(ObjCInterfaceDecl *IDecl, Selector Sel) const
Check if the selector may have multiple definitions (may have overrides).
bool argumentsMayEscape() const override
Returns true if any of the arguments are known to escape to long- term storage, even if this method w...
SVal getReceiverSVal() const
Returns the value of the receiver at the time of this call.
RuntimeDefinition getRuntimeDefinition() const override
Returns the definition of the function or method that will be called.
bool isReceiverSelfOrSuper() const
Checks if the receiver refers to 'self' or 'super'.
Selector getSelector() const
Definition CallEvent.h:1309
const ObjCPropertyDecl * getAccessedProperty() const
void getInitialStackFrameContents(const StackFrameContext *CalleeCtx, BindingsTy &Bindings) const override
Populates the given SmallVector with the bindings in the callee's stack frame at the start of this ca...
ParamVarRegion - Represents a region for parameters.
Definition MemRegion.h:1062
Information about invalidation for a particular region/symbol.
Definition MemRegion.h:1657
@ TK_PreserveContents
Tells that a region's contents is not changed.
Definition MemRegion.h:1672
@ TK_SuppressEscape
Suppress pointer-escaping of a region.
Definition MemRegion.h:1675
void setTrait(SymbolRef Sym, InvalidationKinds IK)
Defines the runtime definition of the called function.
Definition CallEvent.h:110
BasicValueFactory & getBasicValueFactory()
NonLoc makeCompoundVal(QualType type, llvm::ImmutableList< SVal > vals)
MemRegionManager & getRegionManager()
ProgramStateManager & getStateManager()
ASTContext & getContext()
loc::MemRegionVal makeLoc(SymbolRef sym)
SVal evalCast(SVal V, QualType CastTy, QualType OriginalTy)
Cast a given SVal to another SVal using given QualType's.
loc::MemRegionVal getCXXThis(const CXXMethodDecl *D, const StackFrameContext *SFC)
Return a memory region for the 'this' object reference.
SVal - This represents a symbolic expression, which can be either an L-value or an R-value.
Definition SVals.h:56
bool isUnknownOrUndef() const
Definition SVals.h:109
const FunctionDecl * getAsFunctionDecl() const
getAsFunctionDecl - If this SVal is a MemRegionVal and wraps a CodeTextRegion wrapping a FunctionDecl...
Definition SVals.cpp:45
QualType getType(const ASTContext &) const
Try to get a reasonable type for the given value.
Definition SVals.cpp:180
const MemRegion * getAsRegion() const
Definition SVals.cpp:119
bool isValid() const
Definition SVals.h:111
bool isUnknown() const
Definition SVals.h:105
RuntimeDefinition getRuntimeDefinition() const override
Returns the definition of the function or method that will be called.
const CallExpr * getOriginExpr() const override
Returns the expression whose value will be the result of this call.
Definition CallEvent.h:562
const FunctionDecl * getDecl() const override
Returns the declaration of the function or method that will be called.
std::optional< SVal > evalBaseToDerived(SVal Base, QualType DerivedPtrType)
Attempts to do a down cast.
Definition Store.cpp:318
TypedValueRegion - An abstract class representing regions having a typed value.
Definition MemRegion.h:563
static const FunctionDecl * getCallee(const CXXConstructExpr &D)
bool isWithinStdNamespace(const Decl *D)
Returns true if declaration D is in std namespace or any nested namespace or class scope.
IntrusiveRefCntPtr< const ProgramState > ProgramStateRef
const SymExpr * SymbolRef
Definition SymExpr.h:133
DynamicTypeInfo getDynamicTypeInfo(ProgramStateRef State, const MemRegion *MR)
Get dynamic type information for the region MR.
@ CE_CXXAllocator
Definition CallEvent.h:72
ObjCMessageKind
Represents the ways an Objective-C message send can occur.
Definition CallEvent.h:1256
DynamicTypeInfo getClassObjectDynamicTypeInfo(ProgramStateRef State, SymbolRef Sym)
Get dynamic type information stored in a class object represented by Sym.
The JSON file list parser is used to communicate input to InstallAPI.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
bool isa(CodeGen::Address addr)
Definition Address.h:330
@ Parameter
The parameter type of a method or function.
Definition TypeBase.h:908
@ Result
The result type of a method or function.
Definition TypeBase.h:905
U cast(CodeGen::Address addr)
Definition Address.h:327
@ Interface
The "__interface" keyword introduces the elaborated-type-specifier.
Definition TypeBase.h:5961
@ Class
The "class" keyword introduces the elaborated-type-specifier.
Definition TypeBase.h:5967
Diagnostic wrappers for TextAPI types for error reporting.
Definition Dominators.h:30
Selector LookupSelector
const ObjCInterfaceDecl * Interface
Hints for figuring out of a call should be inlined during evalCall().
Definition ExprEngine.h:95
DenseMapInfo< Selector > SelectorInfo
static unsigned getHashValue(const PrivateMethodKey &Key)
static PrivateMethodKey getEmptyKey()
DenseMapInfo< const ObjCInterfaceDecl * > InterfaceInfo
static bool isEqual(const PrivateMethodKey &LHS, const PrivateMethodKey &RHS)
static PrivateMethodKey getTombstoneKey()