xref: /freebsd-src/contrib/llvm-project/clang/lib/StaticAnalyzer/Core/CallEvent.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===- CallEvent.cpp - Wrapper for all function and method calls ----------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric /// \file This file defines CallEvent and its subclasses, which represent path-
100b57cec5SDimitry Andric /// sensitive instances of different kinds of function and method calls
110b57cec5SDimitry Andric /// (C, C++, and Objective-C).
120b57cec5SDimitry Andric //
130b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
140b57cec5SDimitry Andric 
150b57cec5SDimitry Andric #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
160b57cec5SDimitry Andric #include "clang/AST/ASTContext.h"
17480093f4SDimitry Andric #include "clang/AST/Attr.h"
180b57cec5SDimitry Andric #include "clang/AST/Decl.h"
190b57cec5SDimitry Andric #include "clang/AST/DeclBase.h"
200b57cec5SDimitry Andric #include "clang/AST/DeclCXX.h"
210b57cec5SDimitry Andric #include "clang/AST/DeclObjC.h"
220b57cec5SDimitry Andric #include "clang/AST/Expr.h"
230b57cec5SDimitry Andric #include "clang/AST/ExprCXX.h"
240b57cec5SDimitry Andric #include "clang/AST/ExprObjC.h"
250b57cec5SDimitry Andric #include "clang/AST/ParentMap.h"
260b57cec5SDimitry Andric #include "clang/AST/Stmt.h"
270b57cec5SDimitry Andric #include "clang/AST/Type.h"
280b57cec5SDimitry Andric #include "clang/Analysis/AnalysisDeclContext.h"
290b57cec5SDimitry Andric #include "clang/Analysis/CFG.h"
300b57cec5SDimitry Andric #include "clang/Analysis/CFGStmtMap.h"
31a7dea167SDimitry Andric #include "clang/Analysis/PathDiagnostic.h"
320b57cec5SDimitry Andric #include "clang/Analysis/ProgramPoint.h"
330b57cec5SDimitry Andric #include "clang/Basic/IdentifierTable.h"
340b57cec5SDimitry Andric #include "clang/Basic/LLVM.h"
350b57cec5SDimitry Andric #include "clang/Basic/SourceLocation.h"
360b57cec5SDimitry Andric #include "clang/Basic/SourceManager.h"
370b57cec5SDimitry Andric #include "clang/Basic/Specifiers.h"
38480093f4SDimitry Andric #include "clang/CrossTU/CrossTranslationUnit.h"
39349cc55cSDimitry Andric #include "clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h"
400b57cec5SDimitry Andric #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
41a7dea167SDimitry Andric #include "clang/StaticAnalyzer/Core/PathSensitive/DynamicType.h"
42480093f4SDimitry Andric #include "clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeInfo.h"
430b57cec5SDimitry Andric #include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
440b57cec5SDimitry Andric #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
450b57cec5SDimitry Andric #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h"
460b57cec5SDimitry Andric #include "clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h"
47480093f4SDimitry Andric #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
480b57cec5SDimitry Andric #include "clang/StaticAnalyzer/Core/PathSensitive/Store.h"
490b57cec5SDimitry Andric #include "llvm/ADT/ArrayRef.h"
500b57cec5SDimitry Andric #include "llvm/ADT/DenseMap.h"
51fe6060f1SDimitry Andric #include "llvm/ADT/ImmutableList.h"
520b57cec5SDimitry Andric #include "llvm/ADT/PointerIntPair.h"
530b57cec5SDimitry Andric #include "llvm/ADT/SmallSet.h"
540b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h"
550b57cec5SDimitry Andric #include "llvm/ADT/StringExtras.h"
560b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h"
570b57cec5SDimitry Andric #include "llvm/Support/Casting.h"
580b57cec5SDimitry Andric #include "llvm/Support/Compiler.h"
590b57cec5SDimitry Andric #include "llvm/Support/Debug.h"
600b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
610b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
620b57cec5SDimitry Andric #include <cassert>
63bdd1243dSDimitry Andric #include <optional>
640b57cec5SDimitry Andric #include <utility>
650b57cec5SDimitry Andric 
660b57cec5SDimitry Andric #define DEBUG_TYPE "static-analyzer-call-event"
670b57cec5SDimitry Andric 
680b57cec5SDimitry Andric using namespace clang;
690b57cec5SDimitry Andric using namespace ento;
700b57cec5SDimitry Andric 
710b57cec5SDimitry Andric QualType CallEvent::getResultType() const {
720b57cec5SDimitry Andric   ASTContext &Ctx = getState()->getStateManager().getContext();
730b57cec5SDimitry Andric   const Expr *E = getOriginExpr();
740b57cec5SDimitry Andric   if (!E)
750b57cec5SDimitry Andric     return Ctx.VoidTy;
76349cc55cSDimitry Andric   return Ctx.getReferenceQualifiedType(E);
770b57cec5SDimitry Andric }
780b57cec5SDimitry Andric 
790b57cec5SDimitry Andric static bool isCallback(QualType T) {
800b57cec5SDimitry Andric   // If a parameter is a block or a callback, assume it can modify pointer.
810b57cec5SDimitry Andric   if (T->isBlockPointerType() ||
820b57cec5SDimitry Andric       T->isFunctionPointerType() ||
830b57cec5SDimitry Andric       T->isObjCSelType())
840b57cec5SDimitry Andric     return true;
850b57cec5SDimitry Andric 
860b57cec5SDimitry Andric   // Check if a callback is passed inside a struct (for both, struct passed by
870b57cec5SDimitry Andric   // reference and by value). Dig just one level into the struct for now.
880b57cec5SDimitry Andric 
890b57cec5SDimitry Andric   if (T->isAnyPointerType() || T->isReferenceType())
900b57cec5SDimitry Andric     T = T->getPointeeType();
910b57cec5SDimitry Andric 
920b57cec5SDimitry Andric   if (const RecordType *RT = T->getAsStructureType()) {
930b57cec5SDimitry Andric     const RecordDecl *RD = RT->getDecl();
940b57cec5SDimitry Andric     for (const auto *I : RD->fields()) {
950b57cec5SDimitry Andric       QualType FieldT = I->getType();
960b57cec5SDimitry Andric       if (FieldT->isBlockPointerType() || FieldT->isFunctionPointerType())
970b57cec5SDimitry Andric         return true;
980b57cec5SDimitry Andric     }
990b57cec5SDimitry Andric   }
1000b57cec5SDimitry Andric   return false;
1010b57cec5SDimitry Andric }
1020b57cec5SDimitry Andric 
1030b57cec5SDimitry Andric static bool isVoidPointerToNonConst(QualType T) {
1040b57cec5SDimitry Andric   if (const auto *PT = T->getAs<PointerType>()) {
1050b57cec5SDimitry Andric     QualType PointeeTy = PT->getPointeeType();
1060b57cec5SDimitry Andric     if (PointeeTy.isConstQualified())
1070b57cec5SDimitry Andric       return false;
1080b57cec5SDimitry Andric     return PointeeTy->isVoidType();
1090b57cec5SDimitry Andric   } else
1100b57cec5SDimitry Andric     return false;
1110b57cec5SDimitry Andric }
1120b57cec5SDimitry Andric 
1130b57cec5SDimitry Andric bool CallEvent::hasNonNullArgumentsWithType(bool (*Condition)(QualType)) const {
1140b57cec5SDimitry Andric   unsigned NumOfArgs = getNumArgs();
1150b57cec5SDimitry Andric 
1160b57cec5SDimitry Andric   // If calling using a function pointer, assume the function does not
1170b57cec5SDimitry Andric   // satisfy the callback.
1180b57cec5SDimitry Andric   // TODO: We could check the types of the arguments here.
1190b57cec5SDimitry Andric   if (!getDecl())
1200b57cec5SDimitry Andric     return false;
1210b57cec5SDimitry Andric 
1220b57cec5SDimitry Andric   unsigned Idx = 0;
1230b57cec5SDimitry Andric   for (CallEvent::param_type_iterator I = param_type_begin(),
1240b57cec5SDimitry Andric                                       E = param_type_end();
1250b57cec5SDimitry Andric        I != E && Idx < NumOfArgs; ++I, ++Idx) {
1260b57cec5SDimitry Andric     // If the parameter is 0, it's harmless.
1270b57cec5SDimitry Andric     if (getArgSVal(Idx).isZeroConstant())
1280b57cec5SDimitry Andric       continue;
1290b57cec5SDimitry Andric 
1300b57cec5SDimitry Andric     if (Condition(*I))
1310b57cec5SDimitry Andric       return true;
1320b57cec5SDimitry Andric   }
1330b57cec5SDimitry Andric   return false;
1340b57cec5SDimitry Andric }
1350b57cec5SDimitry Andric 
1360b57cec5SDimitry Andric bool CallEvent::hasNonZeroCallbackArg() const {
1370b57cec5SDimitry Andric   return hasNonNullArgumentsWithType(isCallback);
1380b57cec5SDimitry Andric }
1390b57cec5SDimitry Andric 
1400b57cec5SDimitry Andric bool CallEvent::hasVoidPointerToNonConstArg() const {
1410b57cec5SDimitry Andric   return hasNonNullArgumentsWithType(isVoidPointerToNonConst);
1420b57cec5SDimitry Andric }
1430b57cec5SDimitry Andric 
1440b57cec5SDimitry Andric bool CallEvent::isGlobalCFunction(StringRef FunctionName) const {
1450b57cec5SDimitry Andric   const auto *FD = dyn_cast_or_null<FunctionDecl>(getDecl());
1460b57cec5SDimitry Andric   if (!FD)
1470b57cec5SDimitry Andric     return false;
1480b57cec5SDimitry Andric 
1490b57cec5SDimitry Andric   return CheckerContext::isCLibraryFunction(FD, FunctionName);
1500b57cec5SDimitry Andric }
1510b57cec5SDimitry Andric 
1520b57cec5SDimitry Andric AnalysisDeclContext *CallEvent::getCalleeAnalysisDeclContext() const {
1530b57cec5SDimitry Andric   const Decl *D = getDecl();
1540b57cec5SDimitry Andric   if (!D)
1550b57cec5SDimitry Andric     return nullptr;
1560b57cec5SDimitry Andric 
1570b57cec5SDimitry Andric   AnalysisDeclContext *ADC =
1580b57cec5SDimitry Andric       LCtx->getAnalysisDeclContext()->getManager()->getContext(D);
1590b57cec5SDimitry Andric 
1600b57cec5SDimitry Andric   return ADC;
1610b57cec5SDimitry Andric }
1620b57cec5SDimitry Andric 
163a7dea167SDimitry Andric const StackFrameContext *
164a7dea167SDimitry Andric CallEvent::getCalleeStackFrame(unsigned BlockCount) const {
1650b57cec5SDimitry Andric   AnalysisDeclContext *ADC = getCalleeAnalysisDeclContext();
1660b57cec5SDimitry Andric   if (!ADC)
1670b57cec5SDimitry Andric     return nullptr;
1680b57cec5SDimitry Andric 
1690b57cec5SDimitry Andric   const Expr *E = getOriginExpr();
1700b57cec5SDimitry Andric   if (!E)
1710b57cec5SDimitry Andric     return nullptr;
1720b57cec5SDimitry Andric 
1730b57cec5SDimitry Andric   // Recover CFG block via reverse lookup.
1740b57cec5SDimitry Andric   // TODO: If we were to keep CFG element information as part of the CallEvent
1750b57cec5SDimitry Andric   // instead of doing this reverse lookup, we would be able to build the stack
1760b57cec5SDimitry Andric   // frame for non-expression-based calls, and also we wouldn't need the reverse
1770b57cec5SDimitry Andric   // lookup.
1780b57cec5SDimitry Andric   CFGStmtMap *Map = LCtx->getAnalysisDeclContext()->getCFGStmtMap();
1790b57cec5SDimitry Andric   const CFGBlock *B = Map->getBlock(E);
1800b57cec5SDimitry Andric   assert(B);
1810b57cec5SDimitry Andric 
1820b57cec5SDimitry Andric   // Also recover CFG index by scanning the CFG block.
1830b57cec5SDimitry Andric   unsigned Idx = 0, Sz = B->size();
1840b57cec5SDimitry Andric   for (; Idx < Sz; ++Idx)
1850b57cec5SDimitry Andric     if (auto StmtElem = (*B)[Idx].getAs<CFGStmt>())
1860b57cec5SDimitry Andric       if (StmtElem->getStmt() == E)
1870b57cec5SDimitry Andric         break;
1880b57cec5SDimitry Andric   assert(Idx < Sz);
1890b57cec5SDimitry Andric 
190a7dea167SDimitry Andric   return ADC->getManager()->getStackFrame(ADC, LCtx, E, B, BlockCount, Idx);
1910b57cec5SDimitry Andric }
1920b57cec5SDimitry Andric 
1935ffd83dbSDimitry Andric const ParamVarRegion
1945ffd83dbSDimitry Andric *CallEvent::getParameterLocation(unsigned Index, unsigned BlockCount) const {
195a7dea167SDimitry Andric   const StackFrameContext *SFC = getCalleeStackFrame(BlockCount);
1960b57cec5SDimitry Andric   // We cannot construct a VarRegion without a stack frame.
1970b57cec5SDimitry Andric   if (!SFC)
1980b57cec5SDimitry Andric     return nullptr;
1990b57cec5SDimitry Andric 
2005ffd83dbSDimitry Andric   const ParamVarRegion *PVR =
2015ffd83dbSDimitry Andric     State->getStateManager().getRegionManager().getParamVarRegion(
2025ffd83dbSDimitry Andric         getOriginExpr(), Index, SFC);
2035ffd83dbSDimitry Andric   return PVR;
2040b57cec5SDimitry Andric }
2050b57cec5SDimitry Andric 
2060b57cec5SDimitry Andric /// Returns true if a type is a pointer-to-const or reference-to-const
2070b57cec5SDimitry Andric /// with no further indirection.
2080b57cec5SDimitry Andric static bool isPointerToConst(QualType Ty) {
2090b57cec5SDimitry Andric   QualType PointeeTy = Ty->getPointeeType();
2100b57cec5SDimitry Andric   if (PointeeTy == QualType())
2110b57cec5SDimitry Andric     return false;
2120b57cec5SDimitry Andric   if (!PointeeTy.isConstQualified())
2130b57cec5SDimitry Andric     return false;
2140b57cec5SDimitry Andric   if (PointeeTy->isAnyPointerType())
2150b57cec5SDimitry Andric     return false;
2160b57cec5SDimitry Andric   return true;
2170b57cec5SDimitry Andric }
2180b57cec5SDimitry Andric 
2190b57cec5SDimitry Andric // Try to retrieve the function declaration and find the function parameter
2200b57cec5SDimitry Andric // types which are pointers/references to a non-pointer const.
2210b57cec5SDimitry Andric // We will not invalidate the corresponding argument regions.
2220b57cec5SDimitry Andric static void findPtrToConstParams(llvm::SmallSet<unsigned, 4> &PreserveArgs,
2230b57cec5SDimitry Andric                                  const CallEvent &Call) {
2240b57cec5SDimitry Andric   unsigned Idx = 0;
2250b57cec5SDimitry Andric   for (CallEvent::param_type_iterator I = Call.param_type_begin(),
2260b57cec5SDimitry Andric                                       E = Call.param_type_end();
2270b57cec5SDimitry Andric        I != E; ++I, ++Idx) {
2280b57cec5SDimitry Andric     if (isPointerToConst(*I))
2290b57cec5SDimitry Andric       PreserveArgs.insert(Idx);
2300b57cec5SDimitry Andric   }
2310b57cec5SDimitry Andric }
2320b57cec5SDimitry Andric 
2330b57cec5SDimitry Andric ProgramStateRef CallEvent::invalidateRegions(unsigned BlockCount,
2340b57cec5SDimitry Andric                                              ProgramStateRef Orig) const {
2350b57cec5SDimitry Andric   ProgramStateRef Result = (Orig ? Orig : getState());
2360b57cec5SDimitry Andric 
2370b57cec5SDimitry Andric   // Don't invalidate anything if the callee is marked pure/const.
2380b57cec5SDimitry Andric   if (const Decl *callee = getDecl())
2390b57cec5SDimitry Andric     if (callee->hasAttr<PureAttr>() || callee->hasAttr<ConstAttr>())
2400b57cec5SDimitry Andric       return Result;
2410b57cec5SDimitry Andric 
2420b57cec5SDimitry Andric   SmallVector<SVal, 8> ValuesToInvalidate;
2430b57cec5SDimitry Andric   RegionAndSymbolInvalidationTraits ETraits;
2440b57cec5SDimitry Andric 
2450b57cec5SDimitry Andric   getExtraInvalidatedValues(ValuesToInvalidate, &ETraits);
2460b57cec5SDimitry Andric 
2470b57cec5SDimitry Andric   // Indexes of arguments whose values will be preserved by the call.
2480b57cec5SDimitry Andric   llvm::SmallSet<unsigned, 4> PreserveArgs;
2490b57cec5SDimitry Andric   if (!argumentsMayEscape())
2500b57cec5SDimitry Andric     findPtrToConstParams(PreserveArgs, *this);
2510b57cec5SDimitry Andric 
2520b57cec5SDimitry Andric   for (unsigned Idx = 0, Count = getNumArgs(); Idx != Count; ++Idx) {
2530b57cec5SDimitry Andric     // Mark this region for invalidation.  We batch invalidate regions
2540b57cec5SDimitry Andric     // below for efficiency.
2550b57cec5SDimitry Andric     if (PreserveArgs.count(Idx))
2560b57cec5SDimitry Andric       if (const MemRegion *MR = getArgSVal(Idx).getAsRegion())
2570b57cec5SDimitry Andric         ETraits.setTrait(MR->getBaseRegion(),
2580b57cec5SDimitry Andric                         RegionAndSymbolInvalidationTraits::TK_PreserveContents);
2590b57cec5SDimitry Andric         // TODO: Factor this out + handle the lower level const pointers.
2600b57cec5SDimitry Andric 
2610b57cec5SDimitry Andric     ValuesToInvalidate.push_back(getArgSVal(Idx));
2620b57cec5SDimitry Andric 
2630b57cec5SDimitry Andric     // If a function accepts an object by argument (which would of course be a
2640b57cec5SDimitry Andric     // temporary that isn't lifetime-extended), invalidate the object itself,
2650b57cec5SDimitry Andric     // not only other objects reachable from it. This is necessary because the
2660b57cec5SDimitry Andric     // destructor has access to the temporary object after the call.
2670b57cec5SDimitry Andric     // TODO: Support placement arguments once we start
2680b57cec5SDimitry Andric     // constructing them directly.
2690b57cec5SDimitry Andric     // TODO: This is unnecessary when there's no destructor, but that's
2700b57cec5SDimitry Andric     // currently hard to figure out.
2710b57cec5SDimitry Andric     if (getKind() != CE_CXXAllocator)
2720b57cec5SDimitry Andric       if (isArgumentConstructedDirectly(Idx))
2730b57cec5SDimitry Andric         if (auto AdjIdx = getAdjustedParameterIndex(Idx))
2745ffd83dbSDimitry Andric           if (const TypedValueRegion *TVR =
2755ffd83dbSDimitry Andric                   getParameterLocation(*AdjIdx, BlockCount))
2765ffd83dbSDimitry Andric             ValuesToInvalidate.push_back(loc::MemRegionVal(TVR));
2770b57cec5SDimitry Andric   }
2780b57cec5SDimitry Andric 
2790b57cec5SDimitry Andric   // Invalidate designated regions using the batch invalidation API.
2800b57cec5SDimitry Andric   // NOTE: Even if RegionsToInvalidate is empty, we may still invalidate
2810b57cec5SDimitry Andric   //  global variables.
2820b57cec5SDimitry Andric   return Result->invalidateRegions(ValuesToInvalidate, getOriginExpr(),
2830b57cec5SDimitry Andric                                    BlockCount, getLocationContext(),
2840b57cec5SDimitry Andric                                    /*CausedByPointerEscape*/ true,
2850b57cec5SDimitry Andric                                    /*Symbols=*/nullptr, this, &ETraits);
2860b57cec5SDimitry Andric }
2870b57cec5SDimitry Andric 
2880b57cec5SDimitry Andric ProgramPoint CallEvent::getProgramPoint(bool IsPreVisit,
2890b57cec5SDimitry Andric                                         const ProgramPointTag *Tag) const {
29006c3fb27SDimitry Andric 
2910b57cec5SDimitry Andric   if (const Expr *E = getOriginExpr()) {
2920b57cec5SDimitry Andric     if (IsPreVisit)
2930b57cec5SDimitry Andric       return PreStmt(E, getLocationContext(), Tag);
2940b57cec5SDimitry Andric     return PostStmt(E, getLocationContext(), Tag);
2950b57cec5SDimitry Andric   }
2960b57cec5SDimitry Andric 
2970b57cec5SDimitry Andric   const Decl *D = getDecl();
2980b57cec5SDimitry Andric   assert(D && "Cannot get a program point without a statement or decl");
29906c3fb27SDimitry Andric   assert(ElemRef.getParent() &&
30006c3fb27SDimitry Andric          "Cannot get a program point without a CFGElementRef");
3010b57cec5SDimitry Andric 
3020b57cec5SDimitry Andric   SourceLocation Loc = getSourceRange().getBegin();
3030b57cec5SDimitry Andric   if (IsPreVisit)
30406c3fb27SDimitry Andric     return PreImplicitCall(D, Loc, getLocationContext(), ElemRef, Tag);
30506c3fb27SDimitry Andric   return PostImplicitCall(D, Loc, getLocationContext(), ElemRef, Tag);
3060b57cec5SDimitry Andric }
3070b57cec5SDimitry Andric 
3080b57cec5SDimitry Andric SVal CallEvent::getArgSVal(unsigned Index) const {
3090b57cec5SDimitry Andric   const Expr *ArgE = getArgExpr(Index);
3100b57cec5SDimitry Andric   if (!ArgE)
3110b57cec5SDimitry Andric     return UnknownVal();
3120b57cec5SDimitry Andric   return getSVal(ArgE);
3130b57cec5SDimitry Andric }
3140b57cec5SDimitry Andric 
3150b57cec5SDimitry Andric SourceRange CallEvent::getArgSourceRange(unsigned Index) const {
3160b57cec5SDimitry Andric   const Expr *ArgE = getArgExpr(Index);
3170b57cec5SDimitry Andric   if (!ArgE)
3180b57cec5SDimitry Andric     return {};
3190b57cec5SDimitry Andric   return ArgE->getSourceRange();
3200b57cec5SDimitry Andric }
3210b57cec5SDimitry Andric 
3220b57cec5SDimitry Andric SVal CallEvent::getReturnValue() const {
3230b57cec5SDimitry Andric   const Expr *E = getOriginExpr();
3240b57cec5SDimitry Andric   if (!E)
3250b57cec5SDimitry Andric     return UndefinedVal();
3260b57cec5SDimitry Andric   return getSVal(E);
3270b57cec5SDimitry Andric }
3280b57cec5SDimitry Andric 
3290b57cec5SDimitry Andric LLVM_DUMP_METHOD void CallEvent::dump() const { dump(llvm::errs()); }
3300b57cec5SDimitry Andric 
3310b57cec5SDimitry Andric void CallEvent::dump(raw_ostream &Out) const {
3320b57cec5SDimitry Andric   ASTContext &Ctx = getState()->getStateManager().getContext();
3330b57cec5SDimitry Andric   if (const Expr *E = getOriginExpr()) {
3340b57cec5SDimitry Andric     E->printPretty(Out, nullptr, Ctx.getPrintingPolicy());
3350b57cec5SDimitry Andric     return;
3360b57cec5SDimitry Andric   }
3370b57cec5SDimitry Andric 
3380b57cec5SDimitry Andric   if (const Decl *D = getDecl()) {
3390b57cec5SDimitry Andric     Out << "Call to ";
3400b57cec5SDimitry Andric     D->print(Out, Ctx.getPrintingPolicy());
3410b57cec5SDimitry Andric     return;
3420b57cec5SDimitry Andric   }
3430b57cec5SDimitry Andric 
3445ffd83dbSDimitry Andric   Out << "Unknown call (type " << getKindAsString() << ")";
3450b57cec5SDimitry Andric }
3460b57cec5SDimitry Andric 
3470b57cec5SDimitry Andric bool CallEvent::isCallStmt(const Stmt *S) {
348349cc55cSDimitry Andric   return isa<CallExpr, ObjCMessageExpr, CXXConstructExpr, CXXNewExpr>(S);
3490b57cec5SDimitry Andric }
3500b57cec5SDimitry Andric 
3510b57cec5SDimitry Andric QualType CallEvent::getDeclaredResultType(const Decl *D) {
3520b57cec5SDimitry Andric   assert(D);
3530b57cec5SDimitry Andric   if (const auto *FD = dyn_cast<FunctionDecl>(D))
3540b57cec5SDimitry Andric     return FD->getReturnType();
3550b57cec5SDimitry Andric   if (const auto *MD = dyn_cast<ObjCMethodDecl>(D))
3560b57cec5SDimitry Andric     return MD->getReturnType();
3570b57cec5SDimitry Andric   if (const auto *BD = dyn_cast<BlockDecl>(D)) {
3580b57cec5SDimitry Andric     // Blocks are difficult because the return type may not be stored in the
3590b57cec5SDimitry Andric     // BlockDecl itself. The AST should probably be enhanced, but for now we
3600b57cec5SDimitry Andric     // just do what we can.
3610b57cec5SDimitry Andric     // If the block is declared without an explicit argument list, the
3620b57cec5SDimitry Andric     // signature-as-written just includes the return type, not the entire
3630b57cec5SDimitry Andric     // function type.
3640b57cec5SDimitry Andric     // FIXME: All blocks should have signatures-as-written, even if the return
3650b57cec5SDimitry Andric     // type is inferred. (That's signified with a dependent result type.)
3660b57cec5SDimitry Andric     if (const TypeSourceInfo *TSI = BD->getSignatureAsWritten()) {
3670b57cec5SDimitry Andric       QualType Ty = TSI->getType();
3680b57cec5SDimitry Andric       if (const FunctionType *FT = Ty->getAs<FunctionType>())
3690b57cec5SDimitry Andric         Ty = FT->getReturnType();
3700b57cec5SDimitry Andric       if (!Ty->isDependentType())
3710b57cec5SDimitry Andric         return Ty;
3720b57cec5SDimitry Andric     }
3730b57cec5SDimitry Andric 
3740b57cec5SDimitry Andric     return {};
3750b57cec5SDimitry Andric   }
3760b57cec5SDimitry Andric 
3770b57cec5SDimitry Andric   llvm_unreachable("unknown callable kind");
3780b57cec5SDimitry Andric }
3790b57cec5SDimitry Andric 
3800b57cec5SDimitry Andric bool CallEvent::isVariadic(const Decl *D) {
3810b57cec5SDimitry Andric   assert(D);
3820b57cec5SDimitry Andric 
3830b57cec5SDimitry Andric   if (const auto *FD = dyn_cast<FunctionDecl>(D))
3840b57cec5SDimitry Andric     return FD->isVariadic();
3850b57cec5SDimitry Andric   if (const auto *MD = dyn_cast<ObjCMethodDecl>(D))
3860b57cec5SDimitry Andric     return MD->isVariadic();
3870b57cec5SDimitry Andric   if (const auto *BD = dyn_cast<BlockDecl>(D))
3880b57cec5SDimitry Andric     return BD->isVariadic();
3890b57cec5SDimitry Andric 
3900b57cec5SDimitry Andric   llvm_unreachable("unknown callable kind");
3910b57cec5SDimitry Andric }
3920b57cec5SDimitry Andric 
393fe6060f1SDimitry Andric static bool isTransparentUnion(QualType T) {
394fe6060f1SDimitry Andric   const RecordType *UT = T->getAsUnionType();
395fe6060f1SDimitry Andric   return UT && UT->getDecl()->hasAttr<TransparentUnionAttr>();
396fe6060f1SDimitry Andric }
397fe6060f1SDimitry Andric 
398fe6060f1SDimitry Andric // In some cases, symbolic cases should be transformed before we associate
399fe6060f1SDimitry Andric // them with parameters.  This function incapsulates such cases.
400fe6060f1SDimitry Andric static SVal processArgument(SVal Value, const Expr *ArgumentExpr,
401fe6060f1SDimitry Andric                             const ParmVarDecl *Parameter, SValBuilder &SVB) {
402fe6060f1SDimitry Andric   QualType ParamType = Parameter->getType();
403fe6060f1SDimitry Andric   QualType ArgumentType = ArgumentExpr->getType();
404fe6060f1SDimitry Andric 
405fe6060f1SDimitry Andric   // Transparent unions allow users to easily convert values of union field
406fe6060f1SDimitry Andric   // types into union-typed objects.
407fe6060f1SDimitry Andric   //
408fe6060f1SDimitry Andric   // Also, more importantly, they allow users to define functions with different
409fe6060f1SDimitry Andric   // different parameter types, substituting types matching transparent union
410fe6060f1SDimitry Andric   // field types with the union type itself.
411fe6060f1SDimitry Andric   //
412fe6060f1SDimitry Andric   // Here, we check specifically for latter cases and prevent binding
413fe6060f1SDimitry Andric   // field-typed values to union-typed regions.
414fe6060f1SDimitry Andric   if (isTransparentUnion(ParamType) &&
415fe6060f1SDimitry Andric       // Let's check that we indeed trying to bind different types.
416fe6060f1SDimitry Andric       !isTransparentUnion(ArgumentType)) {
417fe6060f1SDimitry Andric     BasicValueFactory &BVF = SVB.getBasicValueFactory();
418fe6060f1SDimitry Andric 
419fe6060f1SDimitry Andric     llvm::ImmutableList<SVal> CompoundSVals = BVF.getEmptySValList();
420fe6060f1SDimitry Andric     CompoundSVals = BVF.prependSVal(Value, CompoundSVals);
421fe6060f1SDimitry Andric 
422fe6060f1SDimitry Andric     // Wrap it with compound value.
423fe6060f1SDimitry Andric     return SVB.makeCompoundVal(ParamType, CompoundSVals);
424fe6060f1SDimitry Andric   }
425fe6060f1SDimitry Andric 
426fe6060f1SDimitry Andric   return Value;
427fe6060f1SDimitry Andric }
428fe6060f1SDimitry Andric 
429bdd1243dSDimitry Andric /// Cast the argument value to the type of the parameter at the function
430bdd1243dSDimitry Andric /// declaration.
431bdd1243dSDimitry Andric /// Returns the argument value if it didn't need a cast.
432bdd1243dSDimitry Andric /// Or returns the cast argument if it needed a cast.
433bdd1243dSDimitry Andric /// Or returns 'Unknown' if it would need a cast but the callsite and the
434bdd1243dSDimitry Andric /// runtime definition don't match in terms of argument and parameter count.
435bdd1243dSDimitry Andric static SVal castArgToParamTypeIfNeeded(const CallEvent &Call, unsigned ArgIdx,
436bdd1243dSDimitry Andric                                        SVal ArgVal, SValBuilder &SVB) {
437bdd1243dSDimitry Andric   const FunctionDecl *RTDecl =
438bdd1243dSDimitry Andric       Call.getRuntimeDefinition().getDecl()->getAsFunction();
439bdd1243dSDimitry Andric   const auto *CallExprDecl = dyn_cast_or_null<FunctionDecl>(Call.getDecl());
440bdd1243dSDimitry Andric 
441bdd1243dSDimitry Andric   if (!RTDecl || !CallExprDecl)
442bdd1243dSDimitry Andric     return ArgVal;
443bdd1243dSDimitry Andric 
444bdd1243dSDimitry Andric   // The function decl of the Call (in the AST) will not have any parameter
445bdd1243dSDimitry Andric   // declarations, if it was 'only' declared without a prototype. However, the
446bdd1243dSDimitry Andric   // engine will find the appropriate runtime definition - basically a
447bdd1243dSDimitry Andric   // redeclaration, which has a function body (and a function prototype).
448bdd1243dSDimitry Andric   if (CallExprDecl->hasPrototype() || !RTDecl->hasPrototype())
449bdd1243dSDimitry Andric     return ArgVal;
450bdd1243dSDimitry Andric 
451bdd1243dSDimitry Andric   // Only do this cast if the number arguments at the callsite matches with
452bdd1243dSDimitry Andric   // the parameters at the runtime definition.
453bdd1243dSDimitry Andric   if (Call.getNumArgs() != RTDecl->getNumParams())
454bdd1243dSDimitry Andric     return UnknownVal();
455bdd1243dSDimitry Andric 
456bdd1243dSDimitry Andric   const Expr *ArgExpr = Call.getArgExpr(ArgIdx);
457bdd1243dSDimitry Andric   const ParmVarDecl *Param = RTDecl->getParamDecl(ArgIdx);
458bdd1243dSDimitry Andric   return SVB.evalCast(ArgVal, Param->getType(), ArgExpr->getType());
459bdd1243dSDimitry Andric }
460bdd1243dSDimitry Andric 
4610b57cec5SDimitry Andric static void addParameterValuesToBindings(const StackFrameContext *CalleeCtx,
4620b57cec5SDimitry Andric                                          CallEvent::BindingsTy &Bindings,
4630b57cec5SDimitry Andric                                          SValBuilder &SVB,
4640b57cec5SDimitry Andric                                          const CallEvent &Call,
4650b57cec5SDimitry Andric                                          ArrayRef<ParmVarDecl*> parameters) {
4660b57cec5SDimitry Andric   MemRegionManager &MRMgr = SVB.getRegionManager();
4670b57cec5SDimitry Andric 
4680b57cec5SDimitry Andric   // If the function has fewer parameters than the call has arguments, we simply
4690b57cec5SDimitry Andric   // do not bind any values to them.
4700b57cec5SDimitry Andric   unsigned NumArgs = Call.getNumArgs();
4710b57cec5SDimitry Andric   unsigned Idx = 0;
4720b57cec5SDimitry Andric   ArrayRef<ParmVarDecl*>::iterator I = parameters.begin(), E = parameters.end();
4730b57cec5SDimitry Andric   for (; I != E && Idx < NumArgs; ++I, ++Idx) {
4745ffd83dbSDimitry Andric     assert(*I && "Formal parameter has no decl?");
4750b57cec5SDimitry Andric 
4760b57cec5SDimitry Andric     // TODO: Support allocator calls.
4770b57cec5SDimitry Andric     if (Call.getKind() != CE_CXXAllocator)
478480093f4SDimitry Andric       if (Call.isArgumentConstructedDirectly(Call.getASTArgumentIndex(Idx)))
4790b57cec5SDimitry Andric         continue;
4800b57cec5SDimitry Andric 
4810b57cec5SDimitry Andric     // TODO: Allocators should receive the correct size and possibly alignment,
4820b57cec5SDimitry Andric     // determined in compile-time but not represented as arg-expressions,
4830b57cec5SDimitry Andric     // which makes getArgSVal() fail and return UnknownVal.
4840b57cec5SDimitry Andric     SVal ArgVal = Call.getArgSVal(Idx);
485fe6060f1SDimitry Andric     const Expr *ArgExpr = Call.getArgExpr(Idx);
486bdd1243dSDimitry Andric 
487bdd1243dSDimitry Andric     if (ArgVal.isUnknown())
488bdd1243dSDimitry Andric       continue;
489bdd1243dSDimitry Andric 
490bdd1243dSDimitry Andric     // Cast the argument value to match the type of the parameter in some
491bdd1243dSDimitry Andric     // edge-cases.
492bdd1243dSDimitry Andric     ArgVal = castArgToParamTypeIfNeeded(Call, Idx, ArgVal, SVB);
493bdd1243dSDimitry Andric 
4945ffd83dbSDimitry Andric     Loc ParamLoc = SVB.makeLoc(
4955ffd83dbSDimitry Andric         MRMgr.getParamVarRegion(Call.getOriginExpr(), Idx, CalleeCtx));
496fe6060f1SDimitry Andric     Bindings.push_back(
497fe6060f1SDimitry Andric         std::make_pair(ParamLoc, processArgument(ArgVal, ArgExpr, *I, SVB)));
4980b57cec5SDimitry Andric   }
4990b57cec5SDimitry Andric 
5000b57cec5SDimitry Andric   // FIXME: Variadic arguments are not handled at all right now.
5010b57cec5SDimitry Andric }
5020b57cec5SDimitry Andric 
5035ffd83dbSDimitry Andric const ConstructionContext *CallEvent::getConstructionContext() const {
5045ffd83dbSDimitry Andric   const StackFrameContext *StackFrame = getCalleeStackFrame(0);
5055ffd83dbSDimitry Andric   if (!StackFrame)
5065ffd83dbSDimitry Andric     return nullptr;
5075ffd83dbSDimitry Andric 
5085ffd83dbSDimitry Andric   const CFGElement Element = StackFrame->getCallSiteCFGElement();
5095ffd83dbSDimitry Andric   if (const auto Ctor = Element.getAs<CFGConstructor>()) {
5105ffd83dbSDimitry Andric     return Ctor->getConstructionContext();
5115ffd83dbSDimitry Andric   }
5125ffd83dbSDimitry Andric 
5135ffd83dbSDimitry Andric   if (const auto RecCall = Element.getAs<CFGCXXRecordTypedCall>()) {
5145ffd83dbSDimitry Andric     return RecCall->getConstructionContext();
5155ffd83dbSDimitry Andric   }
5165ffd83dbSDimitry Andric 
5175ffd83dbSDimitry Andric   return nullptr;
5185ffd83dbSDimitry Andric }
5195ffd83dbSDimitry Andric 
5205f757f3fSDimitry Andric const CallEventRef<> CallEvent::getCaller() const {
5215f757f3fSDimitry Andric   const auto *CallLocationContext = this->getLocationContext();
5225f757f3fSDimitry Andric   if (!CallLocationContext || CallLocationContext->inTopFrame())
5235f757f3fSDimitry Andric     return nullptr;
5245f757f3fSDimitry Andric 
5255f757f3fSDimitry Andric   const auto *CallStackFrameContext = CallLocationContext->getStackFrame();
5265f757f3fSDimitry Andric   if (!CallStackFrameContext)
5275f757f3fSDimitry Andric     return nullptr;
5285f757f3fSDimitry Andric 
5295f757f3fSDimitry Andric   CallEventManager &CEMgr = State->getStateManager().getCallEventManager();
5305f757f3fSDimitry Andric   return CEMgr.getCaller(CallStackFrameContext, State);
5315f757f3fSDimitry Andric }
5325f757f3fSDimitry Andric 
5335f757f3fSDimitry Andric bool CallEvent::isCalledFromSystemHeader() const {
5345f757f3fSDimitry Andric   if (const CallEventRef<> Caller = getCaller())
5355f757f3fSDimitry Andric     return Caller->isInSystemHeader();
5365f757f3fSDimitry Andric 
5375f757f3fSDimitry Andric   return false;
5385f757f3fSDimitry Andric }
5395f757f3fSDimitry Andric 
540bdd1243dSDimitry Andric std::optional<SVal> CallEvent::getReturnValueUnderConstruction() const {
5415ffd83dbSDimitry Andric   const auto *CC = getConstructionContext();
5425ffd83dbSDimitry Andric   if (!CC)
543bdd1243dSDimitry Andric     return std::nullopt;
5445ffd83dbSDimitry Andric 
5455ffd83dbSDimitry Andric   EvalCallOptions CallOpts;
5465ffd83dbSDimitry Andric   ExprEngine &Engine = getState()->getStateManager().getOwningEngine();
547bdd1243dSDimitry Andric   SVal RetVal = Engine.computeObjectUnderConstruction(
548bdd1243dSDimitry Andric       getOriginExpr(), getState(), &Engine.getBuilderContext(),
5495ffd83dbSDimitry Andric       getLocationContext(), CC, CallOpts);
5505ffd83dbSDimitry Andric   return RetVal;
5515ffd83dbSDimitry Andric }
5525ffd83dbSDimitry Andric 
5530b57cec5SDimitry Andric ArrayRef<ParmVarDecl*> AnyFunctionCall::parameters() const {
5540b57cec5SDimitry Andric   const FunctionDecl *D = getDecl();
5550b57cec5SDimitry Andric   if (!D)
556bdd1243dSDimitry Andric     return std::nullopt;
5570b57cec5SDimitry Andric   return D->parameters();
5580b57cec5SDimitry Andric }
5590b57cec5SDimitry Andric 
5600b57cec5SDimitry Andric RuntimeDefinition AnyFunctionCall::getRuntimeDefinition() const {
5610b57cec5SDimitry Andric   const FunctionDecl *FD = getDecl();
5620b57cec5SDimitry Andric   if (!FD)
5630b57cec5SDimitry Andric     return {};
5640b57cec5SDimitry Andric 
5650b57cec5SDimitry Andric   // Note that the AnalysisDeclContext will have the FunctionDecl with
5660b57cec5SDimitry Andric   // the definition (if one exists).
5670b57cec5SDimitry Andric   AnalysisDeclContext *AD =
5680b57cec5SDimitry Andric     getLocationContext()->getAnalysisDeclContext()->
5690b57cec5SDimitry Andric     getManager()->getContext(FD);
5700b57cec5SDimitry Andric   bool IsAutosynthesized;
5710b57cec5SDimitry Andric   Stmt* Body = AD->getBody(IsAutosynthesized);
5720b57cec5SDimitry Andric   LLVM_DEBUG({
5730b57cec5SDimitry Andric     if (IsAutosynthesized)
5740b57cec5SDimitry Andric       llvm::dbgs() << "Using autosynthesized body for " << FD->getName()
5750b57cec5SDimitry Andric                    << "\n";
5760b57cec5SDimitry Andric   });
5770b57cec5SDimitry Andric 
5785ffd83dbSDimitry Andric   ExprEngine &Engine = getState()->getStateManager().getOwningEngine();
57981ad6265SDimitry Andric   cross_tu::CrossTranslationUnitContext &CTUCtx =
58081ad6265SDimitry Andric       *Engine.getCrossTranslationUnitContext();
58181ad6265SDimitry Andric 
5820b57cec5SDimitry Andric   AnalyzerOptions &Opts = Engine.getAnalysisManager().options;
5830b57cec5SDimitry Andric 
58481ad6265SDimitry Andric   if (Body) {
58581ad6265SDimitry Andric     const Decl* Decl = AD->getDecl();
58681ad6265SDimitry Andric     if (Opts.IsNaiveCTUEnabled && CTUCtx.isImportedAsNew(Decl)) {
58781ad6265SDimitry Andric       // A newly created definition, but we had error(s) during the import.
58881ad6265SDimitry Andric       if (CTUCtx.hasError(Decl))
58981ad6265SDimitry Andric         return {};
59081ad6265SDimitry Andric       return RuntimeDefinition(Decl, /*Foreign=*/true);
59181ad6265SDimitry Andric     }
59281ad6265SDimitry Andric     return RuntimeDefinition(Decl, /*Foreign=*/false);
59381ad6265SDimitry Andric   }
59481ad6265SDimitry Andric 
5950b57cec5SDimitry Andric   // Try to get CTU definition only if CTUDir is provided.
5960b57cec5SDimitry Andric   if (!Opts.IsNaiveCTUEnabled)
5970b57cec5SDimitry Andric     return {};
5980b57cec5SDimitry Andric 
5990b57cec5SDimitry Andric   llvm::Expected<const FunctionDecl *> CTUDeclOrError =
6000b57cec5SDimitry Andric       CTUCtx.getCrossTUDefinition(FD, Opts.CTUDir, Opts.CTUIndexName,
6010b57cec5SDimitry Andric                                   Opts.DisplayCTUProgress);
6020b57cec5SDimitry Andric 
6030b57cec5SDimitry Andric   if (!CTUDeclOrError) {
6040b57cec5SDimitry Andric     handleAllErrors(CTUDeclOrError.takeError(),
6050b57cec5SDimitry Andric                     [&](const cross_tu::IndexError &IE) {
6060b57cec5SDimitry Andric                       CTUCtx.emitCrossTUDiagnostics(IE);
6070b57cec5SDimitry Andric                     });
6080b57cec5SDimitry Andric     return {};
6090b57cec5SDimitry Andric   }
6100b57cec5SDimitry Andric 
61181ad6265SDimitry Andric   return RuntimeDefinition(*CTUDeclOrError, /*Foreign=*/true);
6120b57cec5SDimitry Andric }
6130b57cec5SDimitry Andric 
6140b57cec5SDimitry Andric void AnyFunctionCall::getInitialStackFrameContents(
6150b57cec5SDimitry Andric                                         const StackFrameContext *CalleeCtx,
6160b57cec5SDimitry Andric                                         BindingsTy &Bindings) const {
6170b57cec5SDimitry Andric   const auto *D = cast<FunctionDecl>(CalleeCtx->getDecl());
6180b57cec5SDimitry Andric   SValBuilder &SVB = getState()->getStateManager().getSValBuilder();
6190b57cec5SDimitry Andric   addParameterValuesToBindings(CalleeCtx, Bindings, SVB, *this,
6200b57cec5SDimitry Andric                                D->parameters());
6210b57cec5SDimitry Andric }
6220b57cec5SDimitry Andric 
6230b57cec5SDimitry Andric bool AnyFunctionCall::argumentsMayEscape() const {
6240b57cec5SDimitry Andric   if (CallEvent::argumentsMayEscape() || hasVoidPointerToNonConstArg())
6250b57cec5SDimitry Andric     return true;
6260b57cec5SDimitry Andric 
6270b57cec5SDimitry Andric   const FunctionDecl *D = getDecl();
6280b57cec5SDimitry Andric   if (!D)
6290b57cec5SDimitry Andric     return true;
6300b57cec5SDimitry Andric 
6310b57cec5SDimitry Andric   const IdentifierInfo *II = D->getIdentifier();
6320b57cec5SDimitry Andric   if (!II)
6330b57cec5SDimitry Andric     return false;
6340b57cec5SDimitry Andric 
6350b57cec5SDimitry Andric   // This set of "escaping" APIs is
6360b57cec5SDimitry Andric 
6370b57cec5SDimitry Andric   // - 'int pthread_setspecific(ptheread_key k, const void *)' stores a
6380b57cec5SDimitry Andric   //   value into thread local storage. The value can later be retrieved with
6390b57cec5SDimitry Andric   //   'void *ptheread_getspecific(pthread_key)'. So even thought the
6400b57cec5SDimitry Andric   //   parameter is 'const void *', the region escapes through the call.
6410b57cec5SDimitry Andric   if (II->isStr("pthread_setspecific"))
6420b57cec5SDimitry Andric     return true;
6430b57cec5SDimitry Andric 
6440b57cec5SDimitry Andric   // - xpc_connection_set_context stores a value which can be retrieved later
6450b57cec5SDimitry Andric   //   with xpc_connection_get_context.
6460b57cec5SDimitry Andric   if (II->isStr("xpc_connection_set_context"))
6470b57cec5SDimitry Andric     return true;
6480b57cec5SDimitry Andric 
6490b57cec5SDimitry Andric   // - funopen - sets a buffer for future IO calls.
6500b57cec5SDimitry Andric   if (II->isStr("funopen"))
6510b57cec5SDimitry Andric     return true;
6520b57cec5SDimitry Andric 
6530b57cec5SDimitry Andric   // - __cxa_demangle - can reallocate memory and can return the pointer to
6540b57cec5SDimitry Andric   // the input buffer.
6550b57cec5SDimitry Andric   if (II->isStr("__cxa_demangle"))
6560b57cec5SDimitry Andric     return true;
6570b57cec5SDimitry Andric 
6580b57cec5SDimitry Andric   StringRef FName = II->getName();
6590b57cec5SDimitry Andric 
6600b57cec5SDimitry Andric   // - CoreFoundation functions that end with "NoCopy" can free a passed-in
6610b57cec5SDimitry Andric   //   buffer even if it is const.
6625f757f3fSDimitry Andric   if (FName.ends_with("NoCopy"))
6630b57cec5SDimitry Andric     return true;
6640b57cec5SDimitry Andric 
6650b57cec5SDimitry Andric   // - NSXXInsertXX, for example NSMapInsertIfAbsent, since they can
6660b57cec5SDimitry Andric   //   be deallocated by NSMapRemove.
6675f757f3fSDimitry Andric   if (FName.starts_with("NS") && FName.contains("Insert"))
6680b57cec5SDimitry Andric     return true;
6690b57cec5SDimitry Andric 
6700b57cec5SDimitry Andric   // - Many CF containers allow objects to escape through custom
6710b57cec5SDimitry Andric   //   allocators/deallocators upon container construction. (PR12101)
6725f757f3fSDimitry Andric   if (FName.starts_with("CF") || FName.starts_with("CG")) {
6730b57cec5SDimitry Andric     return StrInStrNoCase(FName, "InsertValue")  != StringRef::npos ||
6740b57cec5SDimitry Andric            StrInStrNoCase(FName, "AddValue")     != StringRef::npos ||
6750b57cec5SDimitry Andric            StrInStrNoCase(FName, "SetValue")     != StringRef::npos ||
6760b57cec5SDimitry Andric            StrInStrNoCase(FName, "WithData")     != StringRef::npos ||
6770b57cec5SDimitry Andric            StrInStrNoCase(FName, "AppendValue")  != StringRef::npos ||
6780b57cec5SDimitry Andric            StrInStrNoCase(FName, "SetAttribute") != StringRef::npos;
6790b57cec5SDimitry Andric   }
6800b57cec5SDimitry Andric 
6810b57cec5SDimitry Andric   return false;
6820b57cec5SDimitry Andric }
6830b57cec5SDimitry Andric 
6840b57cec5SDimitry Andric const FunctionDecl *SimpleFunctionCall::getDecl() const {
6850b57cec5SDimitry Andric   const FunctionDecl *D = getOriginExpr()->getDirectCallee();
6860b57cec5SDimitry Andric   if (D)
6870b57cec5SDimitry Andric     return D;
6880b57cec5SDimitry Andric 
6890b57cec5SDimitry Andric   return getSVal(getOriginExpr()->getCallee()).getAsFunctionDecl();
6900b57cec5SDimitry Andric }
6910b57cec5SDimitry Andric 
6920b57cec5SDimitry Andric const FunctionDecl *CXXInstanceCall::getDecl() const {
6930b57cec5SDimitry Andric   const auto *CE = cast_or_null<CallExpr>(getOriginExpr());
6940b57cec5SDimitry Andric   if (!CE)
6950b57cec5SDimitry Andric     return AnyFunctionCall::getDecl();
6960b57cec5SDimitry Andric 
6970b57cec5SDimitry Andric   const FunctionDecl *D = CE->getDirectCallee();
6980b57cec5SDimitry Andric   if (D)
6990b57cec5SDimitry Andric     return D;
7000b57cec5SDimitry Andric 
7010b57cec5SDimitry Andric   return getSVal(CE->getCallee()).getAsFunctionDecl();
7020b57cec5SDimitry Andric }
7030b57cec5SDimitry Andric 
7040b57cec5SDimitry Andric void CXXInstanceCall::getExtraInvalidatedValues(
7050b57cec5SDimitry Andric     ValueList &Values, RegionAndSymbolInvalidationTraits *ETraits) const {
7060b57cec5SDimitry Andric   SVal ThisVal = getCXXThisVal();
7070b57cec5SDimitry Andric   Values.push_back(ThisVal);
7080b57cec5SDimitry Andric 
7090b57cec5SDimitry Andric   // Don't invalidate if the method is const and there are no mutable fields.
7100b57cec5SDimitry Andric   if (const auto *D = cast_or_null<CXXMethodDecl>(getDecl())) {
7110b57cec5SDimitry Andric     if (!D->isConst())
7120b57cec5SDimitry Andric       return;
7130b57cec5SDimitry Andric     // Get the record decl for the class of 'This'. D->getParent() may return a
7140b57cec5SDimitry Andric     // base class decl, rather than the class of the instance which needs to be
7150b57cec5SDimitry Andric     // checked for mutable fields.
7160b57cec5SDimitry Andric     // TODO: We might as well look at the dynamic type of the object.
717e8d8bef9SDimitry Andric     const Expr *Ex = getCXXThisExpr()->IgnoreParenBaseCasts();
7180b57cec5SDimitry Andric     QualType T = Ex->getType();
7190b57cec5SDimitry Andric     if (T->isPointerType()) // Arrow or implicit-this syntax?
7200b57cec5SDimitry Andric       T = T->getPointeeType();
7210b57cec5SDimitry Andric     const CXXRecordDecl *ParentRecord = T->getAsCXXRecordDecl();
7220b57cec5SDimitry Andric     assert(ParentRecord);
7230b57cec5SDimitry Andric     if (ParentRecord->hasMutableFields())
7240b57cec5SDimitry Andric       return;
7250b57cec5SDimitry Andric     // Preserve CXXThis.
7260b57cec5SDimitry Andric     const MemRegion *ThisRegion = ThisVal.getAsRegion();
7270b57cec5SDimitry Andric     if (!ThisRegion)
7280b57cec5SDimitry Andric       return;
7290b57cec5SDimitry Andric 
7300b57cec5SDimitry Andric     ETraits->setTrait(ThisRegion->getBaseRegion(),
7310b57cec5SDimitry Andric                       RegionAndSymbolInvalidationTraits::TK_PreserveContents);
7320b57cec5SDimitry Andric   }
7330b57cec5SDimitry Andric }
7340b57cec5SDimitry Andric 
7350b57cec5SDimitry Andric SVal CXXInstanceCall::getCXXThisVal() const {
7360b57cec5SDimitry Andric   const Expr *Base = getCXXThisExpr();
7370b57cec5SDimitry Andric   // FIXME: This doesn't handle an overloaded ->* operator.
7385f757f3fSDimitry Andric   SVal ThisVal = Base ? getSVal(Base) : UnknownVal();
7390b57cec5SDimitry Andric 
7405f757f3fSDimitry Andric   if (isa<NonLoc>(ThisVal)) {
7415f757f3fSDimitry Andric     SValBuilder &SVB = getState()->getStateManager().getSValBuilder();
7425f757f3fSDimitry Andric     QualType OriginalTy = ThisVal.getType(SVB.getContext());
7435f757f3fSDimitry Andric     return SVB.evalCast(ThisVal, Base->getType(), OriginalTy);
7445f757f3fSDimitry Andric   }
7455f757f3fSDimitry Andric 
74681ad6265SDimitry Andric   assert(ThisVal.isUnknownOrUndef() || isa<Loc>(ThisVal));
7470b57cec5SDimitry Andric   return ThisVal;
7480b57cec5SDimitry Andric }
7490b57cec5SDimitry Andric 
7500b57cec5SDimitry Andric RuntimeDefinition CXXInstanceCall::getRuntimeDefinition() const {
7510b57cec5SDimitry Andric   // Do we have a decl at all?
7520b57cec5SDimitry Andric   const Decl *D = getDecl();
7530b57cec5SDimitry Andric   if (!D)
7540b57cec5SDimitry Andric     return {};
7550b57cec5SDimitry Andric 
7560b57cec5SDimitry Andric   // If the method is non-virtual, we know we can inline it.
7570b57cec5SDimitry Andric   const auto *MD = cast<CXXMethodDecl>(D);
7580b57cec5SDimitry Andric   if (!MD->isVirtual())
7590b57cec5SDimitry Andric     return AnyFunctionCall::getRuntimeDefinition();
7600b57cec5SDimitry Andric 
7610b57cec5SDimitry Andric   // Do we know the implicit 'this' object being called?
7620b57cec5SDimitry Andric   const MemRegion *R = getCXXThisVal().getAsRegion();
7630b57cec5SDimitry Andric   if (!R)
7640b57cec5SDimitry Andric     return {};
7650b57cec5SDimitry Andric 
7660b57cec5SDimitry Andric   // Do we know anything about the type of 'this'?
7670b57cec5SDimitry Andric   DynamicTypeInfo DynType = getDynamicTypeInfo(getState(), R);
7680b57cec5SDimitry Andric   if (!DynType.isValid())
7690b57cec5SDimitry Andric     return {};
7700b57cec5SDimitry Andric 
7710b57cec5SDimitry Andric   // Is the type a C++ class? (This is mostly a defensive check.)
7720b57cec5SDimitry Andric   QualType RegionType = DynType.getType()->getPointeeType();
7730b57cec5SDimitry Andric   assert(!RegionType.isNull() && "DynamicTypeInfo should always be a pointer.");
7740b57cec5SDimitry Andric 
7750b57cec5SDimitry Andric   const CXXRecordDecl *RD = RegionType->getAsCXXRecordDecl();
7760b57cec5SDimitry Andric   if (!RD || !RD->hasDefinition())
7770b57cec5SDimitry Andric     return {};
7780b57cec5SDimitry Andric 
7790b57cec5SDimitry Andric   // Find the decl for this method in that class.
7800b57cec5SDimitry Andric   const CXXMethodDecl *Result = MD->getCorrespondingMethodInClass(RD, true);
7810b57cec5SDimitry Andric   if (!Result) {
7820b57cec5SDimitry Andric     // We might not even get the original statically-resolved method due to
7830b57cec5SDimitry Andric     // some particularly nasty casting (e.g. casts to sister classes).
7840b57cec5SDimitry Andric     // However, we should at least be able to search up and down our own class
7850b57cec5SDimitry Andric     // hierarchy, and some real bugs have been caught by checking this.
7860b57cec5SDimitry Andric     assert(!RD->isDerivedFrom(MD->getParent()) && "Couldn't find known method");
7870b57cec5SDimitry Andric 
7880b57cec5SDimitry Andric     // FIXME: This is checking that our DynamicTypeInfo is at least as good as
7890b57cec5SDimitry Andric     // the static type. However, because we currently don't update
7900b57cec5SDimitry Andric     // DynamicTypeInfo when an object is cast, we can't actually be sure the
7910b57cec5SDimitry Andric     // DynamicTypeInfo is up to date. This assert should be re-enabled once
7925f757f3fSDimitry Andric     // this is fixed.
7935f757f3fSDimitry Andric     //
7940b57cec5SDimitry Andric     // assert(!MD->getParent()->isDerivedFrom(RD) && "Bad DynamicTypeInfo");
7950b57cec5SDimitry Andric 
7960b57cec5SDimitry Andric     return {};
7970b57cec5SDimitry Andric   }
7980b57cec5SDimitry Andric 
7990b57cec5SDimitry Andric   // Does the decl that we found have an implementation?
8000b57cec5SDimitry Andric   const FunctionDecl *Definition;
8010b57cec5SDimitry Andric   if (!Result->hasBody(Definition)) {
8020b57cec5SDimitry Andric     if (!DynType.canBeASubClass())
8030b57cec5SDimitry Andric       return AnyFunctionCall::getRuntimeDefinition();
8040b57cec5SDimitry Andric     return {};
8050b57cec5SDimitry Andric   }
8060b57cec5SDimitry Andric 
8070b57cec5SDimitry Andric   // We found a definition. If we're not sure that this devirtualization is
8080b57cec5SDimitry Andric   // actually what will happen at runtime, make sure to provide the region so
8090b57cec5SDimitry Andric   // that ExprEngine can decide what to do with it.
8100b57cec5SDimitry Andric   if (DynType.canBeASubClass())
8110b57cec5SDimitry Andric     return RuntimeDefinition(Definition, R->StripCasts());
8120b57cec5SDimitry Andric   return RuntimeDefinition(Definition, /*DispatchRegion=*/nullptr);
8130b57cec5SDimitry Andric }
8140b57cec5SDimitry Andric 
8150b57cec5SDimitry Andric void CXXInstanceCall::getInitialStackFrameContents(
8160b57cec5SDimitry Andric                                             const StackFrameContext *CalleeCtx,
8170b57cec5SDimitry Andric                                             BindingsTy &Bindings) const {
8180b57cec5SDimitry Andric   AnyFunctionCall::getInitialStackFrameContents(CalleeCtx, Bindings);
8190b57cec5SDimitry Andric 
8200b57cec5SDimitry Andric   // Handle the binding of 'this' in the new stack frame.
8210b57cec5SDimitry Andric   SVal ThisVal = getCXXThisVal();
8220b57cec5SDimitry Andric   if (!ThisVal.isUnknown()) {
8230b57cec5SDimitry Andric     ProgramStateManager &StateMgr = getState()->getStateManager();
8240b57cec5SDimitry Andric     SValBuilder &SVB = StateMgr.getSValBuilder();
8250b57cec5SDimitry Andric 
8260b57cec5SDimitry Andric     const auto *MD = cast<CXXMethodDecl>(CalleeCtx->getDecl());
8270b57cec5SDimitry Andric     Loc ThisLoc = SVB.getCXXThis(MD, CalleeCtx);
8280b57cec5SDimitry Andric 
8290b57cec5SDimitry Andric     // If we devirtualized to a different member function, we need to make sure
8300b57cec5SDimitry Andric     // we have the proper layering of CXXBaseObjectRegions.
8310b57cec5SDimitry Andric     if (MD->getCanonicalDecl() != getDecl()->getCanonicalDecl()) {
8320b57cec5SDimitry Andric       ASTContext &Ctx = SVB.getContext();
8330b57cec5SDimitry Andric       const CXXRecordDecl *Class = MD->getParent();
8340b57cec5SDimitry Andric       QualType Ty = Ctx.getPointerType(Ctx.getRecordType(Class));
8350b57cec5SDimitry Andric 
8360b57cec5SDimitry Andric       // FIXME: CallEvent maybe shouldn't be directly accessing StoreManager.
837bdd1243dSDimitry Andric       std::optional<SVal> V =
8380eae32dcSDimitry Andric           StateMgr.getStoreManager().evalBaseToDerived(ThisVal, Ty);
83981ad6265SDimitry Andric       if (!V) {
8400b57cec5SDimitry Andric         // We might have suffered some sort of placement new earlier, so
8410b57cec5SDimitry Andric         // we're constructing in a completely unexpected storage.
8420b57cec5SDimitry Andric         // Fall back to a generic pointer cast for this-value.
8430b57cec5SDimitry Andric         const CXXMethodDecl *StaticMD = cast<CXXMethodDecl>(getDecl());
8440b57cec5SDimitry Andric         const CXXRecordDecl *StaticClass = StaticMD->getParent();
8450b57cec5SDimitry Andric         QualType StaticTy = Ctx.getPointerType(Ctx.getRecordType(StaticClass));
8460b57cec5SDimitry Andric         ThisVal = SVB.evalCast(ThisVal, Ty, StaticTy);
8470eae32dcSDimitry Andric       } else
8480eae32dcSDimitry Andric         ThisVal = *V;
8490b57cec5SDimitry Andric     }
8500b57cec5SDimitry Andric 
8510b57cec5SDimitry Andric     if (!ThisVal.isUnknown())
8520b57cec5SDimitry Andric       Bindings.push_back(std::make_pair(ThisLoc, ThisVal));
8530b57cec5SDimitry Andric   }
8540b57cec5SDimitry Andric }
8550b57cec5SDimitry Andric 
8560b57cec5SDimitry Andric const Expr *CXXMemberCall::getCXXThisExpr() const {
8570b57cec5SDimitry Andric   return getOriginExpr()->getImplicitObjectArgument();
8580b57cec5SDimitry Andric }
8590b57cec5SDimitry Andric 
8600b57cec5SDimitry Andric RuntimeDefinition CXXMemberCall::getRuntimeDefinition() const {
8610b57cec5SDimitry Andric   // C++11 [expr.call]p1: ...If the selected function is non-virtual, or if the
8620b57cec5SDimitry Andric   // id-expression in the class member access expression is a qualified-id,
8630b57cec5SDimitry Andric   // that function is called. Otherwise, its final overrider in the dynamic type
8640b57cec5SDimitry Andric   // of the object expression is called.
8650b57cec5SDimitry Andric   if (const auto *ME = dyn_cast<MemberExpr>(getOriginExpr()->getCallee()))
8660b57cec5SDimitry Andric     if (ME->hasQualifier())
8670b57cec5SDimitry Andric       return AnyFunctionCall::getRuntimeDefinition();
8680b57cec5SDimitry Andric 
8690b57cec5SDimitry Andric   return CXXInstanceCall::getRuntimeDefinition();
8700b57cec5SDimitry Andric }
8710b57cec5SDimitry Andric 
8720b57cec5SDimitry Andric const Expr *CXXMemberOperatorCall::getCXXThisExpr() const {
8730b57cec5SDimitry Andric   return getOriginExpr()->getArg(0);
8740b57cec5SDimitry Andric }
8750b57cec5SDimitry Andric 
8760b57cec5SDimitry Andric const BlockDataRegion *BlockCall::getBlockRegion() const {
8770b57cec5SDimitry Andric   const Expr *Callee = getOriginExpr()->getCallee();
8780b57cec5SDimitry Andric   const MemRegion *DataReg = getSVal(Callee).getAsRegion();
8790b57cec5SDimitry Andric 
8800b57cec5SDimitry Andric   return dyn_cast_or_null<BlockDataRegion>(DataReg);
8810b57cec5SDimitry Andric }
8820b57cec5SDimitry Andric 
8830b57cec5SDimitry Andric ArrayRef<ParmVarDecl*> BlockCall::parameters() const {
8840b57cec5SDimitry Andric   const BlockDecl *D = getDecl();
8850b57cec5SDimitry Andric   if (!D)
886bdd1243dSDimitry Andric     return std::nullopt;
8870b57cec5SDimitry Andric   return D->parameters();
8880b57cec5SDimitry Andric }
8890b57cec5SDimitry Andric 
8900b57cec5SDimitry Andric void BlockCall::getExtraInvalidatedValues(ValueList &Values,
8910b57cec5SDimitry Andric                   RegionAndSymbolInvalidationTraits *ETraits) const {
8920b57cec5SDimitry Andric   // FIXME: This also needs to invalidate captured globals.
8930b57cec5SDimitry Andric   if (const MemRegion *R = getBlockRegion())
8940b57cec5SDimitry Andric     Values.push_back(loc::MemRegionVal(R));
8950b57cec5SDimitry Andric }
8960b57cec5SDimitry Andric 
8970b57cec5SDimitry Andric void BlockCall::getInitialStackFrameContents(const StackFrameContext *CalleeCtx,
8980b57cec5SDimitry Andric                                              BindingsTy &Bindings) const {
8990b57cec5SDimitry Andric   SValBuilder &SVB = getState()->getStateManager().getSValBuilder();
9000b57cec5SDimitry Andric   ArrayRef<ParmVarDecl*> Params;
9010b57cec5SDimitry Andric   if (isConversionFromLambda()) {
9020b57cec5SDimitry Andric     auto *LambdaOperatorDecl = cast<CXXMethodDecl>(CalleeCtx->getDecl());
9030b57cec5SDimitry Andric     Params = LambdaOperatorDecl->parameters();
9040b57cec5SDimitry Andric 
9050b57cec5SDimitry Andric     // For blocks converted from a C++ lambda, the callee declaration is the
9060b57cec5SDimitry Andric     // operator() method on the lambda so we bind "this" to
9070b57cec5SDimitry Andric     // the lambda captured by the block.
9080b57cec5SDimitry Andric     const VarRegion *CapturedLambdaRegion = getRegionStoringCapturedLambda();
9090b57cec5SDimitry Andric     SVal ThisVal = loc::MemRegionVal(CapturedLambdaRegion);
9100b57cec5SDimitry Andric     Loc ThisLoc = SVB.getCXXThis(LambdaOperatorDecl, CalleeCtx);
9110b57cec5SDimitry Andric     Bindings.push_back(std::make_pair(ThisLoc, ThisVal));
9120b57cec5SDimitry Andric   } else {
9130b57cec5SDimitry Andric     Params = cast<BlockDecl>(CalleeCtx->getDecl())->parameters();
9140b57cec5SDimitry Andric   }
9150b57cec5SDimitry Andric 
9160b57cec5SDimitry Andric   addParameterValuesToBindings(CalleeCtx, Bindings, SVB, *this,
9170b57cec5SDimitry Andric                                Params);
9180b57cec5SDimitry Andric }
9190b57cec5SDimitry Andric 
9205ffd83dbSDimitry Andric SVal AnyCXXConstructorCall::getCXXThisVal() const {
9210b57cec5SDimitry Andric   if (Data)
9220b57cec5SDimitry Andric     return loc::MemRegionVal(static_cast<const MemRegion *>(Data));
9230b57cec5SDimitry Andric   return UnknownVal();
9240b57cec5SDimitry Andric }
9250b57cec5SDimitry Andric 
9265ffd83dbSDimitry Andric void AnyCXXConstructorCall::getExtraInvalidatedValues(ValueList &Values,
9270b57cec5SDimitry Andric                            RegionAndSymbolInvalidationTraits *ETraits) const {
9285ffd83dbSDimitry Andric   SVal V = getCXXThisVal();
9295ffd83dbSDimitry Andric   if (SymbolRef Sym = V.getAsSymbol(true))
9300b57cec5SDimitry Andric     ETraits->setTrait(Sym,
9310b57cec5SDimitry Andric                       RegionAndSymbolInvalidationTraits::TK_SuppressEscape);
9325ffd83dbSDimitry Andric   Values.push_back(V);
9330b57cec5SDimitry Andric }
9340b57cec5SDimitry Andric 
9355ffd83dbSDimitry Andric void AnyCXXConstructorCall::getInitialStackFrameContents(
9360b57cec5SDimitry Andric                                              const StackFrameContext *CalleeCtx,
9370b57cec5SDimitry Andric                                              BindingsTy &Bindings) const {
9380b57cec5SDimitry Andric   AnyFunctionCall::getInitialStackFrameContents(CalleeCtx, Bindings);
9390b57cec5SDimitry Andric 
9400b57cec5SDimitry Andric   SVal ThisVal = getCXXThisVal();
9410b57cec5SDimitry Andric   if (!ThisVal.isUnknown()) {
9420b57cec5SDimitry Andric     SValBuilder &SVB = getState()->getStateManager().getSValBuilder();
9430b57cec5SDimitry Andric     const auto *MD = cast<CXXMethodDecl>(CalleeCtx->getDecl());
9440b57cec5SDimitry Andric     Loc ThisLoc = SVB.getCXXThis(MD, CalleeCtx);
9450b57cec5SDimitry Andric     Bindings.push_back(std::make_pair(ThisLoc, ThisVal));
9460b57cec5SDimitry Andric   }
9470b57cec5SDimitry Andric }
9480b57cec5SDimitry Andric 
9495ffd83dbSDimitry Andric const StackFrameContext *
9505ffd83dbSDimitry Andric CXXInheritedConstructorCall::getInheritingStackFrame() const {
9515ffd83dbSDimitry Andric   const StackFrameContext *SFC = getLocationContext()->getStackFrame();
9525ffd83dbSDimitry Andric   while (isa<CXXInheritedCtorInitExpr>(SFC->getCallSite()))
9535ffd83dbSDimitry Andric     SFC = SFC->getParent()->getStackFrame();
9545ffd83dbSDimitry Andric   return SFC;
9555ffd83dbSDimitry Andric }
9565ffd83dbSDimitry Andric 
9570b57cec5SDimitry Andric SVal CXXDestructorCall::getCXXThisVal() const {
9580b57cec5SDimitry Andric   if (Data)
9590b57cec5SDimitry Andric     return loc::MemRegionVal(DtorDataTy::getFromOpaqueValue(Data).getPointer());
9600b57cec5SDimitry Andric   return UnknownVal();
9610b57cec5SDimitry Andric }
9620b57cec5SDimitry Andric 
9630b57cec5SDimitry Andric RuntimeDefinition CXXDestructorCall::getRuntimeDefinition() const {
9640b57cec5SDimitry Andric   // Base destructors are always called non-virtually.
9650b57cec5SDimitry Andric   // Skip CXXInstanceCall's devirtualization logic in this case.
9660b57cec5SDimitry Andric   if (isBaseDestructor())
9670b57cec5SDimitry Andric     return AnyFunctionCall::getRuntimeDefinition();
9680b57cec5SDimitry Andric 
9690b57cec5SDimitry Andric   return CXXInstanceCall::getRuntimeDefinition();
9700b57cec5SDimitry Andric }
9710b57cec5SDimitry Andric 
9720b57cec5SDimitry Andric ArrayRef<ParmVarDecl*> ObjCMethodCall::parameters() const {
9730b57cec5SDimitry Andric   const ObjCMethodDecl *D = getDecl();
9740b57cec5SDimitry Andric   if (!D)
975bdd1243dSDimitry Andric     return std::nullopt;
9760b57cec5SDimitry Andric   return D->parameters();
9770b57cec5SDimitry Andric }
9780b57cec5SDimitry Andric 
9790b57cec5SDimitry Andric void ObjCMethodCall::getExtraInvalidatedValues(
9800b57cec5SDimitry Andric     ValueList &Values, RegionAndSymbolInvalidationTraits *ETraits) const {
9810b57cec5SDimitry Andric 
9820b57cec5SDimitry Andric   // If the method call is a setter for property known to be backed by
9830b57cec5SDimitry Andric   // an instance variable, don't invalidate the entire receiver, just
9840b57cec5SDimitry Andric   // the storage for that instance variable.
9850b57cec5SDimitry Andric   if (const ObjCPropertyDecl *PropDecl = getAccessedProperty()) {
9860b57cec5SDimitry Andric     if (const ObjCIvarDecl *PropIvar = PropDecl->getPropertyIvarDecl()) {
9870b57cec5SDimitry Andric       SVal IvarLVal = getState()->getLValue(PropIvar, getReceiverSVal());
9880b57cec5SDimitry Andric       if (const MemRegion *IvarRegion = IvarLVal.getAsRegion()) {
9890b57cec5SDimitry Andric         ETraits->setTrait(
9900b57cec5SDimitry Andric           IvarRegion,
9910b57cec5SDimitry Andric           RegionAndSymbolInvalidationTraits::TK_DoNotInvalidateSuperRegion);
9920b57cec5SDimitry Andric         ETraits->setTrait(
9930b57cec5SDimitry Andric           IvarRegion,
9940b57cec5SDimitry Andric           RegionAndSymbolInvalidationTraits::TK_SuppressEscape);
9950b57cec5SDimitry Andric         Values.push_back(IvarLVal);
9960b57cec5SDimitry Andric       }
9970b57cec5SDimitry Andric       return;
9980b57cec5SDimitry Andric     }
9990b57cec5SDimitry Andric   }
10000b57cec5SDimitry Andric 
10010b57cec5SDimitry Andric   Values.push_back(getReceiverSVal());
10020b57cec5SDimitry Andric }
10030b57cec5SDimitry Andric 
10040b57cec5SDimitry Andric SVal ObjCMethodCall::getReceiverSVal() const {
10050b57cec5SDimitry Andric   // FIXME: Is this the best way to handle class receivers?
10060b57cec5SDimitry Andric   if (!isInstanceMessage())
10070b57cec5SDimitry Andric     return UnknownVal();
10080b57cec5SDimitry Andric 
10090b57cec5SDimitry Andric   if (const Expr *RecE = getOriginExpr()->getInstanceReceiver())
10100b57cec5SDimitry Andric     return getSVal(RecE);
10110b57cec5SDimitry Andric 
10120b57cec5SDimitry Andric   // An instance message with no expression means we are sending to super.
10130b57cec5SDimitry Andric   // In this case the object reference is the same as 'self'.
10140b57cec5SDimitry Andric   assert(getOriginExpr()->getReceiverKind() == ObjCMessageExpr::SuperInstance);
10155ffd83dbSDimitry Andric   SVal SelfVal = getState()->getSelfSVal(getLocationContext());
10160b57cec5SDimitry Andric   assert(SelfVal.isValid() && "Calling super but not in ObjC method");
10170b57cec5SDimitry Andric   return SelfVal;
10180b57cec5SDimitry Andric }
10190b57cec5SDimitry Andric 
10200b57cec5SDimitry Andric bool ObjCMethodCall::isReceiverSelfOrSuper() const {
10210b57cec5SDimitry Andric   if (getOriginExpr()->getReceiverKind() == ObjCMessageExpr::SuperInstance ||
10220b57cec5SDimitry Andric       getOriginExpr()->getReceiverKind() == ObjCMessageExpr::SuperClass)
10230b57cec5SDimitry Andric       return true;
10240b57cec5SDimitry Andric 
10250b57cec5SDimitry Andric   if (!isInstanceMessage())
10260b57cec5SDimitry Andric     return false;
10270b57cec5SDimitry Andric 
10280b57cec5SDimitry Andric   SVal RecVal = getSVal(getOriginExpr()->getInstanceReceiver());
10295ffd83dbSDimitry Andric   SVal SelfVal = getState()->getSelfSVal(getLocationContext());
10300b57cec5SDimitry Andric 
10315ffd83dbSDimitry Andric   return (RecVal == SelfVal);
10320b57cec5SDimitry Andric }
10330b57cec5SDimitry Andric 
10340b57cec5SDimitry Andric SourceRange ObjCMethodCall::getSourceRange() const {
10350b57cec5SDimitry Andric   switch (getMessageKind()) {
10360b57cec5SDimitry Andric   case OCM_Message:
10370b57cec5SDimitry Andric     return getOriginExpr()->getSourceRange();
10380b57cec5SDimitry Andric   case OCM_PropertyAccess:
10390b57cec5SDimitry Andric   case OCM_Subscript:
10400b57cec5SDimitry Andric     return getContainingPseudoObjectExpr()->getSourceRange();
10410b57cec5SDimitry Andric   }
10420b57cec5SDimitry Andric   llvm_unreachable("unknown message kind");
10430b57cec5SDimitry Andric }
10440b57cec5SDimitry Andric 
10450b57cec5SDimitry Andric using ObjCMessageDataTy = llvm::PointerIntPair<const PseudoObjectExpr *, 2>;
10460b57cec5SDimitry Andric 
10470b57cec5SDimitry Andric const PseudoObjectExpr *ObjCMethodCall::getContainingPseudoObjectExpr() const {
10480b57cec5SDimitry Andric   assert(Data && "Lazy lookup not yet performed.");
10490b57cec5SDimitry Andric   assert(getMessageKind() != OCM_Message && "Explicit message send.");
10500b57cec5SDimitry Andric   return ObjCMessageDataTy::getFromOpaqueValue(Data).getPointer();
10510b57cec5SDimitry Andric }
10520b57cec5SDimitry Andric 
10530b57cec5SDimitry Andric static const Expr *
10540b57cec5SDimitry Andric getSyntacticFromForPseudoObjectExpr(const PseudoObjectExpr *POE) {
1055349cc55cSDimitry Andric   const Expr *Syntactic = POE->getSyntacticForm()->IgnoreParens();
10560b57cec5SDimitry Andric 
10570b57cec5SDimitry Andric   // This handles the funny case of assigning to the result of a getter.
10580b57cec5SDimitry Andric   // This can happen if the getter returns a non-const reference.
10590b57cec5SDimitry Andric   if (const auto *BO = dyn_cast<BinaryOperator>(Syntactic))
1060349cc55cSDimitry Andric     Syntactic = BO->getLHS()->IgnoreParens();
10610b57cec5SDimitry Andric 
10620b57cec5SDimitry Andric   return Syntactic;
10630b57cec5SDimitry Andric }
10640b57cec5SDimitry Andric 
10650b57cec5SDimitry Andric ObjCMessageKind ObjCMethodCall::getMessageKind() const {
10660b57cec5SDimitry Andric   if (!Data) {
10670b57cec5SDimitry Andric     // Find the parent, ignoring implicit casts.
1068a7dea167SDimitry Andric     const ParentMap &PM = getLocationContext()->getParentMap();
10690b57cec5SDimitry Andric     const Stmt *S = PM.getParentIgnoreParenCasts(getOriginExpr());
10700b57cec5SDimitry Andric 
10710b57cec5SDimitry Andric     // Check if parent is a PseudoObjectExpr.
10720b57cec5SDimitry Andric     if (const auto *POE = dyn_cast_or_null<PseudoObjectExpr>(S)) {
10730b57cec5SDimitry Andric       const Expr *Syntactic = getSyntacticFromForPseudoObjectExpr(POE);
10740b57cec5SDimitry Andric 
10750b57cec5SDimitry Andric       ObjCMessageKind K;
10760b57cec5SDimitry Andric       switch (Syntactic->getStmtClass()) {
10770b57cec5SDimitry Andric       case Stmt::ObjCPropertyRefExprClass:
10780b57cec5SDimitry Andric         K = OCM_PropertyAccess;
10790b57cec5SDimitry Andric         break;
10800b57cec5SDimitry Andric       case Stmt::ObjCSubscriptRefExprClass:
10810b57cec5SDimitry Andric         K = OCM_Subscript;
10820b57cec5SDimitry Andric         break;
10830b57cec5SDimitry Andric       default:
10840b57cec5SDimitry Andric         // FIXME: Can this ever happen?
10850b57cec5SDimitry Andric         K = OCM_Message;
10860b57cec5SDimitry Andric         break;
10870b57cec5SDimitry Andric       }
10880b57cec5SDimitry Andric 
10890b57cec5SDimitry Andric       if (K != OCM_Message) {
10900b57cec5SDimitry Andric         const_cast<ObjCMethodCall *>(this)->Data
10910b57cec5SDimitry Andric           = ObjCMessageDataTy(POE, K).getOpaqueValue();
10920b57cec5SDimitry Andric         assert(getMessageKind() == K);
10930b57cec5SDimitry Andric         return K;
10940b57cec5SDimitry Andric       }
10950b57cec5SDimitry Andric     }
10960b57cec5SDimitry Andric 
10970b57cec5SDimitry Andric     const_cast<ObjCMethodCall *>(this)->Data
10980b57cec5SDimitry Andric       = ObjCMessageDataTy(nullptr, 1).getOpaqueValue();
10990b57cec5SDimitry Andric     assert(getMessageKind() == OCM_Message);
11000b57cec5SDimitry Andric     return OCM_Message;
11010b57cec5SDimitry Andric   }
11020b57cec5SDimitry Andric 
11030b57cec5SDimitry Andric   ObjCMessageDataTy Info = ObjCMessageDataTy::getFromOpaqueValue(Data);
11040b57cec5SDimitry Andric   if (!Info.getPointer())
11050b57cec5SDimitry Andric     return OCM_Message;
11060b57cec5SDimitry Andric   return static_cast<ObjCMessageKind>(Info.getInt());
11070b57cec5SDimitry Andric }
11080b57cec5SDimitry Andric 
11090b57cec5SDimitry Andric const ObjCPropertyDecl *ObjCMethodCall::getAccessedProperty() const {
11100b57cec5SDimitry Andric   // Look for properties accessed with property syntax (foo.bar = ...)
11110b57cec5SDimitry Andric   if (getMessageKind() == OCM_PropertyAccess) {
11120b57cec5SDimitry Andric     const PseudoObjectExpr *POE = getContainingPseudoObjectExpr();
11130b57cec5SDimitry Andric     assert(POE && "Property access without PseudoObjectExpr?");
11140b57cec5SDimitry Andric 
11150b57cec5SDimitry Andric     const Expr *Syntactic = getSyntacticFromForPseudoObjectExpr(POE);
11160b57cec5SDimitry Andric     auto *RefExpr = cast<ObjCPropertyRefExpr>(Syntactic);
11170b57cec5SDimitry Andric 
11180b57cec5SDimitry Andric     if (RefExpr->isExplicitProperty())
11190b57cec5SDimitry Andric       return RefExpr->getExplicitProperty();
11200b57cec5SDimitry Andric   }
11210b57cec5SDimitry Andric 
11220b57cec5SDimitry Andric   // Look for properties accessed with method syntax ([foo setBar:...]).
11230b57cec5SDimitry Andric   const ObjCMethodDecl *MD = getDecl();
11240b57cec5SDimitry Andric   if (!MD || !MD->isPropertyAccessor())
11250b57cec5SDimitry Andric     return nullptr;
11260b57cec5SDimitry Andric 
11270b57cec5SDimitry Andric   // Note: This is potentially quite slow.
11280b57cec5SDimitry Andric   return MD->findPropertyDecl();
11290b57cec5SDimitry Andric }
11300b57cec5SDimitry Andric 
11310b57cec5SDimitry Andric bool ObjCMethodCall::canBeOverridenInSubclass(ObjCInterfaceDecl *IDecl,
11320b57cec5SDimitry Andric                                              Selector Sel) const {
11330b57cec5SDimitry Andric   assert(IDecl);
11340b57cec5SDimitry Andric   AnalysisManager &AMgr =
11350b57cec5SDimitry Andric       getState()->getStateManager().getOwningEngine().getAnalysisManager();
11360b57cec5SDimitry Andric   // If the class interface is declared inside the main file, assume it is not
11370b57cec5SDimitry Andric   // subcassed.
11380b57cec5SDimitry Andric   // TODO: It could actually be subclassed if the subclass is private as well.
11390b57cec5SDimitry Andric   // This is probably very rare.
11400b57cec5SDimitry Andric   SourceLocation InterfLoc = IDecl->getEndOfDefinitionLoc();
11410b57cec5SDimitry Andric   if (InterfLoc.isValid() && AMgr.isInCodeFile(InterfLoc))
11420b57cec5SDimitry Andric     return false;
11430b57cec5SDimitry Andric 
11440b57cec5SDimitry Andric   // Assume that property accessors are not overridden.
11450b57cec5SDimitry Andric   if (getMessageKind() == OCM_PropertyAccess)
11460b57cec5SDimitry Andric     return false;
11470b57cec5SDimitry Andric 
11480b57cec5SDimitry Andric   // We assume that if the method is public (declared outside of main file) or
11490b57cec5SDimitry Andric   // has a parent which publicly declares the method, the method could be
11500b57cec5SDimitry Andric   // overridden in a subclass.
11510b57cec5SDimitry Andric 
11520b57cec5SDimitry Andric   // Find the first declaration in the class hierarchy that declares
11530b57cec5SDimitry Andric   // the selector.
11540b57cec5SDimitry Andric   ObjCMethodDecl *D = nullptr;
11550b57cec5SDimitry Andric   while (true) {
11560b57cec5SDimitry Andric     D = IDecl->lookupMethod(Sel, true);
11570b57cec5SDimitry Andric 
11580b57cec5SDimitry Andric     // Cannot find a public definition.
11590b57cec5SDimitry Andric     if (!D)
11600b57cec5SDimitry Andric       return false;
11610b57cec5SDimitry Andric 
11620b57cec5SDimitry Andric     // If outside the main file,
11630b57cec5SDimitry Andric     if (D->getLocation().isValid() && !AMgr.isInCodeFile(D->getLocation()))
11640b57cec5SDimitry Andric       return true;
11650b57cec5SDimitry Andric 
11660b57cec5SDimitry Andric     if (D->isOverriding()) {
11670b57cec5SDimitry Andric       // Search in the superclass on the next iteration.
11680b57cec5SDimitry Andric       IDecl = D->getClassInterface();
11690b57cec5SDimitry Andric       if (!IDecl)
11700b57cec5SDimitry Andric         return false;
11710b57cec5SDimitry Andric 
11720b57cec5SDimitry Andric       IDecl = IDecl->getSuperClass();
11730b57cec5SDimitry Andric       if (!IDecl)
11740b57cec5SDimitry Andric         return false;
11750b57cec5SDimitry Andric 
11760b57cec5SDimitry Andric       continue;
11770b57cec5SDimitry Andric     }
11780b57cec5SDimitry Andric 
11790b57cec5SDimitry Andric     return false;
11800b57cec5SDimitry Andric   };
11810b57cec5SDimitry Andric 
11820b57cec5SDimitry Andric   llvm_unreachable("The while loop should always terminate.");
11830b57cec5SDimitry Andric }
11840b57cec5SDimitry Andric 
11850b57cec5SDimitry Andric static const ObjCMethodDecl *findDefiningRedecl(const ObjCMethodDecl *MD) {
11860b57cec5SDimitry Andric   if (!MD)
11870b57cec5SDimitry Andric     return MD;
11880b57cec5SDimitry Andric 
11890b57cec5SDimitry Andric   // Find the redeclaration that defines the method.
11900b57cec5SDimitry Andric   if (!MD->hasBody()) {
1191bdd1243dSDimitry Andric     for (auto *I : MD->redecls())
11920b57cec5SDimitry Andric       if (I->hasBody())
11930b57cec5SDimitry Andric         MD = cast<ObjCMethodDecl>(I);
11940b57cec5SDimitry Andric   }
11950b57cec5SDimitry Andric   return MD;
11960b57cec5SDimitry Andric }
11970b57cec5SDimitry Andric 
11985ffd83dbSDimitry Andric struct PrivateMethodKey {
11995ffd83dbSDimitry Andric   const ObjCInterfaceDecl *Interface;
12005ffd83dbSDimitry Andric   Selector LookupSelector;
12015ffd83dbSDimitry Andric   bool IsClassMethod;
12025ffd83dbSDimitry Andric };
12030b57cec5SDimitry Andric 
12045ffd83dbSDimitry Andric namespace llvm {
12055ffd83dbSDimitry Andric template <> struct DenseMapInfo<PrivateMethodKey> {
12065ffd83dbSDimitry Andric   using InterfaceInfo = DenseMapInfo<const ObjCInterfaceDecl *>;
12075ffd83dbSDimitry Andric   using SelectorInfo = DenseMapInfo<Selector>;
12080b57cec5SDimitry Andric 
12095ffd83dbSDimitry Andric   static inline PrivateMethodKey getEmptyKey() {
12105ffd83dbSDimitry Andric     return {InterfaceInfo::getEmptyKey(), SelectorInfo::getEmptyKey(), false};
12110b57cec5SDimitry Andric   }
12120b57cec5SDimitry Andric 
12135ffd83dbSDimitry Andric   static inline PrivateMethodKey getTombstoneKey() {
12145ffd83dbSDimitry Andric     return {InterfaceInfo::getTombstoneKey(), SelectorInfo::getTombstoneKey(),
12155ffd83dbSDimitry Andric             true};
12160b57cec5SDimitry Andric   }
12170b57cec5SDimitry Andric 
12185ffd83dbSDimitry Andric   static unsigned getHashValue(const PrivateMethodKey &Key) {
12195ffd83dbSDimitry Andric     return llvm::hash_combine(
12205ffd83dbSDimitry Andric         llvm::hash_code(InterfaceInfo::getHashValue(Key.Interface)),
12215ffd83dbSDimitry Andric         llvm::hash_code(SelectorInfo::getHashValue(Key.LookupSelector)),
12225ffd83dbSDimitry Andric         Key.IsClassMethod);
12230b57cec5SDimitry Andric   }
12240b57cec5SDimitry Andric 
12255ffd83dbSDimitry Andric   static bool isEqual(const PrivateMethodKey &LHS,
12265ffd83dbSDimitry Andric                       const PrivateMethodKey &RHS) {
12275ffd83dbSDimitry Andric     return InterfaceInfo::isEqual(LHS.Interface, RHS.Interface) &&
12285ffd83dbSDimitry Andric            SelectorInfo::isEqual(LHS.LookupSelector, RHS.LookupSelector) &&
12295ffd83dbSDimitry Andric            LHS.IsClassMethod == RHS.IsClassMethod;
12300b57cec5SDimitry Andric   }
12315ffd83dbSDimitry Andric };
12325ffd83dbSDimitry Andric } // end namespace llvm
12330b57cec5SDimitry Andric 
12345ffd83dbSDimitry Andric static const ObjCMethodDecl *
12355ffd83dbSDimitry Andric lookupRuntimeDefinition(const ObjCInterfaceDecl *Interface,
12365ffd83dbSDimitry Andric                         Selector LookupSelector, bool InstanceMethod) {
12370b57cec5SDimitry Andric   // Repeatedly calling lookupPrivateMethod() is expensive, especially
12380b57cec5SDimitry Andric   // when in many cases it returns null.  We cache the results so
12390b57cec5SDimitry Andric   // that repeated queries on the same ObjCIntefaceDecl and Selector
12400b57cec5SDimitry Andric   // don't incur the same cost.  On some test cases, we can see the
12410b57cec5SDimitry Andric   // same query being issued thousands of times.
12420b57cec5SDimitry Andric   //
12430b57cec5SDimitry Andric   // NOTE: This cache is essentially a "global" variable, but it
12440b57cec5SDimitry Andric   // only gets lazily created when we get here.  The value of the
12450b57cec5SDimitry Andric   // cache probably comes from it being global across ExprEngines,
12460b57cec5SDimitry Andric   // where the same queries may get issued.  If we are worried about
12470b57cec5SDimitry Andric   // concurrency, or possibly loading/unloading ASTs, etc., we may
12480b57cec5SDimitry Andric   // need to revisit this someday.  In terms of memory, this table
12490b57cec5SDimitry Andric   // stays around until clang quits, which also may be bad if we
12500b57cec5SDimitry Andric   // need to release memory.
12510b57cec5SDimitry Andric   using PrivateMethodCache =
1252bdd1243dSDimitry Andric       llvm::DenseMap<PrivateMethodKey, std::optional<const ObjCMethodDecl *>>;
12530b57cec5SDimitry Andric 
12540b57cec5SDimitry Andric   static PrivateMethodCache PMC;
1255bdd1243dSDimitry Andric   std::optional<const ObjCMethodDecl *> &Val =
12565ffd83dbSDimitry Andric       PMC[{Interface, LookupSelector, InstanceMethod}];
12570b57cec5SDimitry Andric 
12580b57cec5SDimitry Andric   // Query lookupPrivateMethod() if the cache does not hit.
125981ad6265SDimitry Andric   if (!Val) {
12605ffd83dbSDimitry Andric     Val = Interface->lookupPrivateMethod(LookupSelector, InstanceMethod);
12610b57cec5SDimitry Andric 
12625ffd83dbSDimitry Andric     if (!*Val) {
12635ffd83dbSDimitry Andric       // Query 'lookupMethod' as a backup.
12645ffd83dbSDimitry Andric       Val = Interface->lookupMethod(LookupSelector, InstanceMethod);
12650b57cec5SDimitry Andric     }
12660b57cec5SDimitry Andric   }
12670b57cec5SDimitry Andric 
126881ad6265SDimitry Andric   return *Val;
12695ffd83dbSDimitry Andric }
12705ffd83dbSDimitry Andric 
12715ffd83dbSDimitry Andric RuntimeDefinition ObjCMethodCall::getRuntimeDefinition() const {
12725ffd83dbSDimitry Andric   const ObjCMessageExpr *E = getOriginExpr();
12735ffd83dbSDimitry Andric   assert(E);
12745ffd83dbSDimitry Andric   Selector Sel = E->getSelector();
12755ffd83dbSDimitry Andric 
12765ffd83dbSDimitry Andric   if (E->isInstanceMessage()) {
12775ffd83dbSDimitry Andric     // Find the receiver type.
12785ffd83dbSDimitry Andric     const ObjCObjectType *ReceiverT = nullptr;
12795ffd83dbSDimitry Andric     bool CanBeSubClassed = false;
12805ffd83dbSDimitry Andric     bool LookingForInstanceMethod = true;
12815ffd83dbSDimitry Andric     QualType SupersType = E->getSuperType();
12825ffd83dbSDimitry Andric     const MemRegion *Receiver = nullptr;
12835ffd83dbSDimitry Andric 
12845ffd83dbSDimitry Andric     if (!SupersType.isNull()) {
12855ffd83dbSDimitry Andric       // The receiver is guaranteed to be 'super' in this case.
12865ffd83dbSDimitry Andric       // Super always means the type of immediate predecessor to the method
12875ffd83dbSDimitry Andric       // where the call occurs.
12885ffd83dbSDimitry Andric       ReceiverT = cast<ObjCObjectPointerType>(SupersType)->getObjectType();
12895ffd83dbSDimitry Andric     } else {
12905ffd83dbSDimitry Andric       Receiver = getReceiverSVal().getAsRegion();
12915ffd83dbSDimitry Andric       if (!Receiver)
12925ffd83dbSDimitry Andric         return {};
12935ffd83dbSDimitry Andric 
12945ffd83dbSDimitry Andric       DynamicTypeInfo DTI = getDynamicTypeInfo(getState(), Receiver);
12955ffd83dbSDimitry Andric       if (!DTI.isValid()) {
12965ffd83dbSDimitry Andric         assert(isa<AllocaRegion>(Receiver) &&
12975ffd83dbSDimitry Andric                "Unhandled untyped region class!");
12985ffd83dbSDimitry Andric         return {};
12995ffd83dbSDimitry Andric       }
13005ffd83dbSDimitry Andric 
13015ffd83dbSDimitry Andric       QualType DynType = DTI.getType();
13025ffd83dbSDimitry Andric       CanBeSubClassed = DTI.canBeASubClass();
13035ffd83dbSDimitry Andric 
13045ffd83dbSDimitry Andric       const auto *ReceiverDynT =
13055ffd83dbSDimitry Andric           dyn_cast<ObjCObjectPointerType>(DynType.getCanonicalType());
13065ffd83dbSDimitry Andric 
13075ffd83dbSDimitry Andric       if (ReceiverDynT) {
13085ffd83dbSDimitry Andric         ReceiverT = ReceiverDynT->getObjectType();
13095ffd83dbSDimitry Andric 
13105ffd83dbSDimitry Andric         // It can be actually class methods called with Class object as a
13115ffd83dbSDimitry Andric         // receiver. This type of messages is treated by the compiler as
13125ffd83dbSDimitry Andric         // instance (not class).
13135ffd83dbSDimitry Andric         if (ReceiverT->isObjCClass()) {
13145ffd83dbSDimitry Andric 
13155ffd83dbSDimitry Andric           SVal SelfVal = getState()->getSelfSVal(getLocationContext());
13165ffd83dbSDimitry Andric           // For [self classMethod], return compiler visible declaration.
13175ffd83dbSDimitry Andric           if (Receiver == SelfVal.getAsRegion()) {
13185ffd83dbSDimitry Andric             return RuntimeDefinition(findDefiningRedecl(E->getMethodDecl()));
13195ffd83dbSDimitry Andric           }
13205ffd83dbSDimitry Andric 
13215ffd83dbSDimitry Andric           // Otherwise, let's check if we know something about the type
13225ffd83dbSDimitry Andric           // inside of this class object.
13235ffd83dbSDimitry Andric           if (SymbolRef ReceiverSym = getReceiverSVal().getAsSymbol()) {
13245ffd83dbSDimitry Andric             DynamicTypeInfo DTI =
13255ffd83dbSDimitry Andric                 getClassObjectDynamicTypeInfo(getState(), ReceiverSym);
13265ffd83dbSDimitry Andric             if (DTI.isValid()) {
13275ffd83dbSDimitry Andric               // Let's use this type for lookup.
13285ffd83dbSDimitry Andric               ReceiverT =
13295ffd83dbSDimitry Andric                   cast<ObjCObjectType>(DTI.getType().getCanonicalType());
13305ffd83dbSDimitry Andric 
13315ffd83dbSDimitry Andric               CanBeSubClassed = DTI.canBeASubClass();
13325ffd83dbSDimitry Andric               // And it should be a class method instead.
13335ffd83dbSDimitry Andric               LookingForInstanceMethod = false;
13345ffd83dbSDimitry Andric             }
13355ffd83dbSDimitry Andric           }
13365ffd83dbSDimitry Andric         }
13375ffd83dbSDimitry Andric 
13385ffd83dbSDimitry Andric         if (CanBeSubClassed)
13395ffd83dbSDimitry Andric           if (ObjCInterfaceDecl *IDecl = ReceiverT->getInterface())
13405ffd83dbSDimitry Andric             // Even if `DynamicTypeInfo` told us that it can be
13415ffd83dbSDimitry Andric             // not necessarily this type, but its descendants, we still want
13425ffd83dbSDimitry Andric             // to check again if this selector can be actually overridden.
13435ffd83dbSDimitry Andric             CanBeSubClassed = canBeOverridenInSubclass(IDecl, Sel);
13445ffd83dbSDimitry Andric       }
13455ffd83dbSDimitry Andric     }
13465ffd83dbSDimitry Andric 
13475ffd83dbSDimitry Andric     // Lookup the instance method implementation.
13485ffd83dbSDimitry Andric     if (ReceiverT)
13495ffd83dbSDimitry Andric       if (ObjCInterfaceDecl *IDecl = ReceiverT->getInterface()) {
13505ffd83dbSDimitry Andric         const ObjCMethodDecl *MD =
13515ffd83dbSDimitry Andric             lookupRuntimeDefinition(IDecl, Sel, LookingForInstanceMethod);
13525ffd83dbSDimitry Andric 
1353480093f4SDimitry Andric         if (MD && !MD->hasBody())
1354480093f4SDimitry Andric           MD = MD->getCanonicalDecl();
13555ffd83dbSDimitry Andric 
13560b57cec5SDimitry Andric         if (CanBeSubClassed)
13570b57cec5SDimitry Andric           return RuntimeDefinition(MD, Receiver);
13580b57cec5SDimitry Andric         else
13590b57cec5SDimitry Andric           return RuntimeDefinition(MD, nullptr);
13600b57cec5SDimitry Andric       }
13610b57cec5SDimitry Andric   } else {
13620b57cec5SDimitry Andric     // This is a class method.
13630b57cec5SDimitry Andric     // If we have type info for the receiver class, we are calling via
13640b57cec5SDimitry Andric     // class name.
13650b57cec5SDimitry Andric     if (ObjCInterfaceDecl *IDecl = E->getReceiverInterface()) {
13660b57cec5SDimitry Andric       // Find/Return the method implementation.
13670b57cec5SDimitry Andric       return RuntimeDefinition(IDecl->lookupPrivateClassMethod(Sel));
13680b57cec5SDimitry Andric     }
13690b57cec5SDimitry Andric   }
13700b57cec5SDimitry Andric 
13710b57cec5SDimitry Andric   return {};
13720b57cec5SDimitry Andric }
13730b57cec5SDimitry Andric 
13740b57cec5SDimitry Andric bool ObjCMethodCall::argumentsMayEscape() const {
13750b57cec5SDimitry Andric   if (isInSystemHeader() && !isInstanceMessage()) {
13760b57cec5SDimitry Andric     Selector Sel = getSelector();
13770b57cec5SDimitry Andric     if (Sel.getNumArgs() == 1 &&
13780b57cec5SDimitry Andric         Sel.getIdentifierInfoForSlot(0)->isStr("valueWithPointer"))
13790b57cec5SDimitry Andric       return true;
13800b57cec5SDimitry Andric   }
13810b57cec5SDimitry Andric 
13820b57cec5SDimitry Andric   return CallEvent::argumentsMayEscape();
13830b57cec5SDimitry Andric }
13840b57cec5SDimitry Andric 
13850b57cec5SDimitry Andric void ObjCMethodCall::getInitialStackFrameContents(
13860b57cec5SDimitry Andric                                              const StackFrameContext *CalleeCtx,
13870b57cec5SDimitry Andric                                              BindingsTy &Bindings) const {
13880b57cec5SDimitry Andric   const auto *D = cast<ObjCMethodDecl>(CalleeCtx->getDecl());
13890b57cec5SDimitry Andric   SValBuilder &SVB = getState()->getStateManager().getSValBuilder();
13900b57cec5SDimitry Andric   addParameterValuesToBindings(CalleeCtx, Bindings, SVB, *this,
13910b57cec5SDimitry Andric                                D->parameters());
13920b57cec5SDimitry Andric 
13930b57cec5SDimitry Andric   SVal SelfVal = getReceiverSVal();
13940b57cec5SDimitry Andric   if (!SelfVal.isUnknown()) {
13950b57cec5SDimitry Andric     const VarDecl *SelfD = CalleeCtx->getAnalysisDeclContext()->getSelfDecl();
13960b57cec5SDimitry Andric     MemRegionManager &MRMgr = SVB.getRegionManager();
13970b57cec5SDimitry Andric     Loc SelfLoc = SVB.makeLoc(MRMgr.getVarRegion(SelfD, CalleeCtx));
13980b57cec5SDimitry Andric     Bindings.push_back(std::make_pair(SelfLoc, SelfVal));
13990b57cec5SDimitry Andric   }
14000b57cec5SDimitry Andric }
14010b57cec5SDimitry Andric 
14020b57cec5SDimitry Andric CallEventRef<>
14030b57cec5SDimitry Andric CallEventManager::getSimpleCall(const CallExpr *CE, ProgramStateRef State,
140406c3fb27SDimitry Andric                                 const LocationContext *LCtx,
140506c3fb27SDimitry Andric                                 CFGBlock::ConstCFGElementRef ElemRef) {
14060b57cec5SDimitry Andric   if (const auto *MCE = dyn_cast<CXXMemberCallExpr>(CE))
140706c3fb27SDimitry Andric     return create<CXXMemberCall>(MCE, State, LCtx, ElemRef);
14080b57cec5SDimitry Andric 
14090b57cec5SDimitry Andric   if (const auto *OpCE = dyn_cast<CXXOperatorCallExpr>(CE)) {
14100b57cec5SDimitry Andric     const FunctionDecl *DirectCallee = OpCE->getDirectCallee();
1411*0fca6ea1SDimitry Andric     if (const auto *MD = dyn_cast<CXXMethodDecl>(DirectCallee)) {
1412439352acSDimitry Andric       if (MD->isImplicitObjectMemberFunction())
141306c3fb27SDimitry Andric         return create<CXXMemberOperatorCall>(OpCE, State, LCtx, ElemRef);
1414*0fca6ea1SDimitry Andric       if (MD->isStatic())
1415*0fca6ea1SDimitry Andric         return create<CXXStaticOperatorCall>(OpCE, State, LCtx, ElemRef);
1416*0fca6ea1SDimitry Andric     }
14170b57cec5SDimitry Andric 
14180b57cec5SDimitry Andric   } else if (CE->getCallee()->getType()->isBlockPointerType()) {
141906c3fb27SDimitry Andric     return create<BlockCall>(CE, State, LCtx, ElemRef);
14200b57cec5SDimitry Andric   }
14210b57cec5SDimitry Andric 
14220b57cec5SDimitry Andric   // Otherwise, it's a normal function call, static member function call, or
14230b57cec5SDimitry Andric   // something we can't reason about.
142406c3fb27SDimitry Andric   return create<SimpleFunctionCall>(CE, State, LCtx, ElemRef);
14250b57cec5SDimitry Andric }
14260b57cec5SDimitry Andric 
14270b57cec5SDimitry Andric CallEventRef<>
14280b57cec5SDimitry Andric CallEventManager::getCaller(const StackFrameContext *CalleeCtx,
14290b57cec5SDimitry Andric                             ProgramStateRef State) {
14300b57cec5SDimitry Andric   const LocationContext *ParentCtx = CalleeCtx->getParent();
14310b57cec5SDimitry Andric   const LocationContext *CallerCtx = ParentCtx->getStackFrame();
143206c3fb27SDimitry Andric   CFGBlock::ConstCFGElementRef ElemRef = {CalleeCtx->getCallSiteBlock(),
143306c3fb27SDimitry Andric                                           CalleeCtx->getIndex()};
14340b57cec5SDimitry Andric   assert(CallerCtx && "This should not be used for top-level stack frames");
14350b57cec5SDimitry Andric 
14360b57cec5SDimitry Andric   const Stmt *CallSite = CalleeCtx->getCallSite();
14370b57cec5SDimitry Andric 
14380b57cec5SDimitry Andric   if (CallSite) {
143906c3fb27SDimitry Andric     if (CallEventRef<> Out = getCall(CallSite, State, CallerCtx, ElemRef))
14400b57cec5SDimitry Andric       return Out;
14410b57cec5SDimitry Andric 
14420b57cec5SDimitry Andric     SValBuilder &SVB = State->getStateManager().getSValBuilder();
14430b57cec5SDimitry Andric     const auto *Ctor = cast<CXXMethodDecl>(CalleeCtx->getDecl());
14440b57cec5SDimitry Andric     Loc ThisPtr = SVB.getCXXThis(Ctor, CalleeCtx);
14450b57cec5SDimitry Andric     SVal ThisVal = State->getSVal(ThisPtr);
14460b57cec5SDimitry Andric 
14475ffd83dbSDimitry Andric     if (const auto *CE = dyn_cast<CXXConstructExpr>(CallSite))
144806c3fb27SDimitry Andric       return getCXXConstructorCall(CE, ThisVal.getAsRegion(), State, CallerCtx,
144906c3fb27SDimitry Andric                                    ElemRef);
14505ffd83dbSDimitry Andric     else if (const auto *CIE = dyn_cast<CXXInheritedCtorInitExpr>(CallSite))
14515ffd83dbSDimitry Andric       return getCXXInheritedConstructorCall(CIE, ThisVal.getAsRegion(), State,
145206c3fb27SDimitry Andric                                             CallerCtx, ElemRef);
14535ffd83dbSDimitry Andric     else {
14545ffd83dbSDimitry Andric       // All other cases are handled by getCall.
14555ffd83dbSDimitry Andric       llvm_unreachable("This is not an inlineable statement");
14565ffd83dbSDimitry Andric     }
14570b57cec5SDimitry Andric   }
14580b57cec5SDimitry Andric 
14590b57cec5SDimitry Andric   // Fall back to the CFG. The only thing we haven't handled yet is
14600b57cec5SDimitry Andric   // destructors, though this could change in the future.
14610b57cec5SDimitry Andric   const CFGBlock *B = CalleeCtx->getCallSiteBlock();
14620b57cec5SDimitry Andric   CFGElement E = (*B)[CalleeCtx->getIndex()];
14630b57cec5SDimitry Andric   assert((E.getAs<CFGImplicitDtor>() || E.getAs<CFGTemporaryDtor>()) &&
14640b57cec5SDimitry Andric          "All other CFG elements should have exprs");
14650b57cec5SDimitry Andric 
14660b57cec5SDimitry Andric   SValBuilder &SVB = State->getStateManager().getSValBuilder();
14670b57cec5SDimitry Andric   const auto *Dtor = cast<CXXDestructorDecl>(CalleeCtx->getDecl());
14680b57cec5SDimitry Andric   Loc ThisPtr = SVB.getCXXThis(Dtor, CalleeCtx);
14690b57cec5SDimitry Andric   SVal ThisVal = State->getSVal(ThisPtr);
14700b57cec5SDimitry Andric 
14710b57cec5SDimitry Andric   const Stmt *Trigger;
1472bdd1243dSDimitry Andric   if (std::optional<CFGAutomaticObjDtor> AutoDtor =
1473bdd1243dSDimitry Andric           E.getAs<CFGAutomaticObjDtor>())
14740b57cec5SDimitry Andric     Trigger = AutoDtor->getTriggerStmt();
1475bdd1243dSDimitry Andric   else if (std::optional<CFGDeleteDtor> DeleteDtor = E.getAs<CFGDeleteDtor>())
14760b57cec5SDimitry Andric     Trigger = DeleteDtor->getDeleteExpr();
14770b57cec5SDimitry Andric   else
14780b57cec5SDimitry Andric     Trigger = Dtor->getBody();
14790b57cec5SDimitry Andric 
14800b57cec5SDimitry Andric   return getCXXDestructorCall(Dtor, Trigger, ThisVal.getAsRegion(),
148181ad6265SDimitry Andric                               E.getAs<CFGBaseDtor>().has_value(), State,
148206c3fb27SDimitry Andric                               CallerCtx, ElemRef);
14830b57cec5SDimitry Andric }
14840b57cec5SDimitry Andric 
14850b57cec5SDimitry Andric CallEventRef<> CallEventManager::getCall(const Stmt *S, ProgramStateRef State,
148606c3fb27SDimitry Andric                                          const LocationContext *LC,
148706c3fb27SDimitry Andric                                          CFGBlock::ConstCFGElementRef ElemRef) {
14880b57cec5SDimitry Andric   if (const auto *CE = dyn_cast<CallExpr>(S)) {
148906c3fb27SDimitry Andric     return getSimpleCall(CE, State, LC, ElemRef);
14900b57cec5SDimitry Andric   } else if (const auto *NE = dyn_cast<CXXNewExpr>(S)) {
149106c3fb27SDimitry Andric     return getCXXAllocatorCall(NE, State, LC, ElemRef);
149281ad6265SDimitry Andric   } else if (const auto *DE = dyn_cast<CXXDeleteExpr>(S)) {
149306c3fb27SDimitry Andric     return getCXXDeallocatorCall(DE, State, LC, ElemRef);
14940b57cec5SDimitry Andric   } else if (const auto *ME = dyn_cast<ObjCMessageExpr>(S)) {
149506c3fb27SDimitry Andric     return getObjCMethodCall(ME, State, LC, ElemRef);
14960b57cec5SDimitry Andric   } else {
14970b57cec5SDimitry Andric     return nullptr;
14980b57cec5SDimitry Andric   }
14990b57cec5SDimitry Andric }
1500