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