brintos

brintos / llvm-project-archived public Read only

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