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