clang 22.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 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 ProgramStateRef Orig) const {
234 ProgramStateRef Result = (Orig ? Orig : getState());
235
236 // Don't invalidate anything if the callee is marked pure/const.
237 if (const Decl *callee = getDecl())
238 if (callee->hasAttr<PureAttr>() || callee->hasAttr<ConstAttr>())
239 return Result;
240
241 SmallVector<SVal, 8> ValuesToInvalidate;
243
244 getExtraInvalidatedValues(ValuesToInvalidate, &ETraits);
245
246 // Indexes of arguments whose values will be preserved by the call.
247 llvm::SmallSet<unsigned, 4> PreserveArgs;
248 if (!argumentsMayEscape())
249 findPtrToConstParams(PreserveArgs, *this);
250
251 for (unsigned Idx = 0, Count = getNumArgs(); Idx != Count; ++Idx) {
252 // Mark this region for invalidation. We batch invalidate regions
253 // below for efficiency.
254 if (PreserveArgs.count(Idx))
255 if (const MemRegion *MR = getArgSVal(Idx).getAsRegion())
256 ETraits.setTrait(MR->getBaseRegion(),
258 // TODO: Factor this out + handle the lower level const pointers.
259
260 ValuesToInvalidate.push_back(getArgSVal(Idx));
261
262 // If a function accepts an object by argument (which would of course be a
263 // temporary that isn't lifetime-extended), invalidate the object itself,
264 // not only other objects reachable from it. This is necessary because the
265 // destructor has access to the temporary object after the call.
266 // TODO: Support placement arguments once we start
267 // constructing them directly.
268 // TODO: This is unnecessary when there's no destructor, but that's
269 // currently hard to figure out.
270 if (getKind() != CE_CXXAllocator)
272 if (auto AdjIdx = getAdjustedParameterIndex(Idx))
273 if (const TypedValueRegion *TVR =
274 getParameterLocation(*AdjIdx, BlockCount))
275 ValuesToInvalidate.push_back(loc::MemRegionVal(TVR));
276 }
277
278 // Invalidate designated regions using the batch invalidation API.
279 // NOTE: Even if RegionsToInvalidate is empty, we may still invalidate
280 // global variables.
281 return Result->invalidateRegions(ValuesToInvalidate, getCFGElementRef(),
282 BlockCount, getLocationContext(),
283 /*CausedByPointerEscape*/ true,
284 /*Symbols=*/nullptr, this, &ETraits);
285}
286
288 const ProgramPointTag *Tag) const {
289
290 if (const Expr *E = getOriginExpr()) {
291 if (IsPreVisit)
292 return PreStmt(E, getLocationContext(), Tag);
293 return PostStmt(E, getLocationContext(), Tag);
294 }
295
296 const Decl *D = getDecl();
297 assert(D && "Cannot get a program point without a statement or decl");
298 assert(ElemRef.getParent() &&
299 "Cannot get a program point without a CFGElementRef");
300
302 if (IsPreVisit)
303 return PreImplicitCall(D, Loc, getLocationContext(), ElemRef, Tag);
304 return PostImplicitCall(D, Loc, getLocationContext(), ElemRef, Tag);
305}
306
307SVal CallEvent::getArgSVal(unsigned Index) const {
308 const Expr *ArgE = getArgExpr(Index);
309 if (!ArgE)
310 return UnknownVal();
311 return getSVal(ArgE);
312}
313
315 const Expr *ArgE = getArgExpr(Index);
316 if (!ArgE)
317 return {};
318 return ArgE->getSourceRange();
319}
320
322 const Expr *E = getOriginExpr();
323 if (!E)
324 return UndefinedVal();
325 return getSVal(E);
326}
327
328LLVM_DUMP_METHOD void CallEvent::dump() const { dump(llvm::errs()); }
329
330void CallEvent::dump(raw_ostream &Out) const {
331 ASTContext &Ctx = getState()->getStateManager().getContext();
332 if (const Expr *E = getOriginExpr()) {
333 E->printPretty(Out, nullptr, Ctx.getPrintingPolicy());
334 return;
335 }
336
337 if (const Decl *D = getDecl()) {
338 Out << "Call to ";
339 D->print(Out, Ctx.getPrintingPolicy());
340 return;
341 }
342
343 Out << "Unknown call (type " << getKindAsString() << ")";
344}
345
349
351 assert(D);
352 if (const auto *FD = dyn_cast<FunctionDecl>(D))
353 return FD->getReturnType();
354 if (const auto *MD = dyn_cast<ObjCMethodDecl>(D))
355 return MD->getReturnType();
356 if (const auto *BD = dyn_cast<BlockDecl>(D)) {
357 // Blocks are difficult because the return type may not be stored in the
358 // BlockDecl itself. The AST should probably be enhanced, but for now we
359 // just do what we can.
360 // If the block is declared without an explicit argument list, the
361 // signature-as-written just includes the return type, not the entire
362 // function type.
363 // FIXME: All blocks should have signatures-as-written, even if the return
364 // type is inferred. (That's signified with a dependent result type.)
365 if (const TypeSourceInfo *TSI = BD->getSignatureAsWritten()) {
366 QualType Ty = TSI->getType();
367 if (const FunctionType *FT = Ty->getAs<FunctionType>())
368 Ty = FT->getReturnType();
369 if (!Ty->isDependentType())
370 return Ty;
371 }
372
373 return {};
374 }
375
376 llvm_unreachable("unknown callable kind");
377}
378
380 assert(D);
381
382 if (const auto *FD = dyn_cast<FunctionDecl>(D))
383 return FD->isVariadic();
384 if (const auto *MD = dyn_cast<ObjCMethodDecl>(D))
385 return MD->isVariadic();
386 if (const auto *BD = dyn_cast<BlockDecl>(D))
387 return BD->isVariadic();
388
389 llvm_unreachable("unknown callable kind");
390}
391
393 const RecordType *UT = T->getAsUnionType();
394 return UT &&
395 UT->getDecl()->getMostRecentDecl()->hasAttr<TransparentUnionAttr>();
396}
397
398// In some cases, symbolic cases should be transformed before we associate
399// them with parameters. This function incapsulates such cases.
400static SVal processArgument(SVal Value, const Expr *ArgumentExpr,
401 const ParmVarDecl *Parameter, SValBuilder &SVB) {
402 QualType ParamType = Parameter->getType();
403 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 if (isTransparentUnion(ParamType) &&
415 // Let's check that we indeed trying to bind different types.
416 !isTransparentUnion(ArgumentType)) {
418
419 llvm::ImmutableList<SVal> CompoundSVals = BVF.getEmptySValList();
420 CompoundSVals = BVF.prependSVal(Value, CompoundSVals);
421
422 // Wrap it with compound value.
423 return SVB.makeCompoundVal(ParamType, CompoundSVals);
424 }
425
426 return Value;
427}
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.
435static SVal castArgToParamTypeIfNeeded(const CallEvent &Call, unsigned ArgIdx,
436 SVal ArgVal, SValBuilder &SVB) {
437 const auto *CallExprDecl = dyn_cast_or_null<FunctionDecl>(Call.getDecl());
438 if (!CallExprDecl)
439 return ArgVal;
440
441 const FunctionDecl *Definition = CallExprDecl;
442 Definition->hasBody(Definition);
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 if (CallExprDecl->hasPrototype() || !Definition->hasPrototype())
449 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 if (Call.getNumArgs() != Definition->getNumParams())
454 return UnknownVal();
455
456 const Expr *ArgExpr = Call.getArgExpr(ArgIdx);
457 const ParmVarDecl *Param = Definition->getParamDecl(ArgIdx);
458 return SVB.evalCast(ArgVal, Param->getType(), ArgExpr->getType());
459}
460
463 SValBuilder &SVB,
464 const CallEvent &Call,
465 ArrayRef<ParmVarDecl*> parameters) {
466 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 unsigned NumArgs = Call.getNumArgs();
471 unsigned Idx = 0;
472 ArrayRef<ParmVarDecl*>::iterator I = parameters.begin(), E = parameters.end();
473 for (; I != E && Idx < NumArgs; ++I, ++Idx) {
474 assert(*I && "Formal parameter has no decl?");
475
476 // TODO: Support allocator calls.
477 if (Call.getKind() != CE_CXXAllocator)
478 if (Call.isArgumentConstructedDirectly(Call.getASTArgumentIndex(Idx)))
479 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 SVal ArgVal = Call.getArgSVal(Idx);
485 const Expr *ArgExpr = Call.getArgExpr(Idx);
486
487 if (ArgVal.isUnknown())
488 continue;
489
490 // Cast the argument value to match the type of the parameter in some
491 // edge-cases.
492 ArgVal = castArgToParamTypeIfNeeded(Call, Idx, ArgVal, SVB);
493
494 Loc ParamLoc = SVB.makeLoc(
495 MRMgr.getParamVarRegion(Call.getOriginExpr(), Idx, CalleeCtx));
496 Bindings.push_back(
497 std::make_pair(ParamLoc, processArgument(ArgVal, ArgExpr, *I, SVB)));
498 }
499
500 // FIXME: Variadic arguments are not handled at all right now.
501}
502
504 const StackFrameContext *StackFrame = getCalleeStackFrame(0);
505 if (!StackFrame)
506 return nullptr;
507
508 const CFGElement Element = StackFrame->getCallSiteCFGElement();
509 if (const auto Ctor = Element.getAs<CFGConstructor>()) {
510 return Ctor->getConstructionContext();
511 }
512
513 if (const auto RecCall = Element.getAs<CFGCXXRecordTypedCall>()) {
514 return RecCall->getConstructionContext();
515 }
516
517 return nullptr;
518}
519
521 const auto *CallLocationContext = this->getLocationContext();
522 if (!CallLocationContext || CallLocationContext->inTopFrame())
523 return nullptr;
524
525 const auto *CallStackFrameContext = CallLocationContext->getStackFrame();
526 if (!CallStackFrameContext)
527 return nullptr;
528
529 CallEventManager &CEMgr = State->getStateManager().getCallEventManager();
530 return CEMgr.getCaller(CallStackFrameContext, State);
531}
532
534 if (const CallEventRef<> Caller = getCaller())
535 return Caller->isInSystemHeader();
536
537 return false;
538}
539
541 const auto *CC = getConstructionContext();
542 if (!CC)
543 return std::nullopt;
544
545 EvalCallOptions CallOpts;
546 ExprEngine &Engine = getState()->getStateManager().getOwningEngine();
547 SVal RetVal = Engine.computeObjectUnderConstruction(
549 getLocationContext(), CC, CallOpts);
550 return RetVal;
551}
552
554 const FunctionDecl *D = getDecl();
555 if (!D)
556 return {};
557 return D->parameters();
558}
559
561 const FunctionDecl *FD = getDecl();
562 if (!FD)
563 return {};
564
565 // Note that the AnalysisDeclContext will have the FunctionDecl with
566 // the definition (if one exists).
569 getManager()->getContext(FD);
570 bool IsAutosynthesized;
571 Stmt* Body = AD->getBody(IsAutosynthesized);
572 LLVM_DEBUG({
573 if (IsAutosynthesized)
574 llvm::dbgs() << "Using autosynthesized body for " << FD->getName()
575 << "\n";
576 });
577
578 ExprEngine &Engine = getState()->getStateManager().getOwningEngine();
580 *Engine.getCrossTranslationUnitContext();
581
582 AnalyzerOptions &Opts = Engine.getAnalysisManager().options;
583
584 if (Body) {
585 const Decl* Decl = AD->getDecl();
586 if (Opts.IsNaiveCTUEnabled && CTUCtx.isImportedAsNew(Decl)) {
587 // A newly created definition, but we had error(s) during the import.
588 if (CTUCtx.hasError(Decl))
589 return {};
590 return RuntimeDefinition(Decl, /*Foreign=*/true);
591 }
592 return RuntimeDefinition(Decl, /*Foreign=*/false);
593 }
594
595 // Try to get CTU definition only if CTUDir is provided.
596 if (!Opts.IsNaiveCTUEnabled)
597 return {};
598
600 CTUCtx.getCrossTUDefinition(FD, Opts.CTUDir, Opts.CTUIndexName,
601 Opts.DisplayCTUProgress);
602
603 if (!CTUDeclOrError) {
604 handleAllErrors(CTUDeclOrError.takeError(),
605 [&](const cross_tu::IndexError &IE) {
606 CTUCtx.emitCrossTUDiagnostics(IE);
607 });
608 return {};
609 }
610
611 return RuntimeDefinition(*CTUDeclOrError, /*Foreign=*/true);
612}
613
615 const StackFrameContext *CalleeCtx,
616 BindingsTy &Bindings) const {
617 const auto *D = cast<FunctionDecl>(CalleeCtx->getDecl());
618 SValBuilder &SVB = getState()->getStateManager().getSValBuilder();
619 addParameterValuesToBindings(CalleeCtx, Bindings, SVB, *this,
620 D->parameters());
621}
622
625 return true;
626
627 const FunctionDecl *D = getDecl();
628 if (!D)
629 return true;
630
631 const IdentifierInfo *II = D->getIdentifier();
632 if (!II)
633 return false;
634
635 // This set of "escaping" APIs is
636
637 // - 'int pthread_setspecific(ptheread_key k, const void *)' stores a
638 // value into thread local storage. The value can later be retrieved with
639 // 'void *ptheread_getspecific(pthread_key)'. So even thought the
640 // parameter is 'const void *', the region escapes through the call.
641 if (II->isStr("pthread_setspecific"))
642 return true;
643
644 // - xpc_connection_set_context stores a value which can be retrieved later
645 // with xpc_connection_get_context.
646 if (II->isStr("xpc_connection_set_context"))
647 return true;
648
649 // - funopen - sets a buffer for future IO calls.
650 if (II->isStr("funopen"))
651 return true;
652
653 // - __cxa_demangle - can reallocate memory and can return the pointer to
654 // the input buffer.
655 if (II->isStr("__cxa_demangle"))
656 return true;
657
658 StringRef FName = II->getName();
659
660 // - CoreFoundation functions that end with "NoCopy" can free a passed-in
661 // buffer even if it is const.
662 if (FName.ends_with("NoCopy"))
663 return true;
664
665 // - NSXXInsertXX, for example NSMapInsertIfAbsent, since they can
666 // be deallocated by NSMapRemove.
667 if (FName.starts_with("NS") && FName.contains("Insert"))
668 return true;
669
670 // - Many CF containers allow objects to escape through custom
671 // allocators/deallocators upon container construction. (PR12101)
672 if (FName.starts_with("CF") || FName.starts_with("CG")) {
673 return StrInStrNoCase(FName, "InsertValue") != StringRef::npos ||
674 StrInStrNoCase(FName, "AddValue") != StringRef::npos ||
675 StrInStrNoCase(FName, "SetValue") != StringRef::npos ||
676 StrInStrNoCase(FName, "WithData") != StringRef::npos ||
677 StrInStrNoCase(FName, "AppendValue") != StringRef::npos ||
678 StrInStrNoCase(FName, "SetAttribute") != StringRef::npos;
679 }
680
681 return false;
682}
683
686 if (D)
687 return D;
688
690}
691
693 // Clang converts lambdas to function pointers using an implicit conversion
694 // operator, which returns the lambda's '__invoke' method. However, Sema
695 // leaves the body of '__invoke' empty (it is generated later in CodeGen), so
696 // we need to skip '__invoke' and access the lambda's operator() directly.
697 if (const auto *CMD = dyn_cast_if_present<CXXMethodDecl>(getDecl());
698 CMD && CMD->isLambdaStaticInvoker())
699 return RuntimeDefinition{CMD->getParent()->getLambdaCallOperator()};
700
702}
703
705 const auto *CE = cast_or_null<CallExpr>(getOriginExpr());
706 if (!CE)
708
709 const FunctionDecl *D = CE->getDirectCallee();
710 if (D)
711 return D;
712
713 return getSVal(CE->getCallee()).getAsFunctionDecl();
714}
715
717 ValueList &Values, RegionAndSymbolInvalidationTraits *ETraits) const {
718 SVal ThisVal = getCXXThisVal();
719 Values.push_back(ThisVal);
720
721 // Don't invalidate if the method is const and there are no mutable fields.
722 if (const auto *D = cast_or_null<CXXMethodDecl>(getDecl())) {
723 if (!D->isConst())
724 return;
725
726 // Get the record decl for the class of 'This'. D->getParent() may return
727 // a base class decl, rather than the class of the instance which needs to
728 // be checked for mutable fields.
729 const CXXRecordDecl *ParentRecord = getDeclForDynamicType().first;
730 if (!ParentRecord || !ParentRecord->hasDefinition())
731 return;
732
733 if (ParentRecord->hasMutableFields())
734 return;
735
736 // Preserve CXXThis.
737 const MemRegion *ThisRegion = ThisVal.getAsRegion();
738 if (!ThisRegion)
739 return;
740
741 ETraits->setTrait(ThisRegion->getBaseRegion(),
743 }
744}
745
747 const Expr *Base = getCXXThisExpr();
748 // FIXME: This doesn't handle an overloaded ->* operator.
749 SVal ThisVal = Base ? getSVal(Base) : UnknownVal();
750
751 if (isa<NonLoc>(ThisVal)) {
752 SValBuilder &SVB = getState()->getStateManager().getSValBuilder();
753 QualType OriginalTy = ThisVal.getType(SVB.getContext());
754 return SVB.evalCast(ThisVal, Base->getType(), OriginalTy);
755 }
756
757 assert(ThisVal.isUnknownOrUndef() || isa<Loc>(ThisVal));
758 return ThisVal;
759}
760
761std::pair<const CXXRecordDecl *, bool>
763 const MemRegion *R = getCXXThisVal().getAsRegion();
764 if (!R)
765 return {};
766
768 if (!DynType.isValid())
769 return {};
770
771 assert(!DynType.getType()->getPointeeType().isNull());
772 return {DynType.getType()->getPointeeCXXRecordDecl(),
773 DynType.canBeASubClass()};
774}
775
777 // Do we have a decl at all?
778 const Decl *D = getDecl();
779 if (!D)
780 return {};
781
782 // If the method is non-virtual, we know we can inline it.
783 const auto *MD = cast<CXXMethodDecl>(D);
784 if (!MD->isVirtual())
786
787 auto [RD, CanBeSubClass] = getDeclForDynamicType();
788 if (!RD || !RD->hasDefinition())
789 return {};
790
791 // Find the decl for this method in that class.
792 const CXXMethodDecl *Result = MD->getCorrespondingMethodInClass(RD, true);
793 if (!Result) {
794 // We might not even get the original statically-resolved method due to
795 // some particularly nasty casting (e.g. casts to sister classes).
796 // However, we should at least be able to search up and down our own class
797 // hierarchy, and some real bugs have been caught by checking this.
798 assert(!RD->isDerivedFrom(MD->getParent()) && "Couldn't find known method");
799
800 // FIXME: This is checking that our DynamicTypeInfo is at least as good as
801 // the static type. However, because we currently don't update
802 // DynamicTypeInfo when an object is cast, we can't actually be sure the
803 // DynamicTypeInfo is up to date. This assert should be re-enabled once
804 // this is fixed.
805 //
806 // assert(!MD->getParent()->isDerivedFrom(RD) && "Bad DynamicTypeInfo");
807
808 return {};
809 }
810
811 // Does the decl that we found have an implementation?
813 if (!Result->hasBody(Definition)) {
814 if (!CanBeSubClass)
816 return {};
817 }
818
819 // We found a definition. If we're not sure that this devirtualization is
820 // actually what will happen at runtime, make sure to provide the region so
821 // that ExprEngine can decide what to do with it.
822 if (CanBeSubClass)
824 getCXXThisVal().getAsRegion()->StripCasts());
825 return RuntimeDefinition(Definition, /*DispatchRegion=*/nullptr);
826}
827
829 const StackFrameContext *CalleeCtx,
830 BindingsTy &Bindings) const {
832
833 // Handle the binding of 'this' in the new stack frame.
834 SVal ThisVal = getCXXThisVal();
835 if (!ThisVal.isUnknown()) {
836 ProgramStateManager &StateMgr = getState()->getStateManager();
837 SValBuilder &SVB = StateMgr.getSValBuilder();
838
839 const auto *MD = cast<CXXMethodDecl>(CalleeCtx->getDecl());
840 Loc ThisLoc = SVB.getCXXThis(MD, CalleeCtx);
841
842 // If we devirtualized to a different member function, we need to make sure
843 // we have the proper layering of CXXBaseObjectRegions.
844 if (MD->getCanonicalDecl() != getDecl()->getCanonicalDecl()) {
845 ASTContext &Ctx = SVB.getContext();
846 const CXXRecordDecl *Class = MD->getParent();
848
849 // FIXME: CallEvent maybe shouldn't be directly accessing StoreManager.
850 std::optional<SVal> V =
851 StateMgr.getStoreManager().evalBaseToDerived(ThisVal, Ty);
852 if (!V) {
853 // We might have suffered some sort of placement new earlier, so
854 // we're constructing in a completely unexpected storage.
855 // Fall back to a generic pointer cast for this-value.
856 const CXXMethodDecl *StaticMD = cast<CXXMethodDecl>(getDecl());
857 const CXXRecordDecl *StaticClass = StaticMD->getParent();
858 CanQualType StaticTy =
859 Ctx.getPointerType(Ctx.getCanonicalTagType(StaticClass));
860 ThisVal = SVB.evalCast(ThisVal, Ty, StaticTy);
861 } else
862 ThisVal = *V;
863 }
864
865 if (!ThisVal.isUnknown())
866 Bindings.push_back(std::make_pair(ThisLoc, ThisVal));
867 }
868}
869
873
875 // C++11 [expr.call]p1: ...If the selected function is non-virtual, or if the
876 // id-expression in the class member access expression is a qualified-id,
877 // that function is called. Otherwise, its final overrider in the dynamic type
878 // of the object expression is called.
879 if (const auto *ME = dyn_cast<MemberExpr>(getOriginExpr()->getCallee()))
880 if (ME->hasQualifier())
882
884}
885
887 return getOriginExpr()->getArg(0);
888}
889
891 const Expr *Callee = getOriginExpr()->getCallee();
892 const MemRegion *DataReg = getSVal(Callee).getAsRegion();
893
894 return dyn_cast_or_null<BlockDataRegion>(DataReg);
895}
896
898 const BlockDecl *D = getDecl();
899 if (!D)
900 return {};
901 return D->parameters();
902}
903
905 RegionAndSymbolInvalidationTraits *ETraits) const {
906 // FIXME: This also needs to invalidate captured globals.
907 if (const MemRegion *R = getBlockRegion())
908 Values.push_back(loc::MemRegionVal(R));
909}
910
912 BindingsTy &Bindings) const {
913 SValBuilder &SVB = getState()->getStateManager().getSValBuilder();
916 auto *LambdaOperatorDecl = cast<CXXMethodDecl>(CalleeCtx->getDecl());
917 Params = LambdaOperatorDecl->parameters();
918
919 // For blocks converted from a C++ lambda, the callee declaration is the
920 // operator() method on the lambda so we bind "this" to
921 // the lambda captured by the block.
922 const VarRegion *CapturedLambdaRegion = getRegionStoringCapturedLambda();
923 SVal ThisVal = loc::MemRegionVal(CapturedLambdaRegion);
924 Loc ThisLoc = SVB.getCXXThis(LambdaOperatorDecl, CalleeCtx);
925 Bindings.push_back(std::make_pair(ThisLoc, ThisVal));
926 } else {
927 Params = cast<BlockDecl>(CalleeCtx->getDecl())->parameters();
928 }
929
930 addParameterValuesToBindings(CalleeCtx, Bindings, SVB, *this,
931 Params);
932}
933
935 if (Data)
936 return loc::MemRegionVal(static_cast<const MemRegion *>(Data));
937 return UnknownVal();
938}
939
941 RegionAndSymbolInvalidationTraits *ETraits) const {
942 SVal V = getCXXThisVal();
943 if (SymbolRef Sym = V.getAsSymbol(true))
944 ETraits->setTrait(Sym,
946
947 // Standard classes don't reinterpret-cast and modify super regions.
948 const bool IsStdClassCtor = isWithinStdNamespace(getDecl());
949 if (const MemRegion *Obj = V.getAsRegion(); Obj && IsStdClassCtor) {
950 ETraits->setTrait(
952 }
953
954 Values.push_back(V);
955}
956
958 const StackFrameContext *CalleeCtx,
959 BindingsTy &Bindings) const {
961
962 SVal ThisVal = getCXXThisVal();
963 if (!ThisVal.isUnknown()) {
964 SValBuilder &SVB = getState()->getStateManager().getSValBuilder();
965 const auto *MD = cast<CXXMethodDecl>(CalleeCtx->getDecl());
966 Loc ThisLoc = SVB.getCXXThis(MD, CalleeCtx);
967 Bindings.push_back(std::make_pair(ThisLoc, ThisVal));
968 }
969}
970
971const StackFrameContext *
978
980 if (Data)
981 return loc::MemRegionVal(DtorDataTy::getFromOpaqueValue(Data).getPointer());
982 return UnknownVal();
983}
984
986 // Base destructors are always called non-virtually.
987 // Skip CXXInstanceCall's devirtualization logic in this case.
988 if (isBaseDestructor())
990
992}
993
995 const ObjCMethodDecl *D = getDecl();
996 if (!D)
997 return {};
998 return D->parameters();
999}
1000
1002 ValueList &Values, RegionAndSymbolInvalidationTraits *ETraits) const {
1003
1004 // If the method call is a setter for property known to be backed by
1005 // an instance variable, don't invalidate the entire receiver, just
1006 // the storage for that instance variable.
1007 if (const ObjCPropertyDecl *PropDecl = getAccessedProperty()) {
1008 if (const ObjCIvarDecl *PropIvar = PropDecl->getPropertyIvarDecl()) {
1009 SVal IvarLVal = getState()->getLValue(PropIvar, getReceiverSVal());
1010 if (const MemRegion *IvarRegion = IvarLVal.getAsRegion()) {
1011 ETraits->setTrait(
1012 IvarRegion,
1014 ETraits->setTrait(
1015 IvarRegion,
1017 Values.push_back(IvarLVal);
1018 }
1019 return;
1020 }
1021 }
1022
1023 Values.push_back(getReceiverSVal());
1024}
1025
1027 // FIXME: Is this the best way to handle class receivers?
1028 if (!isInstanceMessage())
1029 return UnknownVal();
1030
1031 if (const Expr *RecE = getOriginExpr()->getInstanceReceiver())
1032 return getSVal(RecE);
1033
1034 // An instance message with no expression means we are sending to super.
1035 // In this case the object reference is the same as 'self'.
1036 assert(getOriginExpr()->getReceiverKind() == ObjCMessageExpr::SuperInstance);
1037 SVal SelfVal = getState()->getSelfSVal(getLocationContext());
1038 assert(SelfVal.isValid() && "Calling super but not in ObjC method");
1039 return SelfVal;
1040}
1041
1043 if (getOriginExpr()->getReceiverKind() == ObjCMessageExpr::SuperInstance ||
1044 getOriginExpr()->getReceiverKind() == ObjCMessageExpr::SuperClass)
1045 return true;
1046
1047 if (!isInstanceMessage())
1048 return false;
1049
1050 SVal RecVal = getSVal(getOriginExpr()->getInstanceReceiver());
1051 SVal SelfVal = getState()->getSelfSVal(getLocationContext());
1052
1053 return (RecVal == SelfVal);
1054}
1055
1057 switch (getMessageKind()) {
1058 case OCM_Message:
1059 return getOriginExpr()->getSourceRange();
1060 case OCM_PropertyAccess:
1061 case OCM_Subscript:
1062 return getContainingPseudoObjectExpr()->getSourceRange();
1063 }
1064 llvm_unreachable("unknown message kind");
1065}
1066
1067using ObjCMessageDataTy = llvm::PointerIntPair<const PseudoObjectExpr *, 2>;
1068
1069const PseudoObjectExpr *ObjCMethodCall::getContainingPseudoObjectExpr() const {
1070 assert(Data && "Lazy lookup not yet performed.");
1071 assert(getMessageKind() != OCM_Message && "Explicit message send.");
1072 return ObjCMessageDataTy::getFromOpaqueValue(Data).getPointer();
1073}
1074
1075static const Expr *
1077 const Expr *Syntactic = POE->getSyntacticForm()->IgnoreParens();
1078
1079 // This handles the funny case of assigning to the result of a getter.
1080 // This can happen if the getter returns a non-const reference.
1081 if (const auto *BO = dyn_cast<BinaryOperator>(Syntactic))
1082 Syntactic = BO->getLHS()->IgnoreParens();
1083
1084 return Syntactic;
1085}
1086
1088 if (!Data) {
1089 // Find the parent, ignoring implicit casts.
1090 const ParentMap &PM = getLocationContext()->getParentMap();
1092
1093 // Check if parent is a PseudoObjectExpr.
1094 if (const auto *POE = dyn_cast_or_null<PseudoObjectExpr>(S)) {
1095 const Expr *Syntactic = getSyntacticFromForPseudoObjectExpr(POE);
1096
1098 switch (Syntactic->getStmtClass()) {
1099 case Stmt::ObjCPropertyRefExprClass:
1101 break;
1102 case Stmt::ObjCSubscriptRefExprClass:
1103 K = OCM_Subscript;
1104 break;
1105 default:
1106 // FIXME: Can this ever happen?
1107 K = OCM_Message;
1108 break;
1109 }
1110
1111 if (K != OCM_Message) {
1112 const_cast<ObjCMethodCall *>(this)->Data
1113 = ObjCMessageDataTy(POE, K).getOpaqueValue();
1114 assert(getMessageKind() == K);
1115 return K;
1116 }
1117 }
1118
1119 const_cast<ObjCMethodCall *>(this)->Data
1120 = ObjCMessageDataTy(nullptr, 1).getOpaqueValue();
1121 assert(getMessageKind() == OCM_Message);
1122 return OCM_Message;
1123 }
1124
1125 ObjCMessageDataTy Info = ObjCMessageDataTy::getFromOpaqueValue(Data);
1126 if (!Info.getPointer())
1127 return OCM_Message;
1128 return static_cast<ObjCMessageKind>(Info.getInt());
1129}
1130
1132 // Look for properties accessed with property syntax (foo.bar = ...)
1134 const PseudoObjectExpr *POE = getContainingPseudoObjectExpr();
1135 assert(POE && "Property access without PseudoObjectExpr?");
1136
1137 const Expr *Syntactic = getSyntacticFromForPseudoObjectExpr(POE);
1138 auto *RefExpr = cast<ObjCPropertyRefExpr>(Syntactic);
1139
1140 if (RefExpr->isExplicitProperty())
1141 return RefExpr->getExplicitProperty();
1142 }
1143
1144 // Look for properties accessed with method syntax ([foo setBar:...]).
1145 const ObjCMethodDecl *MD = getDecl();
1146 if (!MD || !MD->isPropertyAccessor())
1147 return nullptr;
1148
1149 // Note: This is potentially quite slow.
1150 return MD->findPropertyDecl();
1151}
1152
1154 Selector Sel) const {
1155 assert(IDecl);
1156 AnalysisManager &AMgr =
1157 getState()->getStateManager().getOwningEngine().getAnalysisManager();
1158 // If the class interface is declared inside the main file, assume it is not
1159 // subcassed.
1160 // TODO: It could actually be subclassed if the subclass is private as well.
1161 // This is probably very rare.
1162 SourceLocation InterfLoc = IDecl->getEndOfDefinitionLoc();
1163 if (InterfLoc.isValid() && AMgr.isInCodeFile(InterfLoc))
1164 return false;
1165
1166 // Assume that property accessors are not overridden.
1168 return false;
1169
1170 // We assume that if the method is public (declared outside of main file) or
1171 // has a parent which publicly declares the method, the method could be
1172 // overridden in a subclass.
1173
1174 // Find the first declaration in the class hierarchy that declares
1175 // the selector.
1176 ObjCMethodDecl *D = nullptr;
1177 while (true) {
1178 D = IDecl->lookupMethod(Sel, true);
1179
1180 // Cannot find a public definition.
1181 if (!D)
1182 return false;
1183
1184 // If outside the main file,
1185 if (D->getLocation().isValid() && !AMgr.isInCodeFile(D->getLocation()))
1186 return true;
1187
1188 if (D->isOverriding()) {
1189 // Search in the superclass on the next iteration.
1190 IDecl = D->getClassInterface();
1191 if (!IDecl)
1192 return false;
1193
1194 IDecl = IDecl->getSuperClass();
1195 if (!IDecl)
1196 return false;
1197
1198 continue;
1199 }
1200
1201 return false;
1202 };
1203
1204 llvm_unreachable("The while loop should always terminate.");
1205}
1206
1208 if (!MD)
1209 return MD;
1210
1211 // Find the redeclaration that defines the method.
1212 if (!MD->hasBody()) {
1213 for (auto *I : MD->redecls())
1214 if (I->hasBody())
1215 MD = cast<ObjCMethodDecl>(I);
1216 }
1217 return MD;
1218}
1219
1225
1226namespace llvm {
1227template <> struct DenseMapInfo<PrivateMethodKey> {
1228 using InterfaceInfo = DenseMapInfo<const ObjCInterfaceDecl *>;
1229 using SelectorInfo = DenseMapInfo<Selector>;
1230
1232 return {InterfaceInfo::getEmptyKey(), SelectorInfo::getEmptyKey(), false};
1233 }
1234
1236 return {InterfaceInfo::getTombstoneKey(), SelectorInfo::getTombstoneKey(),
1237 true};
1238 }
1239
1240 static unsigned getHashValue(const PrivateMethodKey &Key) {
1241 return llvm::hash_combine(
1242 llvm::hash_code(InterfaceInfo::getHashValue(Key.Interface)),
1243 llvm::hash_code(SelectorInfo::getHashValue(Key.LookupSelector)),
1244 Key.IsClassMethod);
1245 }
1246
1247 static bool isEqual(const PrivateMethodKey &LHS,
1248 const PrivateMethodKey &RHS) {
1249 return InterfaceInfo::isEqual(LHS.Interface, RHS.Interface) &&
1250 SelectorInfo::isEqual(LHS.LookupSelector, RHS.LookupSelector) &&
1251 LHS.IsClassMethod == RHS.IsClassMethod;
1252 }
1253};
1254} // end namespace llvm
1255
1256// NOTE: This cache is a "global" variable, and it is cleared by
1257// CallEventManager's constructor so we do not keep old entries when
1258// loading/unloading ASTs. If we are worried about concurrency, we may need to
1259// revisit this someday. In terms of memory, this table stays around until clang
1260// quits, which also may be bad if we need to release memory.
1262 llvm::DenseMap<PrivateMethodKey, std::optional<const ObjCMethodDecl *>>;
1264
1265static const ObjCMethodDecl *
1267 Selector LookupSelector, bool InstanceMethod) {
1268 // Repeatedly calling lookupPrivateMethod() is expensive, especially
1269 // when in many cases it returns null. We cache the results so
1270 // that repeated queries on the same ObjCIntefaceDecl and Selector
1271 // don't incur the same cost. On some test cases, we can see the
1272 // same query being issued thousands of times.
1273 std::optional<const ObjCMethodDecl *> &Val =
1274 PrivateMethodCache[{Interface, LookupSelector, InstanceMethod}];
1275
1276 // Query lookupPrivateMethod() if the cache does not hit.
1277 if (!Val) {
1278 Val = Interface->lookupPrivateMethod(LookupSelector, InstanceMethod);
1279
1280 if (!*Val) {
1281 // Query 'lookupMethod' as a backup.
1282 Val = Interface->lookupMethod(LookupSelector, InstanceMethod);
1283 }
1284 }
1285
1286 return *Val;
1287}
1288
1290 const ObjCMessageExpr *E = getOriginExpr();
1291 assert(E);
1292 Selector Sel = E->getSelector();
1293
1294 if (E->isInstanceMessage()) {
1295 // Find the receiver type.
1296 const ObjCObjectType *ReceiverT = nullptr;
1297 bool CanBeSubClassed = false;
1298 bool LookingForInstanceMethod = true;
1299 QualType SupersType = E->getSuperType();
1300 const MemRegion *Receiver = nullptr;
1301
1302 if (!SupersType.isNull()) {
1303 // The receiver is guaranteed to be 'super' in this case.
1304 // Super always means the type of immediate predecessor to the method
1305 // where the call occurs.
1306 ReceiverT = cast<ObjCObjectPointerType>(SupersType)->getObjectType();
1307 } else {
1308 Receiver = getReceiverSVal().getAsRegion();
1309 if (!Receiver)
1310 return {};
1311
1312 DynamicTypeInfo DTI = getDynamicTypeInfo(getState(), Receiver);
1313 if (!DTI.isValid()) {
1314 assert(isa<AllocaRegion>(Receiver) &&
1315 "Unhandled untyped region class!");
1316 return {};
1317 }
1318
1319 QualType DynType = DTI.getType();
1320 CanBeSubClassed = DTI.canBeASubClass();
1321
1322 const auto *ReceiverDynT =
1323 dyn_cast<ObjCObjectPointerType>(DynType.getCanonicalType());
1324
1325 if (ReceiverDynT) {
1326 ReceiverT = ReceiverDynT->getObjectType();
1327
1328 // It can be actually class methods called with Class object as a
1329 // receiver. This type of messages is treated by the compiler as
1330 // instance (not class).
1331 if (ReceiverT->isObjCClass()) {
1332
1333 SVal SelfVal = getState()->getSelfSVal(getLocationContext());
1334 // For [self classMethod], return compiler visible declaration.
1335 if (Receiver == SelfVal.getAsRegion()) {
1337 }
1338
1339 // Otherwise, let's check if we know something about the type
1340 // inside of this class object.
1341 if (SymbolRef ReceiverSym = getReceiverSVal().getAsSymbol()) {
1342 DynamicTypeInfo DTI =
1344 if (DTI.isValid()) {
1345 // Let's use this type for lookup.
1346 ReceiverT =
1348
1349 CanBeSubClassed = DTI.canBeASubClass();
1350 // And it should be a class method instead.
1351 LookingForInstanceMethod = false;
1352 }
1353 }
1354 }
1355
1356 if (CanBeSubClassed)
1357 if (ObjCInterfaceDecl *IDecl = ReceiverT->getInterface())
1358 // Even if `DynamicTypeInfo` told us that it can be
1359 // not necessarily this type, but its descendants, we still want
1360 // to check again if this selector can be actually overridden.
1361 CanBeSubClassed = canBeOverridenInSubclass(IDecl, Sel);
1362 }
1363 }
1364
1365 // Lookup the instance method implementation.
1366 if (ReceiverT)
1367 if (ObjCInterfaceDecl *IDecl = ReceiverT->getInterface()) {
1368 const ObjCMethodDecl *MD =
1369 lookupRuntimeDefinition(IDecl, Sel, LookingForInstanceMethod);
1370
1371 if (MD && !MD->hasBody())
1372 MD = MD->getCanonicalDecl();
1373
1374 if (CanBeSubClassed)
1375 return RuntimeDefinition(MD, Receiver);
1376 else
1377 return RuntimeDefinition(MD, nullptr);
1378 }
1379 } else {
1380 // This is a class method.
1381 // If we have type info for the receiver class, we are calling via
1382 // class name.
1383 if (ObjCInterfaceDecl *IDecl = E->getReceiverInterface()) {
1384 // Find/Return the method implementation.
1385 return RuntimeDefinition(IDecl->lookupPrivateClassMethod(Sel));
1386 }
1387 }
1388
1389 return {};
1390}
1391
1393 if (isInSystemHeader() && !isInstanceMessage()) {
1394 Selector Sel = getSelector();
1395 if (Sel.getNumArgs() == 1 &&
1396 Sel.getIdentifierInfoForSlot(0)->isStr("valueWithPointer"))
1397 return true;
1398 }
1399
1401}
1402
1404 const StackFrameContext *CalleeCtx,
1405 BindingsTy &Bindings) const {
1406 const auto *D = cast<ObjCMethodDecl>(CalleeCtx->getDecl());
1407 SValBuilder &SVB = getState()->getStateManager().getSValBuilder();
1408 addParameterValuesToBindings(CalleeCtx, Bindings, SVB, *this,
1409 D->parameters());
1410
1411 SVal SelfVal = getReceiverSVal();
1412 if (!SelfVal.isUnknown()) {
1413 const VarDecl *SelfD = CalleeCtx->getAnalysisDeclContext()->getSelfDecl();
1414 MemRegionManager &MRMgr = SVB.getRegionManager();
1415 Loc SelfLoc = SVB.makeLoc(MRMgr.getVarRegion(SelfD, CalleeCtx));
1416 Bindings.push_back(std::make_pair(SelfLoc, SelfVal));
1417 }
1418}
1419
1420CallEventManager::CallEventManager(llvm::BumpPtrAllocator &alloc)
1421 : Alloc(alloc) {
1422 // Clear the method cache to avoid hits when multiple AST are loaded/unloaded
1423 // within a single process. This can happen with unit tests, for instance.
1424 PrivateMethodCache.clear();
1425}
1426
1429 const LocationContext *LCtx,
1431 if (const auto *MCE = dyn_cast<CXXMemberCallExpr>(CE))
1432 return create<CXXMemberCall>(MCE, State, LCtx, ElemRef);
1433
1434 if (const auto *OpCE = dyn_cast<CXXOperatorCallExpr>(CE)) {
1435 const FunctionDecl *DirectCallee = OpCE->getDirectCallee();
1436 if (const auto *MD = dyn_cast<CXXMethodDecl>(DirectCallee)) {
1437 if (MD->isImplicitObjectMemberFunction())
1438 return create<CXXMemberOperatorCall>(OpCE, State, LCtx, ElemRef);
1439 if (MD->isStatic())
1440 return create<CXXStaticOperatorCall>(OpCE, State, LCtx, ElemRef);
1441 }
1442
1443 } else if (CE->getCallee()->getType()->isBlockPointerType()) {
1444 return create<BlockCall>(CE, State, LCtx, ElemRef);
1445 }
1446
1447 // Otherwise, it's a normal function call, static member function call, or
1448 // something we can't reason about.
1449 return create<SimpleFunctionCall>(CE, State, LCtx, ElemRef);
1450}
1451
1454 ProgramStateRef State) {
1455 const LocationContext *ParentCtx = CalleeCtx->getParent();
1456 const LocationContext *CallerCtx = ParentCtx->getStackFrame();
1457 CFGBlock::ConstCFGElementRef ElemRef = {CalleeCtx->getCallSiteBlock(),
1458 CalleeCtx->getIndex()};
1459 assert(CallerCtx && "This should not be used for top-level stack frames");
1460
1461 const Stmt *CallSite = CalleeCtx->getCallSite();
1462
1463 if (CallSite) {
1464 if (CallEventRef<> Out = getCall(CallSite, State, CallerCtx, ElemRef))
1465 return Out;
1466
1467 SValBuilder &SVB = State->getStateManager().getSValBuilder();
1468 const auto *Ctor = cast<CXXMethodDecl>(CalleeCtx->getDecl());
1469 Loc ThisPtr = SVB.getCXXThis(Ctor, CalleeCtx);
1470 SVal ThisVal = State->getSVal(ThisPtr);
1471
1472 if (const auto *CE = dyn_cast<CXXConstructExpr>(CallSite))
1473 return getCXXConstructorCall(CE, ThisVal.getAsRegion(), State, CallerCtx,
1474 ElemRef);
1475 else if (const auto *CIE = dyn_cast<CXXInheritedCtorInitExpr>(CallSite))
1476 return getCXXInheritedConstructorCall(CIE, ThisVal.getAsRegion(), State,
1477 CallerCtx, ElemRef);
1478 else {
1479 // All other cases are handled by getCall.
1480 llvm_unreachable("This is not an inlineable statement");
1481 }
1482 }
1483
1484 // Fall back to the CFG. The only thing we haven't handled yet is
1485 // destructors, though this could change in the future.
1486 const CFGBlock *B = CalleeCtx->getCallSiteBlock();
1487 CFGElement E = (*B)[CalleeCtx->getIndex()];
1488 assert((E.getAs<CFGImplicitDtor>() || E.getAs<CFGTemporaryDtor>()) &&
1489 "All other CFG elements should have exprs");
1490
1491 SValBuilder &SVB = State->getStateManager().getSValBuilder();
1492 const auto *Dtor = cast<CXXDestructorDecl>(CalleeCtx->getDecl());
1493 Loc ThisPtr = SVB.getCXXThis(Dtor, CalleeCtx);
1494 SVal ThisVal = State->getSVal(ThisPtr);
1495
1496 const Stmt *Trigger;
1497 if (std::optional<CFGAutomaticObjDtor> AutoDtor =
1499 Trigger = AutoDtor->getTriggerStmt();
1500 else if (std::optional<CFGDeleteDtor> DeleteDtor = E.getAs<CFGDeleteDtor>())
1501 Trigger = DeleteDtor->getDeleteExpr();
1502 else
1503 Trigger = Dtor->getBody();
1504
1505 return getCXXDestructorCall(Dtor, Trigger, ThisVal.getAsRegion(),
1506 E.getAs<CFGBaseDtor>().has_value(), State,
1507 CallerCtx, ElemRef);
1508}
1509
1511 const LocationContext *LC,
1513 if (const auto *CE = dyn_cast<CallExpr>(S)) {
1514 return getSimpleCall(CE, State, LC, ElemRef);
1515 } else if (const auto *NE = dyn_cast<CXXNewExpr>(S)) {
1516 return getCXXAllocatorCall(NE, State, LC, ElemRef);
1517 } else if (const auto *DE = dyn_cast<CXXDeleteExpr>(S)) {
1518 return getCXXDeallocatorCall(DE, State, LC, ElemRef);
1519 } else if (const auto *ME = dyn_cast<ObjCMessageExpr>(S)) {
1520 return getObjCMethodCall(ME, State, LC, ElemRef);
1521 } else {
1522 return nullptr;
1523 }
1524}
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 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:220
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:825
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:4654
ArrayRef< ParmVarDecl * > parameters() const
Definition Decl.h:4740
Represents C++ object destructor implicitly generated for automatic object or temporary bound to cons...
Definition CFG.h:418
Represents C++ object destructor implicitly generated for base object in destructor.
Definition CFG.h:469
Represents a single basic block in a source-level CFG.
Definition CFG.h:605
unsigned size() const
Definition CFG.h:952
ElementRefImpl< true > ConstCFGElementRef
Definition CFG.h:921
Represents a function call that returns a C++ object by value.
Definition CFG.h:186
Represents C++ constructor call.
Definition CFG.h:157
Represents C++ object destructor generated from a call to delete.
Definition CFG.h:443
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:109
Represents C++ object destructor implicitly generated by compiler on various occasions.
Definition CFG.h:367
CFGBlock * getBlock(Stmt *S)
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:511
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:2129
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined.
Definition DeclCXX.h:2255
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:2877
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
Definition Expr.h:3081
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return null.
Definition Expr.h:3060
Expr * getCallee()
Definition Expr.h:3024
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:3081
QualType getType() const
Definition Expr.h:144
Represents a function declaration or definition.
Definition Decl.h:2000
ArrayRef< ParmVarDecl * > parameters() const
Definition Decl.h:2774
FunctionType - C99 6.7.5.3 - Function Declarators.
Definition TypeBase.h:4450
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:940
Selector getSelector() const
Definition ExprObjC.cpp:289
@ SuperInstance
The receiver is the instance of the superclass object.
Definition ExprObjC.h:954
@ SuperClass
The receiver is a superclass.
Definition ExprObjC.h:951
bool isInstanceMessage() const
Determine whether this is an instance message to either a computed object or to super.
Definition ExprObjC.h:1256
ObjCInterfaceDecl * getReceiverInterface() const
Retrieve the Objective-C interface to which this message is being directed, if known.
Definition ExprObjC.cpp:310
QualType getSuperType() const
Retrieve the type referred to by 'super'.
Definition ExprObjC.h:1344
const ObjCMethodDecl * getMethodDecl() const
Definition ExprObjC.h:1364
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:1790
PointerType - C99 6.7.5.1 - Pointer Declarators.
Definition TypeBase.h:3328
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:6690
Expr * getSyntacticForm()
Return the syntactic form of this expression, i.e.
Definition Expr.h:6727
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:8330
bool isConstQualified() const
Determine whether this type is const-qualified.
Definition TypeBase.h:8351
Represents a struct/union/class.
Definition Decl.h:4312
field_range fields() const
Definition Decl.h:4515
RecordDecl * getDefinitionOrSelf() const
Definition Decl.h:4500
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:85
StmtClass getStmtClass() const
Definition Stmt.h:1472
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
Definition Stmt.cpp:338
A container of type source information.
Definition TypeBase.h:8249
bool isBlockPointerType() const
Definition TypeBase.h:8535
bool isVoidType() const
Definition TypeBase.h:8871
bool isFunctionPointerType() const
Definition TypeBase.h:8582
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:1909
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
Definition Type.cpp:752
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
Definition TypeBase.h:2782
bool isAnyPointerType() const
Definition TypeBase.h:8523
const T * getAs() const
Member-template getAs<specific type>'.
Definition TypeBase.h:9091
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:527
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:620
const BlockDataRegion * getBlockRegion() const
Returns the region associated with this instance of the block.
bool isConversionFromLambda() const
Definition CallEvent.h:627
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:637
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:605
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:954
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:715
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:820
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:865
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:1469
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:1485
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:1447
CallEventManager(llvm::BumpPtrAllocator &alloc)
CallEventRef< CXXAllocatorCall > getCXXAllocatorCall(const CXXNewExpr *E, ProgramStateRef State, const LocationContext *LCtx, CFGBlock::ConstCFGElementRef ElemRef)
Definition CallEvent.h:1478
CallEventRef< CXXConstructorCall > getCXXConstructorCall(const CXXConstructExpr *E, const MemRegion *Target, ProgramStateRef State, const LocationContext *LCtx, CFGBlock::ConstCFGElementRef ElemRef)
Definition CallEvent.h:1454
CallEventRef< CXXInheritedConstructorCall > getCXXInheritedConstructorCall(const CXXInheritedCtorInitExpr *E, const MemRegion *Target, ProgramStateRef State, const LocationContext *LCtx, CFGBlock::ConstCFGElementRef ElemRef)
Definition CallEvent.h:1461
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:501
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.
ProgramStateRef invalidateRegions(unsigned BlockCount, ProgramStateRef Orig=nullptr) const
Returns a new state with all argument regions invalidated.
virtual std::optional< unsigned > getAdjustedParameterIndex(unsigned ASTArgumentIndex) const
Some calls have parameter numbering mismatched from argument numbering.
Definition CallEvent.h:447
QualType getResultType() const
Returns the result type, adjusted for references.
Definition CallEvent.cpp:70
friend class CallEventManager
Definition CallEvent.h:182
llvm::mapped_iterator< ArrayRef< ParmVarDecl * >::iterator, GetTypeFn > param_type_iterator
Definition CallEvent.h:489
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:497
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:435
SmallVectorImpl< FrameBindingTy > BindingsTy
Definition CallEvent.h:383
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.
SVal computeObjectUnderConstruction(const Expr *E, ProgramStateRef State, const NodeBuilderContext *BldrCtx, 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 NodeBuilderContext & getBuilderContext()
Definition ExprEngine.h:220
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:1293
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:1289
ObjCMethodCall(const ObjCMessageExpr *Msg, ProgramStateRef St, const LocationContext *LCtx, CFGBlock::ConstCFGElementRef ElemRef)
Definition CallEvent.h:1269
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:1311
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:564
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:1258
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
const FunctionProtoType * T
U cast(CodeGen::Address addr)
Definition Address.h:327
@ Interface
The "__interface" keyword introduces the elaborated-type-specifier.
Definition TypeBase.h:5858
@ Class
The "class" keyword introduces the elaborated-type-specifier.
Definition TypeBase.h:5864
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:97
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()