15bc81eb9SEugene Zelenko //===- CallEvent.cpp - Wrapper for all function and method calls ----------===//
24f7df9beSJordan Rose //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
64f7df9beSJordan Rose //
74f7df9beSJordan Rose //===----------------------------------------------------------------------===//
84f7df9beSJordan Rose //
94f7df9beSJordan Rose /// \file This file defines CallEvent and its subclasses, which represent path-
104f7df9beSJordan Rose /// sensitive instances of different kinds of function and method calls
114f7df9beSJordan Rose /// (C, C++, and Objective-C).
124f7df9beSJordan Rose //
134f7df9beSJordan Rose //===----------------------------------------------------------------------===//
144f7df9beSJordan Rose 
154f7df9beSJordan Rose #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
165bc81eb9SEugene Zelenko #include "clang/AST/ASTContext.h"
1760573ae6SReid Kleckner #include "clang/AST/Attr.h"
185bc81eb9SEugene Zelenko #include "clang/AST/Decl.h"
195bc81eb9SEugene Zelenko #include "clang/AST/DeclBase.h"
205bc81eb9SEugene Zelenko #include "clang/AST/DeclCXX.h"
215bc81eb9SEugene Zelenko #include "clang/AST/DeclObjC.h"
225bc81eb9SEugene Zelenko #include "clang/AST/Expr.h"
235bc81eb9SEugene Zelenko #include "clang/AST/ExprCXX.h"
245bc81eb9SEugene Zelenko #include "clang/AST/ExprObjC.h"
254f7df9beSJordan Rose #include "clang/AST/ParentMap.h"
265bc81eb9SEugene Zelenko #include "clang/AST/Stmt.h"
275bc81eb9SEugene Zelenko #include "clang/AST/Type.h"
285bc81eb9SEugene Zelenko #include "clang/Analysis/AnalysisDeclContext.h"
295bc81eb9SEugene Zelenko #include "clang/Analysis/CFG.h"
30b21b4796SArtem Dergachev #include "clang/Analysis/CFGStmtMap.h"
31f0bb45faSArtem Dergachev #include "clang/Analysis/PathDiagnostic.h"
323a02247dSChandler Carruth #include "clang/Analysis/ProgramPoint.h"
335bc81eb9SEugene Zelenko #include "clang/Basic/IdentifierTable.h"
345bc81eb9SEugene Zelenko #include "clang/Basic/LLVM.h"
355bc81eb9SEugene Zelenko #include "clang/Basic/SourceLocation.h"
365bc81eb9SEugene Zelenko #include "clang/Basic/SourceManager.h"
375bc81eb9SEugene Zelenko #include "clang/Basic/Specifiers.h"
3860573ae6SReid Kleckner #include "clang/CrossTU/CrossTranslationUnit.h"
390b9d3a6eSBalazs Benics #include "clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h"
403a02247dSChandler Carruth #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
41e4bf456fSCsaba Dabis #include "clang/StaticAnalyzer/Core/PathSensitive/DynamicType.h"
4260573ae6SReid Kleckner #include "clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeInfo.h"
435bc81eb9SEugene Zelenko #include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
445bc81eb9SEugene Zelenko #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
455bc81eb9SEugene Zelenko #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h"
465bc81eb9SEugene Zelenko #include "clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h"
4760573ae6SReid Kleckner #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
485bc81eb9SEugene Zelenko #include "clang/StaticAnalyzer/Core/PathSensitive/Store.h"
495bc81eb9SEugene Zelenko #include "llvm/ADT/ArrayRef.h"
505bc81eb9SEugene Zelenko #include "llvm/ADT/DenseMap.h"
51d6461571SValeriy Savchenko #include "llvm/ADT/ImmutableList.h"
525bc81eb9SEugene Zelenko #include "llvm/ADT/None.h"
535bc81eb9SEugene Zelenko #include "llvm/ADT/Optional.h"
545bc81eb9SEugene Zelenko #include "llvm/ADT/PointerIntPair.h"
554f7df9beSJordan Rose #include "llvm/ADT/SmallSet.h"
565bc81eb9SEugene Zelenko #include "llvm/ADT/SmallVector.h"
574f7df9beSJordan Rose #include "llvm/ADT/StringExtras.h"
585bc81eb9SEugene Zelenko #include "llvm/ADT/StringRef.h"
595bc81eb9SEugene Zelenko #include "llvm/Support/Casting.h"
605bc81eb9SEugene Zelenko #include "llvm/Support/Compiler.h"
61504e2360SGeorge Karpenkov #include "llvm/Support/Debug.h"
625bc81eb9SEugene Zelenko #include "llvm/Support/ErrorHandling.h"
635bc81eb9SEugene Zelenko #include "llvm/Support/raw_ostream.h"
645bc81eb9SEugene Zelenko #include <cassert>
655bc81eb9SEugene Zelenko #include <utility>
66504e2360SGeorge Karpenkov 
67504e2360SGeorge Karpenkov #define DEBUG_TYPE "static-analyzer-call-event"
684f7df9beSJordan Rose 
694f7df9beSJordan Rose using namespace clang;
704f7df9beSJordan Rose using namespace ento;
714f7df9beSJordan Rose 
getResultType() const724f7df9beSJordan Rose QualType CallEvent::getResultType() const {
732da56438SJordan Rose   ASTContext &Ctx = getState()->getStateManager().getContext();
74405fdfc3SGeorge Karpenkov   const Expr *E = getOriginExpr();
75405fdfc3SGeorge Karpenkov   if (!E)
76405fdfc3SGeorge Karpenkov     return Ctx.VoidTy;
770c7cd4a8SMatheus Izvekov   return Ctx.getReferenceQualifiedType(E);
784f7df9beSJordan Rose }
794f7df9beSJordan Rose 
isCallback(QualType T)80fe1eca51SAnna Zaks static bool isCallback(QualType T) {
814f7df9beSJordan Rose   // If a parameter is a block or a callback, assume it can modify pointer.
824f7df9beSJordan Rose   if (T->isBlockPointerType() ||
834f7df9beSJordan Rose       T->isFunctionPointerType() ||
844f7df9beSJordan Rose       T->isObjCSelType())
854f7df9beSJordan Rose     return true;
864f7df9beSJordan Rose 
874f7df9beSJordan Rose   // Check if a callback is passed inside a struct (for both, struct passed by
884f7df9beSJordan Rose   // reference and by value). Dig just one level into the struct for now.
894f7df9beSJordan Rose 
90d1a08b6eSJordan Rose   if (T->isAnyPointerType() || T->isReferenceType())
914f7df9beSJordan Rose     T = T->getPointeeType();
924f7df9beSJordan Rose 
934f7df9beSJordan Rose   if (const RecordType *RT = T->getAsStructureType()) {
944f7df9beSJordan Rose     const RecordDecl *RD = RT->getDecl();
95e8a8baefSAaron Ballman     for (const auto *I : RD->fields()) {
964f7df9beSJordan Rose       QualType FieldT = I->getType();
974f7df9beSJordan Rose       if (FieldT->isBlockPointerType() || FieldT->isFunctionPointerType())
984f7df9beSJordan Rose         return true;
994f7df9beSJordan Rose     }
1004f7df9beSJordan Rose   }
1014f7df9beSJordan Rose   return false;
1024f7df9beSJordan Rose }
1034f7df9beSJordan Rose 
isVoidPointerToNonConst(QualType T)104fe1eca51SAnna Zaks static bool isVoidPointerToNonConst(QualType T) {
1055bc81eb9SEugene Zelenko   if (const auto *PT = T->getAs<PointerType>()) {
106fe1eca51SAnna Zaks     QualType PointeeTy = PT->getPointeeType();
107fe1eca51SAnna Zaks     if (PointeeTy.isConstQualified())
108fe1eca51SAnna Zaks       return false;
109fe1eca51SAnna Zaks     return PointeeTy->isVoidType();
110fe1eca51SAnna Zaks   } else
111fe1eca51SAnna Zaks     return false;
112fe1eca51SAnna Zaks }
113fe1eca51SAnna Zaks 
hasNonNullArgumentsWithType(bool (* Condition)(QualType)) const114fe1eca51SAnna Zaks bool CallEvent::hasNonNullArgumentsWithType(bool (*Condition)(QualType)) const {
1154f7df9beSJordan Rose   unsigned NumOfArgs = getNumArgs();
1164f7df9beSJordan Rose 
1174f7df9beSJordan Rose   // If calling using a function pointer, assume the function does not
118fe1eca51SAnna Zaks   // satisfy the callback.
119fe1eca51SAnna Zaks   // TODO: We could check the types of the arguments here.
1204f7df9beSJordan Rose   if (!getDecl())
1214f7df9beSJordan Rose     return false;
1224f7df9beSJordan Rose 
1234f7df9beSJordan Rose   unsigned Idx = 0;
1244f7df9beSJordan Rose   for (CallEvent::param_type_iterator I = param_type_begin(),
1254f7df9beSJordan Rose                                       E = param_type_end();
1264f7df9beSJordan Rose        I != E && Idx < NumOfArgs; ++I, ++Idx) {
127fe1eca51SAnna Zaks     // If the parameter is 0, it's harmless.
128fe1eca51SAnna Zaks     if (getArgSVal(Idx).isZeroConstant())
129fe1eca51SAnna Zaks       continue;
130fe1eca51SAnna Zaks 
131fe1eca51SAnna Zaks     if (Condition(*I))
1324f7df9beSJordan Rose       return true;
1334f7df9beSJordan Rose   }
1344f7df9beSJordan Rose   return false;
1354f7df9beSJordan Rose }
1364f7df9beSJordan Rose 
hasNonZeroCallbackArg() const137fe1eca51SAnna Zaks bool CallEvent::hasNonZeroCallbackArg() const {
138fe1eca51SAnna Zaks   return hasNonNullArgumentsWithType(isCallback);
139fe1eca51SAnna Zaks }
140fe1eca51SAnna Zaks 
hasVoidPointerToNonConstArg() const141fe1eca51SAnna Zaks bool CallEvent::hasVoidPointerToNonConstArg() const {
142fe1eca51SAnna Zaks   return hasNonNullArgumentsWithType(isVoidPointerToNonConst);
143fe1eca51SAnna Zaks }
144fe1eca51SAnna Zaks 
isGlobalCFunction(StringRef FunctionName) const145829c3831SJordan Rose bool CallEvent::isGlobalCFunction(StringRef FunctionName) const {
1465bc81eb9SEugene Zelenko   const auto *FD = dyn_cast_or_null<FunctionDecl>(getDecl());
147829c3831SJordan Rose   if (!FD)
148829c3831SJordan Rose     return false;
149829c3831SJordan Rose 
150829c3831SJordan Rose   return CheckerContext::isCLibraryFunction(FD, FunctionName);
151829c3831SJordan Rose }
152829c3831SJordan Rose 
getCalleeAnalysisDeclContext() const153b21b4796SArtem Dergachev AnalysisDeclContext *CallEvent::getCalleeAnalysisDeclContext() const {
154b21b4796SArtem Dergachev   const Decl *D = getDecl();
155b21b4796SArtem Dergachev   if (!D)
156b21b4796SArtem Dergachev     return nullptr;
157b21b4796SArtem Dergachev 
1583ccf14ebSArtem Dergachev   AnalysisDeclContext *ADC =
1593ccf14ebSArtem Dergachev       LCtx->getAnalysisDeclContext()->getManager()->getContext(D);
1603ccf14ebSArtem Dergachev 
1613ccf14ebSArtem Dergachev   return ADC;
162b21b4796SArtem Dergachev }
163b21b4796SArtem Dergachev 
1647740c6d6SCsaba Dabis const StackFrameContext *
getCalleeStackFrame(unsigned BlockCount) const1657740c6d6SCsaba Dabis CallEvent::getCalleeStackFrame(unsigned BlockCount) const {
166b21b4796SArtem Dergachev   AnalysisDeclContext *ADC = getCalleeAnalysisDeclContext();
167b21b4796SArtem Dergachev   if (!ADC)
168b21b4796SArtem Dergachev     return nullptr;
169b21b4796SArtem Dergachev 
170b21b4796SArtem Dergachev   const Expr *E = getOriginExpr();
171b21b4796SArtem Dergachev   if (!E)
172b21b4796SArtem Dergachev     return nullptr;
173b21b4796SArtem Dergachev 
174b21b4796SArtem Dergachev   // Recover CFG block via reverse lookup.
175b21b4796SArtem Dergachev   // TODO: If we were to keep CFG element information as part of the CallEvent
176b21b4796SArtem Dergachev   // instead of doing this reverse lookup, we would be able to build the stack
177b21b4796SArtem Dergachev   // frame for non-expression-based calls, and also we wouldn't need the reverse
178b21b4796SArtem Dergachev   // lookup.
179b21b4796SArtem Dergachev   CFGStmtMap *Map = LCtx->getAnalysisDeclContext()->getCFGStmtMap();
180b21b4796SArtem Dergachev   const CFGBlock *B = Map->getBlock(E);
181b21b4796SArtem Dergachev   assert(B);
182b21b4796SArtem Dergachev 
183b21b4796SArtem Dergachev   // Also recover CFG index by scanning the CFG block.
184b21b4796SArtem Dergachev   unsigned Idx = 0, Sz = B->size();
185b21b4796SArtem Dergachev   for (; Idx < Sz; ++Idx)
186b21b4796SArtem Dergachev     if (auto StmtElem = (*B)[Idx].getAs<CFGStmt>())
187b21b4796SArtem Dergachev       if (StmtElem->getStmt() == E)
188b21b4796SArtem Dergachev         break;
189b21b4796SArtem Dergachev   assert(Idx < Sz);
190b21b4796SArtem Dergachev 
1917740c6d6SCsaba Dabis   return ADC->getManager()->getStackFrame(ADC, LCtx, E, B, BlockCount, Idx);
192b21b4796SArtem Dergachev }
193b21b4796SArtem Dergachev 
19498db1f99SAdam Balogh const ParamVarRegion
getParameterLocation(unsigned Index,unsigned BlockCount) const19598db1f99SAdam Balogh *CallEvent::getParameterLocation(unsigned Index, unsigned BlockCount) const {
1967740c6d6SCsaba Dabis   const StackFrameContext *SFC = getCalleeStackFrame(BlockCount);
197b21b4796SArtem Dergachev   // We cannot construct a VarRegion without a stack frame.
198b21b4796SArtem Dergachev   if (!SFC)
199b21b4796SArtem Dergachev     return nullptr;
200b21b4796SArtem Dergachev 
20198db1f99SAdam Balogh   const ParamVarRegion *PVR =
20298db1f99SAdam Balogh     State->getStateManager().getRegionManager().getParamVarRegion(
20398db1f99SAdam Balogh         getOriginExpr(), Index, SFC);
20498db1f99SAdam Balogh   return PVR;
205b21b4796SArtem Dergachev }
206b21b4796SArtem Dergachev 
2079fc8faf9SAdrian Prantl /// Returns true if a type is a pointer-to-const or reference-to-const
2084f7df9beSJordan Rose /// with no further indirection.
isPointerToConst(QualType Ty)2094f7df9beSJordan Rose static bool isPointerToConst(QualType Ty) {
2104f7df9beSJordan Rose   QualType PointeeTy = Ty->getPointeeType();
2114f7df9beSJordan Rose   if (PointeeTy == QualType())
2124f7df9beSJordan Rose     return false;
2134f7df9beSJordan Rose   if (!PointeeTy.isConstQualified())
2144f7df9beSJordan Rose     return false;
2154f7df9beSJordan Rose   if (PointeeTy->isAnyPointerType())
2164f7df9beSJordan Rose     return false;
2174f7df9beSJordan Rose   return true;
2184f7df9beSJordan Rose }
2194f7df9beSJordan Rose 
2204f7df9beSJordan Rose // Try to retrieve the function declaration and find the function parameter
2214f7df9beSJordan Rose // types which are pointers/references to a non-pointer const.
2224f7df9beSJordan Rose // We will not invalidate the corresponding argument regions.
findPtrToConstParams(llvm::SmallSet<unsigned,4> & PreserveArgs,const CallEvent & Call)2235413aaa7SJordan Rose static void findPtrToConstParams(llvm::SmallSet<unsigned, 4> &PreserveArgs,
2244f7df9beSJordan Rose                                  const CallEvent &Call) {
2254f7df9beSJordan Rose   unsigned Idx = 0;
2264f7df9beSJordan Rose   for (CallEvent::param_type_iterator I = Call.param_type_begin(),
2274f7df9beSJordan Rose                                       E = Call.param_type_end();
2284f7df9beSJordan Rose        I != E; ++I, ++Idx) {
2294f7df9beSJordan Rose     if (isPointerToConst(*I))
2304f7df9beSJordan Rose       PreserveArgs.insert(Idx);
2314f7df9beSJordan Rose   }
2324f7df9beSJordan Rose }
2334f7df9beSJordan Rose 
invalidateRegions(unsigned BlockCount,ProgramStateRef Orig) const2344f7df9beSJordan Rose ProgramStateRef CallEvent::invalidateRegions(unsigned BlockCount,
2354f7df9beSJordan Rose                                              ProgramStateRef Orig) const {
2364f7df9beSJordan Rose   ProgramStateRef Result = (Orig ? Orig : getState());
2374f7df9beSJordan Rose 
2382741654bSJordan Rose   // Don't invalidate anything if the callee is marked pure/const.
2392741654bSJordan Rose   if (const Decl *callee = getDecl())
2402741654bSJordan Rose     if (callee->hasAttr<PureAttr>() || callee->hasAttr<ConstAttr>())
2412741654bSJordan Rose       return Result;
2422741654bSJordan Rose 
24360bf5f45SAnna Zaks   SmallVector<SVal, 8> ValuesToInvalidate;
244424ad95fSAnton Yartsev   RegionAndSymbolInvalidationTraits ETraits;
24560bf5f45SAnna Zaks 
2464f770deeSDevin Coughlin   getExtraInvalidatedValues(ValuesToInvalidate, &ETraits);
2474f7df9beSJordan Rose 
2484f7df9beSJordan Rose   // Indexes of arguments whose values will be preserved by the call.
2495413aaa7SJordan Rose   llvm::SmallSet<unsigned, 4> PreserveArgs;
2504f7df9beSJordan Rose   if (!argumentsMayEscape())
2514f7df9beSJordan Rose     findPtrToConstParams(PreserveArgs, *this);
2524f7df9beSJordan Rose 
2534f7df9beSJordan Rose   for (unsigned Idx = 0, Count = getNumArgs(); Idx != Count; ++Idx) {
2544f7df9beSJordan Rose     // Mark this region for invalidation.  We batch invalidate regions
2554f7df9beSJordan Rose     // below for efficiency.
2565413aaa7SJordan Rose     if (PreserveArgs.count(Idx))
2573d90e7e8SArtem Dergachev       if (const MemRegion *MR = getArgSVal(Idx).getAsRegion())
2583d90e7e8SArtem Dergachev         ETraits.setTrait(MR->getBaseRegion(),
259424ad95fSAnton Yartsev                         RegionAndSymbolInvalidationTraits::TK_PreserveContents);
2603d90e7e8SArtem Dergachev         // TODO: Factor this out + handle the lower level const pointers.
261424ad95fSAnton Yartsev 
26260bf5f45SAnna Zaks     ValuesToInvalidate.push_back(getArgSVal(Idx));
2633ccf14ebSArtem Dergachev 
2643ccf14ebSArtem Dergachev     // If a function accepts an object by argument (which would of course be a
2653ccf14ebSArtem Dergachev     // temporary that isn't lifetime-extended), invalidate the object itself,
2663ccf14ebSArtem Dergachev     // not only other objects reachable from it. This is necessary because the
2673ccf14ebSArtem Dergachev     // destructor has access to the temporary object after the call.
2683ccf14ebSArtem Dergachev     // TODO: Support placement arguments once we start
2693ccf14ebSArtem Dergachev     // constructing them directly.
2703ccf14ebSArtem Dergachev     // TODO: This is unnecessary when there's no destructor, but that's
2713ccf14ebSArtem Dergachev     // currently hard to figure out.
2723ccf14ebSArtem Dergachev     if (getKind() != CE_CXXAllocator)
2733ccf14ebSArtem Dergachev       if (isArgumentConstructedDirectly(Idx))
2743ccf14ebSArtem Dergachev         if (auto AdjIdx = getAdjustedParameterIndex(Idx))
27598db1f99SAdam Balogh           if (const TypedValueRegion *TVR =
27698db1f99SAdam Balogh                   getParameterLocation(*AdjIdx, BlockCount))
27798db1f99SAdam Balogh             ValuesToInvalidate.push_back(loc::MemRegionVal(TVR));
2784f7df9beSJordan Rose   }
2794f7df9beSJordan Rose 
2804f7df9beSJordan Rose   // Invalidate designated regions using the batch invalidation API.
2814f7df9beSJordan Rose   // NOTE: Even if RegionsToInvalidate is empty, we may still invalidate
2824f7df9beSJordan Rose   //  global variables.
28360bf5f45SAnna Zaks   return Result->invalidateRegions(ValuesToInvalidate, getOriginExpr(),
2844f7df9beSJordan Rose                                    BlockCount, getLocationContext(),
2859747febbSAnna Zaks                                    /*CausedByPointerEscape*/ true,
2860dbb783cSCraig Topper                                    /*Symbols=*/nullptr, this, &ETraits);
2874f7df9beSJordan Rose }
2884f7df9beSJordan Rose 
getProgramPoint(bool IsPreVisit,const ProgramPointTag * Tag) const2894f7df9beSJordan Rose ProgramPoint CallEvent::getProgramPoint(bool IsPreVisit,
2904f7df9beSJordan Rose                                         const ProgramPointTag *Tag) const {
2914f7df9beSJordan Rose   if (const Expr *E = getOriginExpr()) {
2924f7df9beSJordan Rose     if (IsPreVisit)
2934f7df9beSJordan Rose       return PreStmt(E, getLocationContext(), Tag);
2944f7df9beSJordan Rose     return PostStmt(E, getLocationContext(), Tag);
2954f7df9beSJordan Rose   }
2964f7df9beSJordan Rose 
2974f7df9beSJordan Rose   const Decl *D = getDecl();
2984f7df9beSJordan Rose   assert(D && "Cannot get a program point without a statement or decl");
2994f7df9beSJordan Rose 
3004f7df9beSJordan Rose   SourceLocation Loc = getSourceRange().getBegin();
3014f7df9beSJordan Rose   if (IsPreVisit)
3024f7df9beSJordan Rose     return PreImplicitCall(D, Loc, getLocationContext(), Tag);
3034f7df9beSJordan Rose   return PostImplicitCall(D, Loc, getLocationContext(), Tag);
3044f7df9beSJordan Rose }
3054f7df9beSJordan Rose 
getArgSVal(unsigned Index) const30672ce8e2dSJordan Rose SVal CallEvent::getArgSVal(unsigned Index) const {
30772ce8e2dSJordan Rose   const Expr *ArgE = getArgExpr(Index);
30872ce8e2dSJordan Rose   if (!ArgE)
30972ce8e2dSJordan Rose     return UnknownVal();
31072ce8e2dSJordan Rose   return getSVal(ArgE);
31172ce8e2dSJordan Rose }
31272ce8e2dSJordan Rose 
getArgSourceRange(unsigned Index) const31372ce8e2dSJordan Rose SourceRange CallEvent::getArgSourceRange(unsigned Index) const {
31472ce8e2dSJordan Rose   const Expr *ArgE = getArgExpr(Index);
31572ce8e2dSJordan Rose   if (!ArgE)
3165bc81eb9SEugene Zelenko     return {};
31772ce8e2dSJordan Rose   return ArgE->getSourceRange();
31872ce8e2dSJordan Rose }
31972ce8e2dSJordan Rose 
getReturnValue() const320829c3831SJordan Rose SVal CallEvent::getReturnValue() const {
321829c3831SJordan Rose   const Expr *E = getOriginExpr();
322829c3831SJordan Rose   if (!E)
323829c3831SJordan Rose     return UndefinedVal();
324829c3831SJordan Rose   return getSVal(E);
325829c3831SJordan Rose }
326829c3831SJordan Rose 
dump() const327ef6b007dSAlp Toker LLVM_DUMP_METHOD void CallEvent::dump() const { dump(llvm::errs()); }
3289299d8c2SBenjamin Kramer 
dump(raw_ostream & Out) const32972ce8e2dSJordan Rose void CallEvent::dump(raw_ostream &Out) const {
33072ce8e2dSJordan Rose   ASTContext &Ctx = getState()->getStateManager().getContext();
33172ce8e2dSJordan Rose   if (const Expr *E = getOriginExpr()) {
3320dbb783cSCraig Topper     E->printPretty(Out, nullptr, Ctx.getPrintingPolicy());
33372ce8e2dSJordan Rose     return;
33472ce8e2dSJordan Rose   }
33572ce8e2dSJordan Rose 
33672ce8e2dSJordan Rose   if (const Decl *D = getDecl()) {
33772ce8e2dSJordan Rose     Out << "Call to ";
33872ce8e2dSJordan Rose     D->print(Out, Ctx.getPrintingPolicy());
33972ce8e2dSJordan Rose     return;
34072ce8e2dSJordan Rose   }
34172ce8e2dSJordan Rose 
342023c4d40SKirstóf Umann   Out << "Unknown call (type " << getKindAsString() << ")";
34372ce8e2dSJordan Rose }
34472ce8e2dSJordan Rose 
isCallStmt(const Stmt * S)345e537cc05SJordan Rose bool CallEvent::isCallStmt(const Stmt *S) {
34616be17adSBalazs Benics   return isa<CallExpr, ObjCMessageExpr, CXXConstructExpr, CXXNewExpr>(S);
3474f7df9beSJordan Rose }
3484f7df9beSJordan Rose 
getDeclaredResultType(const Decl * D)3495d2964e7SAnna Zaks QualType CallEvent::getDeclaredResultType(const Decl *D) {
3505d2964e7SAnna Zaks   assert(D);
3515bc81eb9SEugene Zelenko   if (const auto *FD = dyn_cast<FunctionDecl>(D))
352314cc81bSAlp Toker     return FD->getReturnType();
3535bc81eb9SEugene Zelenko   if (const auto *MD = dyn_cast<ObjCMethodDecl>(D))
354314cc81bSAlp Toker     return MD->getReturnType();
3555bc81eb9SEugene Zelenko   if (const auto *BD = dyn_cast<BlockDecl>(D)) {
356add14263SJordan Rose     // Blocks are difficult because the return type may not be stored in the
357add14263SJordan Rose     // BlockDecl itself. The AST should probably be enhanced, but for now we
358add14263SJordan Rose     // just do what we can.
359278d9de3SJordan Rose     // If the block is declared without an explicit argument list, the
360278d9de3SJordan Rose     // signature-as-written just includes the return type, not the entire
361278d9de3SJordan Rose     // function type.
3621bfe9c78SJordan Rose     // FIXME: All blocks should have signatures-as-written, even if the return
363278d9de3SJordan Rose     // type is inferred. (That's signified with a dependent result type.)
3641bfe9c78SJordan Rose     if (const TypeSourceInfo *TSI = BD->getSignatureAsWritten()) {
365278d9de3SJordan Rose       QualType Ty = TSI->getType();
366278d9de3SJordan Rose       if (const FunctionType *FT = Ty->getAs<FunctionType>())
367314cc81bSAlp Toker         Ty = FT->getReturnType();
368278d9de3SJordan Rose       if (!Ty->isDependentType())
369278d9de3SJordan Rose         return Ty;
3701bfe9c78SJordan Rose     }
371add14263SJordan Rose 
3725bc81eb9SEugene Zelenko     return {};
373add14263SJordan Rose   }
374add14263SJordan Rose 
3753553bb38SJordan Rose   llvm_unreachable("unknown callable kind");
3763553bb38SJordan Rose }
3773553bb38SJordan Rose 
isVariadic(const Decl * D)3783553bb38SJordan Rose bool CallEvent::isVariadic(const Decl *D) {
3793553bb38SJordan Rose   assert(D);
3803553bb38SJordan Rose 
3815bc81eb9SEugene Zelenko   if (const auto *FD = dyn_cast<FunctionDecl>(D))
3823553bb38SJordan Rose     return FD->isVariadic();
3835bc81eb9SEugene Zelenko   if (const auto *MD = dyn_cast<ObjCMethodDecl>(D))
3843553bb38SJordan Rose     return MD->isVariadic();
3855bc81eb9SEugene Zelenko   if (const auto *BD = dyn_cast<BlockDecl>(D))
3863553bb38SJordan Rose     return BD->isVariadic();
3873553bb38SJordan Rose 
3883553bb38SJordan Rose   llvm_unreachable("unknown callable kind");
3895d2964e7SAnna Zaks }
3905d2964e7SAnna Zaks 
isTransparentUnion(QualType T)391d6461571SValeriy Savchenko static bool isTransparentUnion(QualType T) {
392d6461571SValeriy Savchenko   const RecordType *UT = T->getAsUnionType();
393d6461571SValeriy Savchenko   return UT && UT->getDecl()->hasAttr<TransparentUnionAttr>();
394d6461571SValeriy Savchenko }
395d6461571SValeriy Savchenko 
396d6461571SValeriy Savchenko // In some cases, symbolic cases should be transformed before we associate
397d6461571SValeriy Savchenko // them with parameters.  This function incapsulates such cases.
processArgument(SVal Value,const Expr * ArgumentExpr,const ParmVarDecl * Parameter,SValBuilder & SVB)398d6461571SValeriy Savchenko static SVal processArgument(SVal Value, const Expr *ArgumentExpr,
399d6461571SValeriy Savchenko                             const ParmVarDecl *Parameter, SValBuilder &SVB) {
400d6461571SValeriy Savchenko   QualType ParamType = Parameter->getType();
401d6461571SValeriy Savchenko   QualType ArgumentType = ArgumentExpr->getType();
402d6461571SValeriy Savchenko 
403d6461571SValeriy Savchenko   // Transparent unions allow users to easily convert values of union field
404d6461571SValeriy Savchenko   // types into union-typed objects.
405d6461571SValeriy Savchenko   //
406d6461571SValeriy Savchenko   // Also, more importantly, they allow users to define functions with different
407d6461571SValeriy Savchenko   // different parameter types, substituting types matching transparent union
408d6461571SValeriy Savchenko   // field types with the union type itself.
409d6461571SValeriy Savchenko   //
410d6461571SValeriy Savchenko   // Here, we check specifically for latter cases and prevent binding
411d6461571SValeriy Savchenko   // field-typed values to union-typed regions.
412d6461571SValeriy Savchenko   if (isTransparentUnion(ParamType) &&
413d6461571SValeriy Savchenko       // Let's check that we indeed trying to bind different types.
414d6461571SValeriy Savchenko       !isTransparentUnion(ArgumentType)) {
415d6461571SValeriy Savchenko     BasicValueFactory &BVF = SVB.getBasicValueFactory();
416d6461571SValeriy Savchenko 
417d6461571SValeriy Savchenko     llvm::ImmutableList<SVal> CompoundSVals = BVF.getEmptySValList();
418d6461571SValeriy Savchenko     CompoundSVals = BVF.prependSVal(Value, CompoundSVals);
419d6461571SValeriy Savchenko 
420d6461571SValeriy Savchenko     // Wrap it with compound value.
421d6461571SValeriy Savchenko     return SVB.makeCompoundVal(ParamType, CompoundSVals);
422d6461571SValeriy Savchenko   }
423d6461571SValeriy Savchenko 
424d6461571SValeriy Savchenko   return Value;
425d6461571SValeriy Savchenko }
426d6461571SValeriy Savchenko 
addParameterValuesToBindings(const StackFrameContext * CalleeCtx,CallEvent::BindingsTy & Bindings,SValBuilder & SVB,const CallEvent & Call,ArrayRef<ParmVarDecl * > parameters)42742e8d649SJordan Rose static void addParameterValuesToBindings(const StackFrameContext *CalleeCtx,
42842e8d649SJordan Rose                                          CallEvent::BindingsTy &Bindings,
42942e8d649SJordan Rose                                          SValBuilder &SVB,
43042e8d649SJordan Rose                                          const CallEvent &Call,
4312ff16004STed Kremenek                                          ArrayRef<ParmVarDecl*> parameters) {
43242e8d649SJordan Rose   MemRegionManager &MRMgr = SVB.getRegionManager();
4334f7df9beSJordan Rose 
434963f91b3SPavel Labath   // If the function has fewer parameters than the call has arguments, we simply
435963f91b3SPavel Labath   // do not bind any values to them.
436963f91b3SPavel Labath   unsigned NumArgs = Call.getNumArgs();
43742e8d649SJordan Rose   unsigned Idx = 0;
4382ff16004STed Kremenek   ArrayRef<ParmVarDecl*>::iterator I = parameters.begin(), E = parameters.end();
439963f91b3SPavel Labath   for (; I != E && Idx < NumArgs; ++I, ++Idx) {
4400cd4d47cSKadir Cetinkaya     assert(*I && "Formal parameter has no decl?");
4414f7df9beSJordan Rose 
442fcf107d4SArtem Dergachev     // TODO: Support allocator calls.
4433ccf14ebSArtem Dergachev     if (Call.getKind() != CE_CXXAllocator)
444be86fdb8SArtem Dergachev       if (Call.isArgumentConstructedDirectly(Call.getASTArgumentIndex(Idx)))
4453ccf14ebSArtem Dergachev         continue;
4463ccf14ebSArtem Dergachev 
447fcf107d4SArtem Dergachev     // TODO: Allocators should receive the correct size and possibly alignment,
448fcf107d4SArtem Dergachev     // determined in compile-time but not represented as arg-expressions,
449fcf107d4SArtem Dergachev     // which makes getArgSVal() fail and return UnknownVal.
45042e8d649SJordan Rose     SVal ArgVal = Call.getArgSVal(Idx);
451d6461571SValeriy Savchenko     const Expr *ArgExpr = Call.getArgExpr(Idx);
45242e8d649SJordan Rose     if (!ArgVal.isUnknown()) {
45398db1f99SAdam Balogh       Loc ParamLoc = SVB.makeLoc(
45498db1f99SAdam Balogh           MRMgr.getParamVarRegion(Call.getOriginExpr(), Idx, CalleeCtx));
455d6461571SValeriy Savchenko       Bindings.push_back(
456d6461571SValeriy Savchenko           std::make_pair(ParamLoc, processArgument(ArgVal, ArgExpr, *I, SVB)));
45742e8d649SJordan Rose     }
4584f7df9beSJordan Rose   }
4594f7df9beSJordan Rose 
46042e8d649SJordan Rose   // FIXME: Variadic arguments are not handled at all right now.
46142e8d649SJordan Rose }
46242e8d649SJordan Rose 
getConstructionContext() const463813734daSAdam Balogh const ConstructionContext *CallEvent::getConstructionContext() const {
464813734daSAdam Balogh   const StackFrameContext *StackFrame = getCalleeStackFrame(0);
465813734daSAdam Balogh   if (!StackFrame)
466813734daSAdam Balogh     return nullptr;
467813734daSAdam Balogh 
468813734daSAdam Balogh   const CFGElement Element = StackFrame->getCallSiteCFGElement();
469813734daSAdam Balogh   if (const auto Ctor = Element.getAs<CFGConstructor>()) {
470813734daSAdam Balogh     return Ctor->getConstructionContext();
471813734daSAdam Balogh   }
472813734daSAdam Balogh 
473813734daSAdam Balogh   if (const auto RecCall = Element.getAs<CFGCXXRecordTypedCall>()) {
474813734daSAdam Balogh     return RecCall->getConstructionContext();
475813734daSAdam Balogh   }
476813734daSAdam Balogh 
477813734daSAdam Balogh   return nullptr;
478813734daSAdam Balogh }
479813734daSAdam Balogh 
480813734daSAdam Balogh Optional<SVal>
getReturnValueUnderConstruction() const481813734daSAdam Balogh CallEvent::getReturnValueUnderConstruction() const {
482813734daSAdam Balogh   const auto *CC = getConstructionContext();
483813734daSAdam Balogh   if (!CC)
484813734daSAdam Balogh     return None;
485813734daSAdam Balogh 
48637c1bf21SNithin Vadukkumchery Rajendrakumar   EvalCallOptions CallOpts;
487813734daSAdam Balogh   ExprEngine &Engine = getState()->getStateManager().getOwningEngine();
488813734daSAdam Balogh   SVal RetVal =
489813734daSAdam Balogh     Engine.computeObjectUnderConstruction(getOriginExpr(), getState(),
490813734daSAdam Balogh                                           getLocationContext(), CC, CallOpts);
491813734daSAdam Balogh   return RetVal;
492813734daSAdam Balogh }
493813734daSAdam Balogh 
parameters() const4942ff16004STed Kremenek ArrayRef<ParmVarDecl*> AnyFunctionCall::parameters() const {
49542e8d649SJordan Rose   const FunctionDecl *D = getDecl();
4964f7df9beSJordan Rose   if (!D)
49700bbdcf9SCraig Topper     return None;
4982ff16004STed Kremenek   return D->parameters();
49942e8d649SJordan Rose }
50042e8d649SJordan Rose 
getRuntimeDefinition() const5017b9cf1c4SGeorge Karpenkov RuntimeDefinition AnyFunctionCall::getRuntimeDefinition() const {
5027b9cf1c4SGeorge Karpenkov   const FunctionDecl *FD = getDecl();
503ca7923abSGabor Horvath   if (!FD)
504ca7923abSGabor Horvath     return {};
505ca7923abSGabor Horvath 
5067b9cf1c4SGeorge Karpenkov   // Note that the AnalysisDeclContext will have the FunctionDecl with
5077b9cf1c4SGeorge Karpenkov   // the definition (if one exists).
5087b9cf1c4SGeorge Karpenkov   AnalysisDeclContext *AD =
5097b9cf1c4SGeorge Karpenkov     getLocationContext()->getAnalysisDeclContext()->
5107b9cf1c4SGeorge Karpenkov     getManager()->getContext(FD);
511504e2360SGeorge Karpenkov   bool IsAutosynthesized;
512504e2360SGeorge Karpenkov   Stmt* Body = AD->getBody(IsAutosynthesized);
5133538b39eSNicola Zaghen   LLVM_DEBUG({
514504e2360SGeorge Karpenkov     if (IsAutosynthesized)
515504e2360SGeorge Karpenkov       llvm::dbgs() << "Using autosynthesized body for " << FD->getName()
516504e2360SGeorge Karpenkov                    << "\n";
517504e2360SGeorge Karpenkov   });
5187b9cf1c4SGeorge Karpenkov 
519d70ec366SAdam Balogh   ExprEngine &Engine = getState()->getStateManager().getOwningEngine();
52056b9b97cSGabor Marton   cross_tu::CrossTranslationUnitContext &CTUCtx =
52156b9b97cSGabor Marton       *Engine.getCrossTranslationUnitContext();
52256b9b97cSGabor Marton 
52321aa8db6SGabor Horvath   AnalyzerOptions &Opts = Engine.getAnalysisManager().options;
5248b9b3bd0SIlya Biryukov 
52556b9b97cSGabor Marton   if (Body) {
52656b9b97cSGabor Marton     const Decl* Decl = AD->getDecl();
52756b9b97cSGabor Marton     if (Opts.IsNaiveCTUEnabled && CTUCtx.isImportedAsNew(Decl)) {
52856b9b97cSGabor Marton       // A newly created definition, but we had error(s) during the import.
52956b9b97cSGabor Marton       if (CTUCtx.hasError(Decl))
53056b9b97cSGabor Marton         return {};
53156b9b97cSGabor Marton       return RuntimeDefinition(Decl, /*Foreign=*/true);
53256b9b97cSGabor Marton     }
53356b9b97cSGabor Marton     return RuntimeDefinition(Decl, /*Foreign=*/false);
53456b9b97cSGabor Marton   }
53556b9b97cSGabor Marton 
5368b9b3bd0SIlya Biryukov   // Try to get CTU definition only if CTUDir is provided.
537549f9cd4SKristof Umann   if (!Opts.IsNaiveCTUEnabled)
538ca7923abSGabor Horvath     return {};
5398b9b3bd0SIlya Biryukov 
5408b9b3bd0SIlya Biryukov   llvm::Expected<const FunctionDecl *> CTUDeclOrError =
5419419eb42SGabor Marton       CTUCtx.getCrossTUDefinition(FD, Opts.CTUDir, Opts.CTUIndexName,
5429419eb42SGabor Marton                                   Opts.DisplayCTUProgress);
5438b9b3bd0SIlya Biryukov 
5448b9b3bd0SIlya Biryukov   if (!CTUDeclOrError) {
5458b9b3bd0SIlya Biryukov     handleAllErrors(CTUDeclOrError.takeError(),
5468b9b3bd0SIlya Biryukov                     [&](const cross_tu::IndexError &IE) {
5478b9b3bd0SIlya Biryukov                       CTUCtx.emitCrossTUDiagnostics(IE);
5488b9b3bd0SIlya Biryukov                     });
5495bc81eb9SEugene Zelenko     return {};
5507b9cf1c4SGeorge Karpenkov   }
5517b9cf1c4SGeorge Karpenkov 
55256b9b97cSGabor Marton   return RuntimeDefinition(*CTUDeclOrError, /*Foreign=*/true);
5538b9b3bd0SIlya Biryukov }
5548b9b3bd0SIlya Biryukov 
getInitialStackFrameContents(const StackFrameContext * CalleeCtx,BindingsTy & Bindings) const55542e8d649SJordan Rose void AnyFunctionCall::getInitialStackFrameContents(
55642e8d649SJordan Rose                                         const StackFrameContext *CalleeCtx,
55742e8d649SJordan Rose                                         BindingsTy &Bindings) const {
5585bc81eb9SEugene Zelenko   const auto *D = cast<FunctionDecl>(CalleeCtx->getDecl());
55942e8d649SJordan Rose   SValBuilder &SVB = getState()->getStateManager().getSValBuilder();
56042e8d649SJordan Rose   addParameterValuesToBindings(CalleeCtx, Bindings, SVB, *this,
5612ff16004STed Kremenek                                D->parameters());
5624f7df9beSJordan Rose }
5634f7df9beSJordan Rose 
argumentsMayEscape() const5644f7df9beSJordan Rose bool AnyFunctionCall::argumentsMayEscape() const {
565fe1eca51SAnna Zaks   if (CallEvent::argumentsMayEscape() || hasVoidPointerToNonConstArg())
5664f7df9beSJordan Rose     return true;
5674f7df9beSJordan Rose 
5684f7df9beSJordan Rose   const FunctionDecl *D = getDecl();
5694f7df9beSJordan Rose   if (!D)
5704f7df9beSJordan Rose     return true;
5714f7df9beSJordan Rose 
5724f7df9beSJordan Rose   const IdentifierInfo *II = D->getIdentifier();
5734f7df9beSJordan Rose   if (!II)
5747bd0674dSAnna Zaks     return false;
5754f7df9beSJordan Rose 
5764f7df9beSJordan Rose   // This set of "escaping" APIs is
5774f7df9beSJordan Rose 
5784f7df9beSJordan Rose   // - 'int pthread_setspecific(ptheread_key k, const void *)' stores a
5794f7df9beSJordan Rose   //   value into thread local storage. The value can later be retrieved with
5804f7df9beSJordan Rose   //   'void *ptheread_getspecific(pthread_key)'. So even thought the
5814f7df9beSJordan Rose   //   parameter is 'const void *', the region escapes through the call.
5824f7df9beSJordan Rose   if (II->isStr("pthread_setspecific"))
5834f7df9beSJordan Rose     return true;
5844f7df9beSJordan Rose 
5854f7df9beSJordan Rose   // - xpc_connection_set_context stores a value which can be retrieved later
5864f7df9beSJordan Rose   //   with xpc_connection_get_context.
5874f7df9beSJordan Rose   if (II->isStr("xpc_connection_set_context"))
5884f7df9beSJordan Rose     return true;
5894f7df9beSJordan Rose 
5904f7df9beSJordan Rose   // - funopen - sets a buffer for future IO calls.
5914f7df9beSJordan Rose   if (II->isStr("funopen"))
5924f7df9beSJordan Rose     return true;
5934f7df9beSJordan Rose 
59444cdeb1dSAnna Zaks   // - __cxa_demangle - can reallocate memory and can return the pointer to
59544cdeb1dSAnna Zaks   // the input buffer.
59644cdeb1dSAnna Zaks   if (II->isStr("__cxa_demangle"))
59744cdeb1dSAnna Zaks     return true;
59844cdeb1dSAnna Zaks 
5994f7df9beSJordan Rose   StringRef FName = II->getName();
6004f7df9beSJordan Rose 
6014f7df9beSJordan Rose   // - CoreFoundation functions that end with "NoCopy" can free a passed-in
6024f7df9beSJordan Rose   //   buffer even if it is const.
6034f7df9beSJordan Rose   if (FName.endswith("NoCopy"))
6044f7df9beSJordan Rose     return true;
6054f7df9beSJordan Rose 
6064f7df9beSJordan Rose   // - NSXXInsertXX, for example NSMapInsertIfAbsent, since they can
6074f7df9beSJordan Rose   //   be deallocated by NSMapRemove.
6080abb5d29SKazu Hirata   if (FName.startswith("NS") && FName.contains("Insert"))
6094f7df9beSJordan Rose     return true;
6104f7df9beSJordan Rose 
6114f7df9beSJordan Rose   // - Many CF containers allow objects to escape through custom
6124f7df9beSJordan Rose   //   allocators/deallocators upon container construction. (PR12101)
6134f7df9beSJordan Rose   if (FName.startswith("CF") || FName.startswith("CG")) {
6144f7df9beSJordan Rose     return StrInStrNoCase(FName, "InsertValue")  != StringRef::npos ||
6154f7df9beSJordan Rose            StrInStrNoCase(FName, "AddValue")     != StringRef::npos ||
6164f7df9beSJordan Rose            StrInStrNoCase(FName, "SetValue")     != StringRef::npos ||
6174f7df9beSJordan Rose            StrInStrNoCase(FName, "WithData")     != StringRef::npos ||
6184f7df9beSJordan Rose            StrInStrNoCase(FName, "AppendValue")  != StringRef::npos ||
6194f7df9beSJordan Rose            StrInStrNoCase(FName, "SetAttribute") != StringRef::npos;
6204f7df9beSJordan Rose   }
6214f7df9beSJordan Rose 
6224f7df9beSJordan Rose   return false;
6234f7df9beSJordan Rose }
6244f7df9beSJordan Rose 
getDecl() const6252a833ca5SJordan Rose const FunctionDecl *SimpleFunctionCall::getDecl() const {
6264f7df9beSJordan Rose   const FunctionDecl *D = getOriginExpr()->getDirectCallee();
6274f7df9beSJordan Rose   if (D)
6284f7df9beSJordan Rose     return D;
6294f7df9beSJordan Rose 
6304f7df9beSJordan Rose   return getSVal(getOriginExpr()->getCallee()).getAsFunctionDecl();
6314f7df9beSJordan Rose }
6324f7df9beSJordan Rose 
getDecl() const633ce6c99a5SJordan Rose const FunctionDecl *CXXInstanceCall::getDecl() const {
6345bc81eb9SEugene Zelenko   const auto *CE = cast_or_null<CallExpr>(getOriginExpr());
635ce6c99a5SJordan Rose   if (!CE)
636ce6c99a5SJordan Rose     return AnyFunctionCall::getDecl();
637ce6c99a5SJordan Rose 
638ce6c99a5SJordan Rose   const FunctionDecl *D = CE->getDirectCallee();
639ce6c99a5SJordan Rose   if (D)
640ce6c99a5SJordan Rose     return D;
641ce6c99a5SJordan Rose 
642ce6c99a5SJordan Rose   return getSVal(CE->getCallee()).getAsFunctionDecl();
643ce6c99a5SJordan Rose }
644ce6c99a5SJordan Rose 
getExtraInvalidatedValues(ValueList & Values,RegionAndSymbolInvalidationTraits * ETraits) const64500e780e1SSean Eveson void CXXInstanceCall::getExtraInvalidatedValues(
64600e780e1SSean Eveson     ValueList &Values, RegionAndSymbolInvalidationTraits *ETraits) const {
6474f770deeSDevin Coughlin   SVal ThisVal = getCXXThisVal();
6484f770deeSDevin Coughlin   Values.push_back(ThisVal);
6494f770deeSDevin Coughlin 
6503f072ef8SSean Eveson   // Don't invalidate if the method is const and there are no mutable fields.
6515bc81eb9SEugene Zelenko   if (const auto *D = cast_or_null<CXXMethodDecl>(getDecl())) {
6524f770deeSDevin Coughlin     if (!D->isConst())
6534f770deeSDevin Coughlin       return;
6544f770deeSDevin Coughlin     // Get the record decl for the class of 'This'. D->getParent() may return a
6554f770deeSDevin Coughlin     // base class decl, rather than the class of the instance which needs to be
6564f770deeSDevin Coughlin     // checked for mutable fields.
657f74ef4b1SArtem Dergachev     // TODO: We might as well look at the dynamic type of the object.
6581a7a2cd7SEduardo Caldas     const Expr *Ex = getCXXThisExpr()->IgnoreParenBaseCasts();
659f74ef4b1SArtem Dergachev     QualType T = Ex->getType();
660f74ef4b1SArtem Dergachev     if (T->isPointerType()) // Arrow or implicit-this syntax?
661f74ef4b1SArtem Dergachev       T = T->getPointeeType();
662f74ef4b1SArtem Dergachev     const CXXRecordDecl *ParentRecord = T->getAsCXXRecordDecl();
663f74ef4b1SArtem Dergachev     assert(ParentRecord);
664f74ef4b1SArtem Dergachev     if (ParentRecord->hasMutableFields())
6654f770deeSDevin Coughlin       return;
6664f770deeSDevin Coughlin     // Preserve CXXThis.
6674f770deeSDevin Coughlin     const MemRegion *ThisRegion = ThisVal.getAsRegion();
6689c76869bSDevin Coughlin     if (!ThisRegion)
6699c76869bSDevin Coughlin       return;
6709c76869bSDevin Coughlin 
6714f770deeSDevin Coughlin     ETraits->setTrait(ThisRegion->getBaseRegion(),
6724f770deeSDevin Coughlin                       RegionAndSymbolInvalidationTraits::TK_PreserveContents);
6734f770deeSDevin Coughlin   }
6744f7df9beSJordan Rose }
6754f7df9beSJordan Rose 
getCXXThisVal() const676fcdda361SJordan Rose SVal CXXInstanceCall::getCXXThisVal() const {
677fcdda361SJordan Rose   const Expr *Base = getCXXThisExpr();
678fcdda361SJordan Rose   // FIXME: This doesn't handle an overloaded ->* operator.
679fcdda361SJordan Rose   if (!Base)
680fcdda361SJordan Rose     return UnknownVal();
681fcdda361SJordan Rose 
682fcdda361SJordan Rose   SVal ThisVal = getSVal(Base);
68396ccb690SBalazs Benics   assert(ThisVal.isUnknownOrUndef() || isa<Loc>(ThisVal));
684fcdda361SJordan Rose   return ThisVal;
685fcdda361SJordan Rose }
686fcdda361SJordan Rose 
getRuntimeDefinition() const687089c5510STed Kremenek RuntimeDefinition CXXInstanceCall::getRuntimeDefinition() const {
6880f6d63beSJordan Rose   // Do we have a decl at all?
68951bcb226SJordan Rose   const Decl *D = getDecl();
6904f7df9beSJordan Rose   if (!D)
6915bc81eb9SEugene Zelenko     return {};
6924f7df9beSJordan Rose 
6930f6d63beSJordan Rose   // If the method is non-virtual, we know we can inline it.
6945bc81eb9SEugene Zelenko   const auto *MD = cast<CXXMethodDecl>(D);
6954f7df9beSJordan Rose   if (!MD->isVirtual())
696089c5510STed Kremenek     return AnyFunctionCall::getRuntimeDefinition();
6974f7df9beSJordan Rose 
6980f6d63beSJordan Rose   // Do we know the implicit 'this' object being called?
6990f6d63beSJordan Rose   const MemRegion *R = getCXXThisVal().getAsRegion();
7000f6d63beSJordan Rose   if (!R)
7015bc81eb9SEugene Zelenko     return {};
7020f6d63beSJordan Rose 
7030f6d63beSJordan Rose   // Do we know anything about the type of 'this'?
7044df9d812SGabor Horvath   DynamicTypeInfo DynType = getDynamicTypeInfo(getState(), R);
7050f6d63beSJordan Rose   if (!DynType.isValid())
7065bc81eb9SEugene Zelenko     return {};
7070f6d63beSJordan Rose 
7080f6d63beSJordan Rose   // Is the type a C++ class? (This is mostly a defensive check.)
7090f6d63beSJordan Rose   QualType RegionType = DynType.getType()->getPointeeType();
710d1a08b6eSJordan Rose   assert(!RegionType.isNull() && "DynamicTypeInfo should always be a pointer.");
711d1a08b6eSJordan Rose 
7120f6d63beSJordan Rose   const CXXRecordDecl *RD = RegionType->getAsCXXRecordDecl();
71399107208SJordan Rose   if (!RD || !RD->hasDefinition())
7145bc81eb9SEugene Zelenko     return {};
7150f6d63beSJordan Rose 
71699c6c2b4SJordan Rose   // Find the decl for this method in that class.
71799c6c2b4SJordan Rose   const CXXMethodDecl *Result = MD->getCorrespondingMethodInClass(RD, true);
71881456d9fSJordan Rose   if (!Result) {
71981456d9fSJordan Rose     // We might not even get the original statically-resolved method due to
72081456d9fSJordan Rose     // some particularly nasty casting (e.g. casts to sister classes).
72181456d9fSJordan Rose     // However, we should at least be able to search up and down our own class
72281456d9fSJordan Rose     // hierarchy, and some real bugs have been caught by checking this.
72381456d9fSJordan Rose     assert(!RD->isDerivedFrom(MD->getParent()) && "Couldn't find known method");
724d44977efSJordan Rose 
725d44977efSJordan Rose     // FIXME: This is checking that our DynamicTypeInfo is at least as good as
726d44977efSJordan Rose     // the static type. However, because we currently don't update
727d44977efSJordan Rose     // DynamicTypeInfo when an object is cast, we can't actually be sure the
728d44977efSJordan Rose     // DynamicTypeInfo is up to date. This assert should be re-enabled once
729d44977efSJordan Rose     // this is fixed. <rdar://problem/12287087>
730d44977efSJordan Rose     //assert(!MD->getParent()->isDerivedFrom(RD) && "Bad DynamicTypeInfo");
731d44977efSJordan Rose 
7325bc81eb9SEugene Zelenko     return {};
73381456d9fSJordan Rose   }
7340f6d63beSJordan Rose 
7350f6d63beSJordan Rose   // Does the decl that we found have an implementation?
7360f6d63beSJordan Rose   const FunctionDecl *Definition;
737e712295fSGabor Marton   if (!Result->hasBody(Definition)) {
738e712295fSGabor Marton     if (!DynType.canBeASubClass())
739e712295fSGabor Marton       return AnyFunctionCall::getRuntimeDefinition();
7405bc81eb9SEugene Zelenko     return {};
741e712295fSGabor Marton   }
7420f6d63beSJordan Rose 
7430f6d63beSJordan Rose   // We found a definition. If we're not sure that this devirtualization is
7440f6d63beSJordan Rose   // actually what will happen at runtime, make sure to provide the region so
7450f6d63beSJordan Rose   // that ExprEngine can decide what to do with it.
7460f6d63beSJordan Rose   if (DynType.canBeASubClass())
7470f6d63beSJordan Rose     return RuntimeDefinition(Definition, R->StripCasts());
7480dbb783cSCraig Topper   return RuntimeDefinition(Definition, /*DispatchRegion=*/nullptr);
7494f7df9beSJordan Rose }
7504f7df9beSJordan Rose 
getInitialStackFrameContents(const StackFrameContext * CalleeCtx,BindingsTy & Bindings) const75142e8d649SJordan Rose void CXXInstanceCall::getInitialStackFrameContents(
75242e8d649SJordan Rose                                             const StackFrameContext *CalleeCtx,
75342e8d649SJordan Rose                                             BindingsTy &Bindings) const {
75442e8d649SJordan Rose   AnyFunctionCall::getInitialStackFrameContents(CalleeCtx, Bindings);
75542e8d649SJordan Rose 
75602e5309bSJordan Rose   // Handle the binding of 'this' in the new stack frame.
75742e8d649SJordan Rose   SVal ThisVal = getCXXThisVal();
75842e8d649SJordan Rose   if (!ThisVal.isUnknown()) {
75902e5309bSJordan Rose     ProgramStateManager &StateMgr = getState()->getStateManager();
76002e5309bSJordan Rose     SValBuilder &SVB = StateMgr.getSValBuilder();
76102e5309bSJordan Rose 
7625bc81eb9SEugene Zelenko     const auto *MD = cast<CXXMethodDecl>(CalleeCtx->getDecl());
76342e8d649SJordan Rose     Loc ThisLoc = SVB.getCXXThis(MD, CalleeCtx);
76402e5309bSJordan Rose 
76531c3fa9cSJordan Rose     // If we devirtualized to a different member function, we need to make sure
76631c3fa9cSJordan Rose     // we have the proper layering of CXXBaseObjectRegions.
76731c3fa9cSJordan Rose     if (MD->getCanonicalDecl() != getDecl()->getCanonicalDecl()) {
768710f6b12SJordan Rose       ASTContext &Ctx = SVB.getContext();
76902e5309bSJordan Rose       const CXXRecordDecl *Class = MD->getParent();
770710f6b12SJordan Rose       QualType Ty = Ctx.getPointerType(Ctx.getRecordType(Class));
77102e5309bSJordan Rose 
772710f6b12SJordan Rose       // FIXME: CallEvent maybe shouldn't be directly accessing StoreManager.
773da8bd972SDenys Petrov       Optional<SVal> V =
774da8bd972SDenys Petrov           StateMgr.getStoreManager().evalBaseToDerived(ThisVal, Ty);
775452db157SKazu Hirata       if (!V) {
776f01831ebSArtem Dergachev         // We might have suffered some sort of placement new earlier, so
777f01831ebSArtem Dergachev         // we're constructing in a completely unexpected storage.
778f01831ebSArtem Dergachev         // Fall back to a generic pointer cast for this-value.
779f01831ebSArtem Dergachev         const CXXMethodDecl *StaticMD = cast<CXXMethodDecl>(getDecl());
780f01831ebSArtem Dergachev         const CXXRecordDecl *StaticClass = StaticMD->getParent();
781f01831ebSArtem Dergachev         QualType StaticTy = Ctx.getPointerType(Ctx.getRecordType(StaticClass));
782f01831ebSArtem Dergachev         ThisVal = SVB.evalCast(ThisVal, Ty, StaticTy);
783da8bd972SDenys Petrov       } else
784da8bd972SDenys Petrov         ThisVal = *V;
78502e5309bSJordan Rose     }
78602e5309bSJordan Rose 
78731c3fa9cSJordan Rose     if (!ThisVal.isUnknown())
78842e8d649SJordan Rose       Bindings.push_back(std::make_pair(ThisLoc, ThisVal));
78942e8d649SJordan Rose   }
79042e8d649SJordan Rose }
79142e8d649SJordan Rose 
getCXXThisExpr() const79292e1449bSJordan Rose const Expr *CXXMemberCall::getCXXThisExpr() const {
79392e1449bSJordan Rose   return getOriginExpr()->getImplicitObjectArgument();
7944f7df9beSJordan Rose }
7954f7df9beSJordan Rose 
getRuntimeDefinition() const796089c5510STed Kremenek RuntimeDefinition CXXMemberCall::getRuntimeDefinition() const {
79712f669e3SJordan Rose   // C++11 [expr.call]p1: ...If the selected function is non-virtual, or if the
79812f669e3SJordan Rose   // id-expression in the class member access expression is a qualified-id,
79912f669e3SJordan Rose   // that function is called. Otherwise, its final overrider in the dynamic type
80012f669e3SJordan Rose   // of the object expression is called.
8015bc81eb9SEugene Zelenko   if (const auto *ME = dyn_cast<MemberExpr>(getOriginExpr()->getCallee()))
80212f669e3SJordan Rose     if (ME->hasQualifier())
803089c5510STed Kremenek       return AnyFunctionCall::getRuntimeDefinition();
80412f669e3SJordan Rose 
805089c5510STed Kremenek   return CXXInstanceCall::getRuntimeDefinition();
80612f669e3SJordan Rose }
80712f669e3SJordan Rose 
getCXXThisExpr() const80892e1449bSJordan Rose const Expr *CXXMemberOperatorCall::getCXXThisExpr() const {
80992e1449bSJordan Rose   return getOriginExpr()->getArg(0);
8104f7df9beSJordan Rose }
8114f7df9beSJordan Rose 
getBlockRegion() const8124f7df9beSJordan Rose const BlockDataRegion *BlockCall::getBlockRegion() const {
8134f7df9beSJordan Rose   const Expr *Callee = getOriginExpr()->getCallee();
8144f7df9beSJordan Rose   const MemRegion *DataReg = getSVal(Callee).getAsRegion();
8154f7df9beSJordan Rose 
8164f7df9beSJordan Rose   return dyn_cast_or_null<BlockDataRegion>(DataReg);
8174f7df9beSJordan Rose }
8184f7df9beSJordan Rose 
parameters() const8192ff16004STed Kremenek ArrayRef<ParmVarDecl*> BlockCall::parameters() const {
8202a833ca5SJordan Rose   const BlockDecl *D = getDecl();
8214f7df9beSJordan Rose   if (!D)
82246f34624SArtem Dergachev     return None;
8232ff16004STed Kremenek   return D->parameters();
8244f7df9beSJordan Rose }
8254f7df9beSJordan Rose 
getExtraInvalidatedValues(ValueList & Values,RegionAndSymbolInvalidationTraits * ETraits) const8264f770deeSDevin Coughlin void BlockCall::getExtraInvalidatedValues(ValueList &Values,
8274f770deeSDevin Coughlin                   RegionAndSymbolInvalidationTraits *ETraits) const {
8284f7df9beSJordan Rose   // FIXME: This also needs to invalidate captured globals.
8294f7df9beSJordan Rose   if (const MemRegion *R = getBlockRegion())
83060bf5f45SAnna Zaks     Values.push_back(loc::MemRegionVal(R));
8314f7df9beSJordan Rose }
8324f7df9beSJordan Rose 
getInitialStackFrameContents(const StackFrameContext * CalleeCtx,BindingsTy & Bindings) const83342e8d649SJordan Rose void BlockCall::getInitialStackFrameContents(const StackFrameContext *CalleeCtx,
83442e8d649SJordan Rose                                              BindingsTy &Bindings) const {
83542e8d649SJordan Rose   SValBuilder &SVB = getState()->getStateManager().getSValBuilder();
836ebeed880SDevin Coughlin   ArrayRef<ParmVarDecl*> Params;
837ebeed880SDevin Coughlin   if (isConversionFromLambda()) {
838ebeed880SDevin Coughlin     auto *LambdaOperatorDecl = cast<CXXMethodDecl>(CalleeCtx->getDecl());
839ebeed880SDevin Coughlin     Params = LambdaOperatorDecl->parameters();
840ebeed880SDevin Coughlin 
841ebeed880SDevin Coughlin     // For blocks converted from a C++ lambda, the callee declaration is the
8425690454bSSanjay Patel     // operator() method on the lambda so we bind "this" to
843ebeed880SDevin Coughlin     // the lambda captured by the block.
844ebeed880SDevin Coughlin     const VarRegion *CapturedLambdaRegion = getRegionStoringCapturedLambda();
845ebeed880SDevin Coughlin     SVal ThisVal = loc::MemRegionVal(CapturedLambdaRegion);
846ebeed880SDevin Coughlin     Loc ThisLoc = SVB.getCXXThis(LambdaOperatorDecl, CalleeCtx);
847ebeed880SDevin Coughlin     Bindings.push_back(std::make_pair(ThisLoc, ThisVal));
848ebeed880SDevin Coughlin   } else {
849ebeed880SDevin Coughlin     Params = cast<BlockDecl>(CalleeCtx->getDecl())->parameters();
850ebeed880SDevin Coughlin   }
851ebeed880SDevin Coughlin 
85242e8d649SJordan Rose   addParameterValuesToBindings(CalleeCtx, Bindings, SVB, *this,
853ebeed880SDevin Coughlin                                Params);
85442e8d649SJordan Rose }
85542e8d649SJordan Rose 
getCXXThisVal() const856a82ffe9dSArtem Dergachev SVal AnyCXXConstructorCall::getCXXThisVal() const {
8574f7df9beSJordan Rose   if (Data)
8584f7df9beSJordan Rose     return loc::MemRegionVal(static_cast<const MemRegion *>(Data));
8594f7df9beSJordan Rose   return UnknownVal();
8604f7df9beSJordan Rose }
8614f7df9beSJordan Rose 
getExtraInvalidatedValues(ValueList & Values,RegionAndSymbolInvalidationTraits * ETraits) const862a82ffe9dSArtem Dergachev void AnyCXXConstructorCall::getExtraInvalidatedValues(ValueList &Values,
8634f770deeSDevin Coughlin                            RegionAndSymbolInvalidationTraits *ETraits) const {
864a82ffe9dSArtem Dergachev   SVal V = getCXXThisVal();
865a82ffe9dSArtem Dergachev   if (SymbolRef Sym = V.getAsSymbol(true))
8660c79eab0SArtem Dergachev     ETraits->setTrait(Sym,
8670c79eab0SArtem Dergachev                       RegionAndSymbolInvalidationTraits::TK_SuppressEscape);
868a82ffe9dSArtem Dergachev   Values.push_back(V);
8694f7df9beSJordan Rose }
8704f7df9beSJordan Rose 
getInitialStackFrameContents(const StackFrameContext * CalleeCtx,BindingsTy & Bindings) const871a82ffe9dSArtem Dergachev void AnyCXXConstructorCall::getInitialStackFrameContents(
87242e8d649SJordan Rose                                              const StackFrameContext *CalleeCtx,
87342e8d649SJordan Rose                                              BindingsTy &Bindings) const {
87442e8d649SJordan Rose   AnyFunctionCall::getInitialStackFrameContents(CalleeCtx, Bindings);
87542e8d649SJordan Rose 
87642e8d649SJordan Rose   SVal ThisVal = getCXXThisVal();
87742e8d649SJordan Rose   if (!ThisVal.isUnknown()) {
87842e8d649SJordan Rose     SValBuilder &SVB = getState()->getStateManager().getSValBuilder();
8795bc81eb9SEugene Zelenko     const auto *MD = cast<CXXMethodDecl>(CalleeCtx->getDecl());
88042e8d649SJordan Rose     Loc ThisLoc = SVB.getCXXThis(MD, CalleeCtx);
88142e8d649SJordan Rose     Bindings.push_back(std::make_pair(ThisLoc, ThisVal));
88242e8d649SJordan Rose   }
88342e8d649SJordan Rose }
88442e8d649SJordan Rose 
885a82ffe9dSArtem Dergachev const StackFrameContext *
getInheritingStackFrame() const886a82ffe9dSArtem Dergachev CXXInheritedConstructorCall::getInheritingStackFrame() const {
887a82ffe9dSArtem Dergachev   const StackFrameContext *SFC = getLocationContext()->getStackFrame();
888a82ffe9dSArtem Dergachev   while (isa<CXXInheritedCtorInitExpr>(SFC->getCallSite()))
889a82ffe9dSArtem Dergachev     SFC = SFC->getParent()->getStackFrame();
890a82ffe9dSArtem Dergachev   return SFC;
891a82ffe9dSArtem Dergachev }
892a82ffe9dSArtem Dergachev 
getCXXThisVal() const8934f7df9beSJordan Rose SVal CXXDestructorCall::getCXXThisVal() const {
8944f7df9beSJordan Rose   if (Data)
8952bc9674bSJordan Rose     return loc::MemRegionVal(DtorDataTy::getFromOpaqueValue(Data).getPointer());
8964f7df9beSJordan Rose   return UnknownVal();
8974f7df9beSJordan Rose }
8984f7df9beSJordan Rose 
getRuntimeDefinition() const899089c5510STed Kremenek RuntimeDefinition CXXDestructorCall::getRuntimeDefinition() const {
9002bc9674bSJordan Rose   // Base destructors are always called non-virtually.
9012bc9674bSJordan Rose   // Skip CXXInstanceCall's devirtualization logic in this case.
9022bc9674bSJordan Rose   if (isBaseDestructor())
903089c5510STed Kremenek     return AnyFunctionCall::getRuntimeDefinition();
9042bc9674bSJordan Rose 
905089c5510STed Kremenek   return CXXInstanceCall::getRuntimeDefinition();
9062bc9674bSJordan Rose }
9072bc9674bSJordan Rose 
parameters() const9082ff16004STed Kremenek ArrayRef<ParmVarDecl*> ObjCMethodCall::parameters() const {
90942e8d649SJordan Rose   const ObjCMethodDecl *D = getDecl();
9104f7df9beSJordan Rose   if (!D)
9115fc8fc2dSCraig Topper     return None;
9122ff16004STed Kremenek   return D->parameters();
9134f7df9beSJordan Rose }
9144f7df9beSJordan Rose 
getExtraInvalidatedValues(ValueList & Values,RegionAndSymbolInvalidationTraits * ETraits) const915069a1073SDevin Coughlin void ObjCMethodCall::getExtraInvalidatedValues(
916069a1073SDevin Coughlin     ValueList &Values, RegionAndSymbolInvalidationTraits *ETraits) const {
917069a1073SDevin Coughlin 
918069a1073SDevin Coughlin   // If the method call is a setter for property known to be backed by
919069a1073SDevin Coughlin   // an instance variable, don't invalidate the entire receiver, just
920069a1073SDevin Coughlin   // the storage for that instance variable.
921069a1073SDevin Coughlin   if (const ObjCPropertyDecl *PropDecl = getAccessedProperty()) {
922069a1073SDevin Coughlin     if (const ObjCIvarDecl *PropIvar = PropDecl->getPropertyIvarDecl()) {
923069a1073SDevin Coughlin       SVal IvarLVal = getState()->getLValue(PropIvar, getReceiverSVal());
9245f24c12dSAlexander Shaposhnikov       if (const MemRegion *IvarRegion = IvarLVal.getAsRegion()) {
925069a1073SDevin Coughlin         ETraits->setTrait(
926069a1073SDevin Coughlin           IvarRegion,
927069a1073SDevin Coughlin           RegionAndSymbolInvalidationTraits::TK_DoNotInvalidateSuperRegion);
9285f24c12dSAlexander Shaposhnikov         ETraits->setTrait(
9295f24c12dSAlexander Shaposhnikov           IvarRegion,
930069a1073SDevin Coughlin           RegionAndSymbolInvalidationTraits::TK_SuppressEscape);
931069a1073SDevin Coughlin         Values.push_back(IvarLVal);
9325f24c12dSAlexander Shaposhnikov       }
933069a1073SDevin Coughlin       return;
934069a1073SDevin Coughlin     }
935069a1073SDevin Coughlin   }
936069a1073SDevin Coughlin 
93760bf5f45SAnna Zaks   Values.push_back(getReceiverSVal());
9384f7df9beSJordan Rose }
9394f7df9beSJordan Rose 
getReceiverSVal() const9404f7df9beSJordan Rose SVal ObjCMethodCall::getReceiverSVal() const {
9414f7df9beSJordan Rose   // FIXME: Is this the best way to handle class receivers?
9424f7df9beSJordan Rose   if (!isInstanceMessage())
9434f7df9beSJordan Rose     return UnknownVal();
9444f7df9beSJordan Rose 
945472dbcf1SAnna Zaks   if (const Expr *RecE = getOriginExpr()->getInstanceReceiver())
946472dbcf1SAnna Zaks     return getSVal(RecE);
9474f7df9beSJordan Rose 
9484f7df9beSJordan Rose   // An instance message with no expression means we are sending to super.
9494f7df9beSJordan Rose   // In this case the object reference is the same as 'self'.
9503d5d3d3eSAnna Zaks   assert(getOriginExpr()->getReceiverKind() == ObjCMessageExpr::SuperInstance);
951239c53b7SValeriy Savchenko   SVal SelfVal = getState()->getSelfSVal(getLocationContext());
9523d5d3d3eSAnna Zaks   assert(SelfVal.isValid() && "Calling super but not in ObjC method");
9533d5d3d3eSAnna Zaks   return SelfVal;
9543d5d3d3eSAnna Zaks }
9553d5d3d3eSAnna Zaks 
isReceiverSelfOrSuper() const9563d5d3d3eSAnna Zaks bool ObjCMethodCall::isReceiverSelfOrSuper() const {
9573d5d3d3eSAnna Zaks   if (getOriginExpr()->getReceiverKind() == ObjCMessageExpr::SuperInstance ||
9583d5d3d3eSAnna Zaks       getOriginExpr()->getReceiverKind() == ObjCMessageExpr::SuperClass)
9593d5d3d3eSAnna Zaks       return true;
9603d5d3d3eSAnna Zaks 
9613d5d3d3eSAnna Zaks   if (!isInstanceMessage())
9623d5d3d3eSAnna Zaks     return false;
9633d5d3d3eSAnna Zaks 
9643d5d3d3eSAnna Zaks   SVal RecVal = getSVal(getOriginExpr()->getInstanceReceiver());
965239c53b7SValeriy Savchenko   SVal SelfVal = getState()->getSelfSVal(getLocationContext());
9663d5d3d3eSAnna Zaks 
967239c53b7SValeriy Savchenko   return (RecVal == SelfVal);
9684f7df9beSJordan Rose }
9694f7df9beSJordan Rose 
getSourceRange() const9704f7df9beSJordan Rose SourceRange ObjCMethodCall::getSourceRange() const {
9714f7df9beSJordan Rose   switch (getMessageKind()) {
9724f7df9beSJordan Rose   case OCM_Message:
9734f7df9beSJordan Rose     return getOriginExpr()->getSourceRange();
9744f7df9beSJordan Rose   case OCM_PropertyAccess:
9754f7df9beSJordan Rose   case OCM_Subscript:
9764f7df9beSJordan Rose     return getContainingPseudoObjectExpr()->getSourceRange();
9774f7df9beSJordan Rose   }
9784f7df9beSJordan Rose   llvm_unreachable("unknown message kind");
9794f7df9beSJordan Rose }
9804f7df9beSJordan Rose 
9815bc81eb9SEugene Zelenko using ObjCMessageDataTy = llvm::PointerIntPair<const PseudoObjectExpr *, 2>;
9824f7df9beSJordan Rose 
getContainingPseudoObjectExpr() const9834f7df9beSJordan Rose const PseudoObjectExpr *ObjCMethodCall::getContainingPseudoObjectExpr() const {
9840dbb783cSCraig Topper   assert(Data && "Lazy lookup not yet performed.");
9854f7df9beSJordan Rose   assert(getMessageKind() != OCM_Message && "Explicit message send.");
9864f7df9beSJordan Rose   return ObjCMessageDataTy::getFromOpaqueValue(Data).getPointer();
9874f7df9beSJordan Rose }
9884f7df9beSJordan Rose 
989069a1073SDevin Coughlin static const Expr *
getSyntacticFromForPseudoObjectExpr(const PseudoObjectExpr * POE)990069a1073SDevin Coughlin getSyntacticFromForPseudoObjectExpr(const PseudoObjectExpr *POE) {
99112cbc8cbSArtem Dergachev   const Expr *Syntactic = POE->getSyntacticForm()->IgnoreParens();
992069a1073SDevin Coughlin 
993069a1073SDevin Coughlin   // This handles the funny case of assigning to the result of a getter.
994069a1073SDevin Coughlin   // This can happen if the getter returns a non-const reference.
9955bc81eb9SEugene Zelenko   if (const auto *BO = dyn_cast<BinaryOperator>(Syntactic))
99612cbc8cbSArtem Dergachev     Syntactic = BO->getLHS()->IgnoreParens();
997069a1073SDevin Coughlin 
998069a1073SDevin Coughlin   return Syntactic;
999069a1073SDevin Coughlin }
1000069a1073SDevin Coughlin 
getMessageKind() const10014f7df9beSJordan Rose ObjCMessageKind ObjCMethodCall::getMessageKind() const {
10020dbb783cSCraig Topper   if (!Data) {
1003226a56faSAnna Zaks     // Find the parent, ignoring implicit casts.
1004fc76d855SKristof Umann     const ParentMap &PM = getLocationContext()->getParentMap();
10055770c038SJordan Rose     const Stmt *S = PM.getParentIgnoreParenCasts(getOriginExpr());
1006226a56faSAnna Zaks 
1007226a56faSAnna Zaks     // Check if parent is a PseudoObjectExpr.
10085bc81eb9SEugene Zelenko     if (const auto *POE = dyn_cast_or_null<PseudoObjectExpr>(S)) {
1009069a1073SDevin Coughlin       const Expr *Syntactic = getSyntacticFromForPseudoObjectExpr(POE);
10104f7df9beSJordan Rose 
10114f7df9beSJordan Rose       ObjCMessageKind K;
10124f7df9beSJordan Rose       switch (Syntactic->getStmtClass()) {
10134f7df9beSJordan Rose       case Stmt::ObjCPropertyRefExprClass:
10144f7df9beSJordan Rose         K = OCM_PropertyAccess;
10154f7df9beSJordan Rose         break;
10164f7df9beSJordan Rose       case Stmt::ObjCSubscriptRefExprClass:
10174f7df9beSJordan Rose         K = OCM_Subscript;
10184f7df9beSJordan Rose         break;
10194f7df9beSJordan Rose       default:
10204f7df9beSJordan Rose         // FIXME: Can this ever happen?
10214f7df9beSJordan Rose         K = OCM_Message;
10224f7df9beSJordan Rose         break;
10234f7df9beSJordan Rose       }
10244f7df9beSJordan Rose 
10254f7df9beSJordan Rose       if (K != OCM_Message) {
10264f7df9beSJordan Rose         const_cast<ObjCMethodCall *>(this)->Data
10274f7df9beSJordan Rose           = ObjCMessageDataTy(POE, K).getOpaqueValue();
10284f7df9beSJordan Rose         assert(getMessageKind() == K);
10294f7df9beSJordan Rose         return K;
10304f7df9beSJordan Rose       }
10314f7df9beSJordan Rose     }
10324f7df9beSJordan Rose 
10334f7df9beSJordan Rose     const_cast<ObjCMethodCall *>(this)->Data
10340dbb783cSCraig Topper       = ObjCMessageDataTy(nullptr, 1).getOpaqueValue();
10354f7df9beSJordan Rose     assert(getMessageKind() == OCM_Message);
10364f7df9beSJordan Rose     return OCM_Message;
10374f7df9beSJordan Rose   }
10384f7df9beSJordan Rose 
10394f7df9beSJordan Rose   ObjCMessageDataTy Info = ObjCMessageDataTy::getFromOpaqueValue(Data);
10404f7df9beSJordan Rose   if (!Info.getPointer())
10414f7df9beSJordan Rose     return OCM_Message;
10424f7df9beSJordan Rose   return static_cast<ObjCMessageKind>(Info.getInt());
10434f7df9beSJordan Rose }
10444f7df9beSJordan Rose 
getAccessedProperty() const1045069a1073SDevin Coughlin const ObjCPropertyDecl *ObjCMethodCall::getAccessedProperty() const {
1046069a1073SDevin Coughlin   // Look for properties accessed with property syntax (foo.bar = ...)
1047069a1073SDevin Coughlin   if (getMessageKind() == OCM_PropertyAccess) {
1048069a1073SDevin Coughlin     const PseudoObjectExpr *POE = getContainingPseudoObjectExpr();
1049069a1073SDevin Coughlin     assert(POE && "Property access without PseudoObjectExpr?");
1050069a1073SDevin Coughlin 
1051069a1073SDevin Coughlin     const Expr *Syntactic = getSyntacticFromForPseudoObjectExpr(POE);
1052069a1073SDevin Coughlin     auto *RefExpr = cast<ObjCPropertyRefExpr>(Syntactic);
1053069a1073SDevin Coughlin 
1054069a1073SDevin Coughlin     if (RefExpr->isExplicitProperty())
1055069a1073SDevin Coughlin       return RefExpr->getExplicitProperty();
1056069a1073SDevin Coughlin   }
1057069a1073SDevin Coughlin 
1058069a1073SDevin Coughlin   // Look for properties accessed with method syntax ([foo setBar:...]).
1059069a1073SDevin Coughlin   const ObjCMethodDecl *MD = getDecl();
1060069a1073SDevin Coughlin   if (!MD || !MD->isPropertyAccessor())
1061069a1073SDevin Coughlin     return nullptr;
1062069a1073SDevin Coughlin 
1063069a1073SDevin Coughlin   // Note: This is potentially quite slow.
1064069a1073SDevin Coughlin   return MD->findPropertyDecl();
1065069a1073SDevin Coughlin }
1066920af014SAnna Zaks 
canBeOverridenInSubclass(ObjCInterfaceDecl * IDecl,Selector Sel) const1067920af014SAnna Zaks bool ObjCMethodCall::canBeOverridenInSubclass(ObjCInterfaceDecl *IDecl,
1068920af014SAnna Zaks                                              Selector Sel) const {
1069920af014SAnna Zaks   assert(IDecl);
1070516837f2SArtem Dergachev   AnalysisManager &AMgr =
107121aa8db6SGabor Horvath       getState()->getStateManager().getOwningEngine().getAnalysisManager();
1072920af014SAnna Zaks   // If the class interface is declared inside the main file, assume it is not
1073920af014SAnna Zaks   // subcassed.
1074920af014SAnna Zaks   // TODO: It could actually be subclassed if the subclass is private as well.
1075920af014SAnna Zaks   // This is probably very rare.
1076920af014SAnna Zaks   SourceLocation InterfLoc = IDecl->getEndOfDefinitionLoc();
1077516837f2SArtem Dergachev   if (InterfLoc.isValid() && AMgr.isInCodeFile(InterfLoc))
1078920af014SAnna Zaks     return false;
1079920af014SAnna Zaks 
10806ddb6b1aSAnna Zaks   // Assume that property accessors are not overridden.
10816ddb6b1aSAnna Zaks   if (getMessageKind() == OCM_PropertyAccess)
10826ddb6b1aSAnna Zaks     return false;
1083920af014SAnna Zaks 
1084920af014SAnna Zaks   // We assume that if the method is public (declared outside of main file) or
1085920af014SAnna Zaks   // has a parent which publicly declares the method, the method could be
1086920af014SAnna Zaks   // overridden in a subclass.
1087920af014SAnna Zaks 
1088920af014SAnna Zaks   // Find the first declaration in the class hierarchy that declares
1089920af014SAnna Zaks   // the selector.
10900dbb783cSCraig Topper   ObjCMethodDecl *D = nullptr;
1091920af014SAnna Zaks   while (true) {
1092920af014SAnna Zaks     D = IDecl->lookupMethod(Sel, true);
1093920af014SAnna Zaks 
1094920af014SAnna Zaks     // Cannot find a public definition.
1095920af014SAnna Zaks     if (!D)
1096920af014SAnna Zaks       return false;
1097920af014SAnna Zaks 
1098920af014SAnna Zaks     // If outside the main file,
1099516837f2SArtem Dergachev     if (D->getLocation().isValid() && !AMgr.isInCodeFile(D->getLocation()))
1100920af014SAnna Zaks       return true;
1101920af014SAnna Zaks 
1102920af014SAnna Zaks     if (D->isOverriding()) {
1103920af014SAnna Zaks       // Search in the superclass on the next iteration.
1104920af014SAnna Zaks       IDecl = D->getClassInterface();
1105920af014SAnna Zaks       if (!IDecl)
1106920af014SAnna Zaks         return false;
1107920af014SAnna Zaks 
1108920af014SAnna Zaks       IDecl = IDecl->getSuperClass();
1109920af014SAnna Zaks       if (!IDecl)
1110920af014SAnna Zaks         return false;
1111920af014SAnna Zaks 
1112920af014SAnna Zaks       continue;
1113920af014SAnna Zaks     }
1114920af014SAnna Zaks 
1115920af014SAnna Zaks     return false;
1116920af014SAnna Zaks   };
1117920af014SAnna Zaks 
1118920af014SAnna Zaks   llvm_unreachable("The while loop should always terminate.");
1119920af014SAnna Zaks }
1120920af014SAnna Zaks 
findDefiningRedecl(const ObjCMethodDecl * MD)1121dcfc1914SAnna Zaks static const ObjCMethodDecl *findDefiningRedecl(const ObjCMethodDecl *MD) {
1122dcfc1914SAnna Zaks   if (!MD)
1123dcfc1914SAnna Zaks     return MD;
1124dcfc1914SAnna Zaks 
1125dcfc1914SAnna Zaks   // Find the redeclaration that defines the method.
1126dcfc1914SAnna Zaks   if (!MD->hasBody()) {
1127dcfc1914SAnna Zaks     for (auto I : MD->redecls())
1128dcfc1914SAnna Zaks       if (I->hasBody())
1129dcfc1914SAnna Zaks         MD = cast<ObjCMethodDecl>(I);
1130dcfc1914SAnna Zaks   }
1131dcfc1914SAnna Zaks   return MD;
1132dcfc1914SAnna Zaks }
1133dcfc1914SAnna Zaks 
1134239c53b7SValeriy Savchenko struct PrivateMethodKey {
1135239c53b7SValeriy Savchenko   const ObjCInterfaceDecl *Interface;
1136239c53b7SValeriy Savchenko   Selector LookupSelector;
1137239c53b7SValeriy Savchenko   bool IsClassMethod;
1138239c53b7SValeriy Savchenko };
1139dcfc1914SAnna Zaks 
114023f4edf1SValeriy Savchenko namespace llvm {
114123f4edf1SValeriy Savchenko template <> struct DenseMapInfo<PrivateMethodKey> {
1142239c53b7SValeriy Savchenko   using InterfaceInfo = DenseMapInfo<const ObjCInterfaceDecl *>;
1143239c53b7SValeriy Savchenko   using SelectorInfo = DenseMapInfo<Selector>;
1144dcfc1914SAnna Zaks 
getEmptyKeyllvm::DenseMapInfo1145239c53b7SValeriy Savchenko   static inline PrivateMethodKey getEmptyKey() {
1146239c53b7SValeriy Savchenko     return {InterfaceInfo::getEmptyKey(), SelectorInfo::getEmptyKey(), false};
1147dcfc1914SAnna Zaks   }
1148dcfc1914SAnna Zaks 
getTombstoneKeyllvm::DenseMapInfo1149239c53b7SValeriy Savchenko   static inline PrivateMethodKey getTombstoneKey() {
1150239c53b7SValeriy Savchenko     return {InterfaceInfo::getTombstoneKey(), SelectorInfo::getTombstoneKey(),
1151239c53b7SValeriy Savchenko             true};
115211150c00SArtem Dergachev   }
115311150c00SArtem Dergachev 
getHashValuellvm::DenseMapInfo1154239c53b7SValeriy Savchenko   static unsigned getHashValue(const PrivateMethodKey &Key) {
1155239c53b7SValeriy Savchenko     return llvm::hash_combine(
1156239c53b7SValeriy Savchenko         llvm::hash_code(InterfaceInfo::getHashValue(Key.Interface)),
1157239c53b7SValeriy Savchenko         llvm::hash_code(SelectorInfo::getHashValue(Key.LookupSelector)),
1158239c53b7SValeriy Savchenko         Key.IsClassMethod);
11594f7df9beSJordan Rose   }
11604f7df9beSJordan Rose 
isEqualllvm::DenseMapInfo1161239c53b7SValeriy Savchenko   static bool isEqual(const PrivateMethodKey &LHS,
1162239c53b7SValeriy Savchenko                       const PrivateMethodKey &RHS) {
1163239c53b7SValeriy Savchenko     return InterfaceInfo::isEqual(LHS.Interface, RHS.Interface) &&
1164239c53b7SValeriy Savchenko            SelectorInfo::isEqual(LHS.LookupSelector, RHS.LookupSelector) &&
1165239c53b7SValeriy Savchenko            LHS.IsClassMethod == RHS.IsClassMethod;
1166dcfc1914SAnna Zaks   }
1167239c53b7SValeriy Savchenko };
116823f4edf1SValeriy Savchenko } // end namespace llvm
1169dcfc1914SAnna Zaks 
1170350dadaaSBenjamin Kramer static const ObjCMethodDecl *
lookupRuntimeDefinition(const ObjCInterfaceDecl * Interface,Selector LookupSelector,bool InstanceMethod)1171239c53b7SValeriy Savchenko lookupRuntimeDefinition(const ObjCInterfaceDecl *Interface,
1172239c53b7SValeriy Savchenko                         Selector LookupSelector, bool InstanceMethod) {
1173245e45afSTed Kremenek   // Repeatedly calling lookupPrivateMethod() is expensive, especially
1174245e45afSTed Kremenek   // when in many cases it returns null.  We cache the results so
1175245e45afSTed Kremenek   // that repeated queries on the same ObjCIntefaceDecl and Selector
1176245e45afSTed Kremenek   // don't incur the same cost.  On some test cases, we can see the
1177245e45afSTed Kremenek   // same query being issued thousands of times.
1178245e45afSTed Kremenek   //
1179245e45afSTed Kremenek   // NOTE: This cache is essentially a "global" variable, but it
1180245e45afSTed Kremenek   // only gets lazily created when we get here.  The value of the
1181245e45afSTed Kremenek   // cache probably comes from it being global across ExprEngines,
1182245e45afSTed Kremenek   // where the same queries may get issued.  If we are worried about
1183245e45afSTed Kremenek   // concurrency, or possibly loading/unloading ASTs, etc., we may
1184245e45afSTed Kremenek   // need to revisit this someday.  In terms of memory, this table
1185245e45afSTed Kremenek   // stays around until clang quits, which also may be bad if we
1186245e45afSTed Kremenek   // need to release memory.
11875bc81eb9SEugene Zelenko   using PrivateMethodCache =
11885bc81eb9SEugene Zelenko       llvm::DenseMap<PrivateMethodKey, Optional<const ObjCMethodDecl *>>;
1189245e45afSTed Kremenek 
1190245e45afSTed Kremenek   static PrivateMethodCache PMC;
1191239c53b7SValeriy Savchenko   Optional<const ObjCMethodDecl *> &Val =
1192239c53b7SValeriy Savchenko       PMC[{Interface, LookupSelector, InstanceMethod}];
1193245e45afSTed Kremenek 
1194245e45afSTed Kremenek   // Query lookupPrivateMethod() if the cache does not hit.
1195452db157SKazu Hirata   if (!Val) {
1196239c53b7SValeriy Savchenko     Val = Interface->lookupPrivateMethod(LookupSelector, InstanceMethod);
1197245e45afSTed Kremenek 
1198239c53b7SValeriy Savchenko     if (!*Val) {
1199239c53b7SValeriy Savchenko       // Query 'lookupMethod' as a backup.
1200239c53b7SValeriy Savchenko       Val = Interface->lookupMethod(LookupSelector, InstanceMethod);
12011a866cd5SJordan Rose     }
1202c239dd13SDevin Coughlin   }
12031a866cd5SJordan Rose 
1204*ca4af13eSKazu Hirata   return *Val;
1205239c53b7SValeriy Savchenko }
1206239c53b7SValeriy Savchenko 
getRuntimeDefinition() const1207239c53b7SValeriy Savchenko RuntimeDefinition ObjCMethodCall::getRuntimeDefinition() const {
1208239c53b7SValeriy Savchenko   const ObjCMessageExpr *E = getOriginExpr();
1209239c53b7SValeriy Savchenko   assert(E);
1210239c53b7SValeriy Savchenko   Selector Sel = E->getSelector();
1211239c53b7SValeriy Savchenko 
1212239c53b7SValeriy Savchenko   if (E->isInstanceMessage()) {
1213239c53b7SValeriy Savchenko     // Find the receiver type.
1214239c53b7SValeriy Savchenko     const ObjCObjectType *ReceiverT = nullptr;
1215239c53b7SValeriy Savchenko     bool CanBeSubClassed = false;
1216239c53b7SValeriy Savchenko     bool LookingForInstanceMethod = true;
1217239c53b7SValeriy Savchenko     QualType SupersType = E->getSuperType();
1218239c53b7SValeriy Savchenko     const MemRegion *Receiver = nullptr;
1219239c53b7SValeriy Savchenko 
1220239c53b7SValeriy Savchenko     if (!SupersType.isNull()) {
1221239c53b7SValeriy Savchenko       // The receiver is guaranteed to be 'super' in this case.
1222239c53b7SValeriy Savchenko       // Super always means the type of immediate predecessor to the method
1223239c53b7SValeriy Savchenko       // where the call occurs.
1224239c53b7SValeriy Savchenko       ReceiverT = cast<ObjCObjectPointerType>(SupersType)->getObjectType();
1225239c53b7SValeriy Savchenko     } else {
1226239c53b7SValeriy Savchenko       Receiver = getReceiverSVal().getAsRegion();
1227239c53b7SValeriy Savchenko       if (!Receiver)
1228239c53b7SValeriy Savchenko         return {};
1229239c53b7SValeriy Savchenko 
1230239c53b7SValeriy Savchenko       DynamicTypeInfo DTI = getDynamicTypeInfo(getState(), Receiver);
1231239c53b7SValeriy Savchenko       if (!DTI.isValid()) {
1232239c53b7SValeriy Savchenko         assert(isa<AllocaRegion>(Receiver) &&
1233239c53b7SValeriy Savchenko                "Unhandled untyped region class!");
1234239c53b7SValeriy Savchenko         return {};
1235239c53b7SValeriy Savchenko       }
1236239c53b7SValeriy Savchenko 
1237239c53b7SValeriy Savchenko       QualType DynType = DTI.getType();
1238239c53b7SValeriy Savchenko       CanBeSubClassed = DTI.canBeASubClass();
1239239c53b7SValeriy Savchenko 
1240239c53b7SValeriy Savchenko       const auto *ReceiverDynT =
1241239c53b7SValeriy Savchenko           dyn_cast<ObjCObjectPointerType>(DynType.getCanonicalType());
1242239c53b7SValeriy Savchenko 
1243239c53b7SValeriy Savchenko       if (ReceiverDynT) {
1244239c53b7SValeriy Savchenko         ReceiverT = ReceiverDynT->getObjectType();
1245239c53b7SValeriy Savchenko 
1246239c53b7SValeriy Savchenko         // It can be actually class methods called with Class object as a
1247239c53b7SValeriy Savchenko         // receiver. This type of messages is treated by the compiler as
1248239c53b7SValeriy Savchenko         // instance (not class).
1249239c53b7SValeriy Savchenko         if (ReceiverT->isObjCClass()) {
1250239c53b7SValeriy Savchenko 
1251239c53b7SValeriy Savchenko           SVal SelfVal = getState()->getSelfSVal(getLocationContext());
1252239c53b7SValeriy Savchenko           // For [self classMethod], return compiler visible declaration.
1253239c53b7SValeriy Savchenko           if (Receiver == SelfVal.getAsRegion()) {
1254239c53b7SValeriy Savchenko             return RuntimeDefinition(findDefiningRedecl(E->getMethodDecl()));
1255239c53b7SValeriy Savchenko           }
1256239c53b7SValeriy Savchenko 
1257239c53b7SValeriy Savchenko           // Otherwise, let's check if we know something about the type
1258239c53b7SValeriy Savchenko           // inside of this class object.
1259239c53b7SValeriy Savchenko           if (SymbolRef ReceiverSym = getReceiverSVal().getAsSymbol()) {
1260239c53b7SValeriy Savchenko             DynamicTypeInfo DTI =
1261239c53b7SValeriy Savchenko                 getClassObjectDynamicTypeInfo(getState(), ReceiverSym);
1262239c53b7SValeriy Savchenko             if (DTI.isValid()) {
1263239c53b7SValeriy Savchenko               // Let's use this type for lookup.
1264239c53b7SValeriy Savchenko               ReceiverT =
1265239c53b7SValeriy Savchenko                   cast<ObjCObjectType>(DTI.getType().getCanonicalType());
1266239c53b7SValeriy Savchenko 
1267239c53b7SValeriy Savchenko               CanBeSubClassed = DTI.canBeASubClass();
1268239c53b7SValeriy Savchenko               // And it should be a class method instead.
1269239c53b7SValeriy Savchenko               LookingForInstanceMethod = false;
1270239c53b7SValeriy Savchenko             }
1271239c53b7SValeriy Savchenko           }
1272239c53b7SValeriy Savchenko         }
1273239c53b7SValeriy Savchenko 
1274239c53b7SValeriy Savchenko         if (CanBeSubClassed)
1275239c53b7SValeriy Savchenko           if (ObjCInterfaceDecl *IDecl = ReceiverT->getInterface())
1276239c53b7SValeriy Savchenko             // Even if `DynamicTypeInfo` told us that it can be
1277239c53b7SValeriy Savchenko             // not necessarily this type, but its descendants, we still want
1278239c53b7SValeriy Savchenko             // to check again if this selector can be actually overridden.
1279239c53b7SValeriy Savchenko             CanBeSubClassed = canBeOverridenInSubclass(IDecl, Sel);
1280239c53b7SValeriy Savchenko       }
1281239c53b7SValeriy Savchenko     }
1282239c53b7SValeriy Savchenko 
1283239c53b7SValeriy Savchenko     // Lookup the instance method implementation.
1284239c53b7SValeriy Savchenko     if (ReceiverT)
1285239c53b7SValeriy Savchenko       if (ObjCInterfaceDecl *IDecl = ReceiverT->getInterface()) {
1286239c53b7SValeriy Savchenko         const ObjCMethodDecl *MD =
1287239c53b7SValeriy Savchenko             lookupRuntimeDefinition(IDecl, Sel, LookingForInstanceMethod);
1288239c53b7SValeriy Savchenko 
12890b58b80eSArtem Dergachev         if (MD && !MD->hasBody())
12900b58b80eSArtem Dergachev           MD = MD->getCanonicalDecl();
1291239c53b7SValeriy Savchenko 
129275f49a9cSAnna Zaks         if (CanBeSubClassed)
129375f49a9cSAnna Zaks           return RuntimeDefinition(MD, Receiver);
1294920af014SAnna Zaks         else
12950dbb783cSCraig Topper           return RuntimeDefinition(MD, nullptr);
1296920af014SAnna Zaks       }
129763282aefSAnna Zaks   } else {
129863282aefSAnna Zaks     // This is a class method.
129963282aefSAnna Zaks     // If we have type info for the receiver class, we are calling via
130063282aefSAnna Zaks     // class name.
130163282aefSAnna Zaks     if (ObjCInterfaceDecl *IDecl = E->getReceiverInterface()) {
130263282aefSAnna Zaks       // Find/Return the method implementation.
130385383182SAnna Zaks       return RuntimeDefinition(IDecl->lookupPrivateClassMethod(Sel));
13044f7df9beSJordan Rose     }
130563282aefSAnna Zaks   }
130663282aefSAnna Zaks 
13075bc81eb9SEugene Zelenko   return {};
13084f7df9beSJordan Rose }
13094f7df9beSJordan Rose 
argumentsMayEscape() const1310514f9354SJordan Rose bool ObjCMethodCall::argumentsMayEscape() const {
1311514f9354SJordan Rose   if (isInSystemHeader() && !isInstanceMessage()) {
1312514f9354SJordan Rose     Selector Sel = getSelector();
1313514f9354SJordan Rose     if (Sel.getNumArgs() == 1 &&
1314514f9354SJordan Rose         Sel.getIdentifierInfoForSlot(0)->isStr("valueWithPointer"))
1315514f9354SJordan Rose       return true;
1316514f9354SJordan Rose   }
1317514f9354SJordan Rose 
1318514f9354SJordan Rose   return CallEvent::argumentsMayEscape();
1319514f9354SJordan Rose }
1320514f9354SJordan Rose 
getInitialStackFrameContents(const StackFrameContext * CalleeCtx,BindingsTy & Bindings) const132142e8d649SJordan Rose void ObjCMethodCall::getInitialStackFrameContents(
132242e8d649SJordan Rose                                              const StackFrameContext *CalleeCtx,
132342e8d649SJordan Rose                                              BindingsTy &Bindings) const {
13245bc81eb9SEugene Zelenko   const auto *D = cast<ObjCMethodDecl>(CalleeCtx->getDecl());
132542e8d649SJordan Rose   SValBuilder &SVB = getState()->getStateManager().getSValBuilder();
132642e8d649SJordan Rose   addParameterValuesToBindings(CalleeCtx, Bindings, SVB, *this,
13272ff16004STed Kremenek                                D->parameters());
132842e8d649SJordan Rose 
132942e8d649SJordan Rose   SVal SelfVal = getReceiverSVal();
133042e8d649SJordan Rose   if (!SelfVal.isUnknown()) {
133142e8d649SJordan Rose     const VarDecl *SelfD = CalleeCtx->getAnalysisDeclContext()->getSelfDecl();
133242e8d649SJordan Rose     MemRegionManager &MRMgr = SVB.getRegionManager();
133342e8d649SJordan Rose     Loc SelfLoc = SVB.makeLoc(MRMgr.getVarRegion(SelfD, CalleeCtx));
133442e8d649SJordan Rose     Bindings.push_back(std::make_pair(SelfLoc, SelfVal));
133542e8d649SJordan Rose   }
133642e8d649SJordan Rose }
133742e8d649SJordan Rose 
1338ce6c99a5SJordan Rose CallEventRef<>
getSimpleCall(const CallExpr * CE,ProgramStateRef State,const LocationContext * LCtx)1339fcd016e5SJordan Rose CallEventManager::getSimpleCall(const CallExpr *CE, ProgramStateRef State,
1340fcd016e5SJordan Rose                                 const LocationContext *LCtx) {
13415bc81eb9SEugene Zelenko   if (const auto *MCE = dyn_cast<CXXMemberCallExpr>(CE))
1342fcd016e5SJordan Rose     return create<CXXMemberCall>(MCE, State, LCtx);
1343fcd016e5SJordan Rose 
13445bc81eb9SEugene Zelenko   if (const auto *OpCE = dyn_cast<CXXOperatorCallExpr>(CE)) {
1345fcd016e5SJordan Rose     const FunctionDecl *DirectCallee = OpCE->getDirectCallee();
13465bc81eb9SEugene Zelenko     if (const auto *MD = dyn_cast<CXXMethodDecl>(DirectCallee))
1347fcd016e5SJordan Rose       if (MD->isInstance())
1348fcd016e5SJordan Rose         return create<CXXMemberOperatorCall>(OpCE, State, LCtx);
1349fcd016e5SJordan Rose 
1350fcd016e5SJordan Rose   } else if (CE->getCallee()->getType()->isBlockPointerType()) {
1351fcd016e5SJordan Rose     return create<BlockCall>(CE, State, LCtx);
1352fcd016e5SJordan Rose   }
1353fcd016e5SJordan Rose 
1354fcd016e5SJordan Rose   // Otherwise, it's a normal function call, static member function call, or
1355fcd016e5SJordan Rose   // something we can't reason about.
13562a833ca5SJordan Rose   return create<SimpleFunctionCall>(CE, State, LCtx);
1357fcd016e5SJordan Rose }
1358c2d249ceSJordan Rose 
1359c2d249ceSJordan Rose CallEventRef<>
getCaller(const StackFrameContext * CalleeCtx,ProgramStateRef State)1360c2d249ceSJordan Rose CallEventManager::getCaller(const StackFrameContext *CalleeCtx,
1361c2d249ceSJordan Rose                             ProgramStateRef State) {
1362c2d249ceSJordan Rose   const LocationContext *ParentCtx = CalleeCtx->getParent();
1363dd18b11bSGeorge Karpenkov   const LocationContext *CallerCtx = ParentCtx->getStackFrame();
1364c2d249ceSJordan Rose   assert(CallerCtx && "This should not be used for top-level stack frames");
1365c2d249ceSJordan Rose 
1366c2d249ceSJordan Rose   const Stmt *CallSite = CalleeCtx->getCallSite();
1367c2d249ceSJordan Rose 
1368c2d249ceSJordan Rose   if (CallSite) {
13699f3a279fSGeorge Karpenkov     if (CallEventRef<> Out = getCall(CallSite, State, CallerCtx))
13709f3a279fSGeorge Karpenkov       return Out;
1371c2d249ceSJordan Rose 
1372c2d249ceSJordan Rose     SValBuilder &SVB = State->getStateManager().getSValBuilder();
13735bc81eb9SEugene Zelenko     const auto *Ctor = cast<CXXMethodDecl>(CalleeCtx->getDecl());
1374c2d249ceSJordan Rose     Loc ThisPtr = SVB.getCXXThis(Ctor, CalleeCtx);
1375c2d249ceSJordan Rose     SVal ThisVal = State->getSVal(ThisPtr);
1376c2d249ceSJordan Rose 
1377a82ffe9dSArtem Dergachev     if (const auto *CE = dyn_cast<CXXConstructExpr>(CallSite))
1378a82ffe9dSArtem Dergachev       return getCXXConstructorCall(CE, ThisVal.getAsRegion(), State, CallerCtx);
1379a82ffe9dSArtem Dergachev     else if (const auto *CIE = dyn_cast<CXXInheritedCtorInitExpr>(CallSite))
1380a82ffe9dSArtem Dergachev       return getCXXInheritedConstructorCall(CIE, ThisVal.getAsRegion(), State,
1381a82ffe9dSArtem Dergachev                                             CallerCtx);
1382a82ffe9dSArtem Dergachev     else {
1383a82ffe9dSArtem Dergachev       // All other cases are handled by getCall.
1384a82ffe9dSArtem Dergachev       llvm_unreachable("This is not an inlineable statement");
1385a82ffe9dSArtem Dergachev     }
1386c2d249ceSJordan Rose   }
1387c2d249ceSJordan Rose 
1388c2d249ceSJordan Rose   // Fall back to the CFG. The only thing we haven't handled yet is
1389c2d249ceSJordan Rose   // destructors, though this could change in the future.
1390c2d249ceSJordan Rose   const CFGBlock *B = CalleeCtx->getCallSiteBlock();
1391c2d249ceSJordan Rose   CFGElement E = (*B)[CalleeCtx->getIndex()];
1392f884cd42SAaron Ballman   assert((E.getAs<CFGImplicitDtor>() || E.getAs<CFGTemporaryDtor>()) &&
13932a01f5d4SDavid Blaikie          "All other CFG elements should have exprs");
1394c2d249ceSJordan Rose 
1395c2d249ceSJordan Rose   SValBuilder &SVB = State->getStateManager().getSValBuilder();
13965bc81eb9SEugene Zelenko   const auto *Dtor = cast<CXXDestructorDecl>(CalleeCtx->getDecl());
1397c2d249ceSJordan Rose   Loc ThisPtr = SVB.getCXXThis(Dtor, CalleeCtx);
1398c2d249ceSJordan Rose   SVal ThisVal = State->getSVal(ThisPtr);
1399c2d249ceSJordan Rose 
1400c2d249ceSJordan Rose   const Stmt *Trigger;
140100be69abSDavid Blaikie   if (Optional<CFGAutomaticObjDtor> AutoDtor = E.getAs<CFGAutomaticObjDtor>())
140200be69abSDavid Blaikie     Trigger = AutoDtor->getTriggerStmt();
14031ccc43d5SJordan Rose   else if (Optional<CFGDeleteDtor> DeleteDtor = E.getAs<CFGDeleteDtor>())
140400f70bd9SGeorge Burgess IV     Trigger = DeleteDtor->getDeleteExpr();
1405c2d249ceSJordan Rose   else
1406c2d249ceSJordan Rose     Trigger = Dtor->getBody();
1407c2d249ceSJordan Rose 
1408c2d249ceSJordan Rose   return getCXXDestructorCall(Dtor, Trigger, ThisVal.getAsRegion(),
14090916d96dSKazu Hirata                               E.getAs<CFGBaseDtor>().has_value(), State,
141000be69abSDavid Blaikie                               CallerCtx);
1411c2d249ceSJordan Rose }
14129f3a279fSGeorge Karpenkov 
getCall(const Stmt * S,ProgramStateRef State,const LocationContext * LC)14139f3a279fSGeorge Karpenkov CallEventRef<> CallEventManager::getCall(const Stmt *S, ProgramStateRef State,
14149f3a279fSGeorge Karpenkov                                          const LocationContext *LC) {
14159f3a279fSGeorge Karpenkov   if (const auto *CE = dyn_cast<CallExpr>(S)) {
14169f3a279fSGeorge Karpenkov     return getSimpleCall(CE, State, LC);
14179f3a279fSGeorge Karpenkov   } else if (const auto *NE = dyn_cast<CXXNewExpr>(S)) {
14189f3a279fSGeorge Karpenkov     return getCXXAllocatorCall(NE, State, LC);
14191ec1cdcfSFred Tingaud   } else if (const auto *DE = dyn_cast<CXXDeleteExpr>(S)) {
14201ec1cdcfSFred Tingaud     return getCXXDeallocatorCall(DE, State, LC);
14219f3a279fSGeorge Karpenkov   } else if (const auto *ME = dyn_cast<ObjCMessageExpr>(S)) {
14229f3a279fSGeorge Karpenkov     return getObjCMethodCall(ME, State, LC);
14239f3a279fSGeorge Karpenkov   } else {
14249f3a279fSGeorge Karpenkov     return nullptr;
14259f3a279fSGeorge Karpenkov   }
14269f3a279fSGeorge Karpenkov }
1427