14f7df9beSJordan Rose //===- Calls.cpp - Wrapper for all function and method calls ------*- C++ -*--//
24f7df9beSJordan Rose //
34f7df9beSJordan Rose //                     The LLVM Compiler Infrastructure
44f7df9beSJordan Rose //
54f7df9beSJordan Rose // This file is distributed under the University of Illinois Open Source
64f7df9beSJordan Rose // License. See LICENSE.TXT for details.
74f7df9beSJordan Rose //
84f7df9beSJordan Rose //===----------------------------------------------------------------------===//
94f7df9beSJordan Rose //
104f7df9beSJordan Rose /// \file This file defines CallEvent and its subclasses, which represent path-
114f7df9beSJordan Rose /// sensitive instances of different kinds of function and method calls
124f7df9beSJordan Rose /// (C, C++, and Objective-C).
134f7df9beSJordan Rose //
144f7df9beSJordan Rose //===----------------------------------------------------------------------===//
154f7df9beSJordan Rose 
164f7df9beSJordan Rose #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
174f7df9beSJordan Rose #include "clang/AST/ParentMap.h"
183a02247dSChandler Carruth #include "clang/Analysis/ProgramPoint.h"
193a02247dSChandler Carruth #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
204df9d812SGabor Horvath #include "clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeMap.h"
214f7df9beSJordan Rose #include "llvm/ADT/SmallSet.h"
224f7df9beSJordan Rose #include "llvm/ADT/StringExtras.h"
23444a1304SBenjamin Kramer #include "llvm/Support/raw_ostream.h"
244f7df9beSJordan Rose 
254f7df9beSJordan Rose using namespace clang;
264f7df9beSJordan Rose using namespace ento;
274f7df9beSJordan Rose 
284f7df9beSJordan Rose QualType CallEvent::getResultType() const {
292da56438SJordan Rose   const Expr *E = getOriginExpr();
302da56438SJordan Rose   assert(E && "Calls without origin expressions do not have results");
312da56438SJordan Rose   QualType ResultTy = E->getType();
324f7df9beSJordan Rose 
332da56438SJordan Rose   ASTContext &Ctx = getState()->getStateManager().getContext();
342da56438SJordan Rose 
352da56438SJordan Rose   // A function that returns a reference to 'int' will have a result type
362da56438SJordan Rose   // of simply 'int'. Check the origin expr's value kind to recover the
372da56438SJordan Rose   // proper type.
382da56438SJordan Rose   switch (E->getValueKind()) {
392da56438SJordan Rose   case VK_LValue:
402da56438SJordan Rose     ResultTy = Ctx.getLValueReferenceType(ResultTy);
412da56438SJordan Rose     break;
422da56438SJordan Rose   case VK_XValue:
432da56438SJordan Rose     ResultTy = Ctx.getRValueReferenceType(ResultTy);
442da56438SJordan Rose     break;
452da56438SJordan Rose   case VK_RValue:
462da56438SJordan Rose     // No adjustment is necessary.
472da56438SJordan Rose     break;
482da56438SJordan Rose   }
494f7df9beSJordan Rose 
504f7df9beSJordan Rose   return ResultTy;
514f7df9beSJordan Rose }
524f7df9beSJordan Rose 
53fe1eca51SAnna Zaks static bool isCallback(QualType T) {
544f7df9beSJordan Rose   // If a parameter is a block or a callback, assume it can modify pointer.
554f7df9beSJordan Rose   if (T->isBlockPointerType() ||
564f7df9beSJordan Rose       T->isFunctionPointerType() ||
574f7df9beSJordan Rose       T->isObjCSelType())
584f7df9beSJordan Rose     return true;
594f7df9beSJordan Rose 
604f7df9beSJordan Rose   // Check if a callback is passed inside a struct (for both, struct passed by
614f7df9beSJordan Rose   // reference and by value). Dig just one level into the struct for now.
624f7df9beSJordan Rose 
63d1a08b6eSJordan Rose   if (T->isAnyPointerType() || T->isReferenceType())
644f7df9beSJordan Rose     T = T->getPointeeType();
654f7df9beSJordan Rose 
664f7df9beSJordan Rose   if (const RecordType *RT = T->getAsStructureType()) {
674f7df9beSJordan Rose     const RecordDecl *RD = RT->getDecl();
68e8a8baefSAaron Ballman     for (const auto *I : RD->fields()) {
694f7df9beSJordan Rose       QualType FieldT = I->getType();
704f7df9beSJordan Rose       if (FieldT->isBlockPointerType() || FieldT->isFunctionPointerType())
714f7df9beSJordan Rose         return true;
724f7df9beSJordan Rose     }
734f7df9beSJordan Rose   }
744f7df9beSJordan Rose   return false;
754f7df9beSJordan Rose }
764f7df9beSJordan Rose 
77fe1eca51SAnna Zaks static bool isVoidPointerToNonConst(QualType T) {
78fe1eca51SAnna Zaks   if (const PointerType *PT = T->getAs<PointerType>()) {
79fe1eca51SAnna Zaks     QualType PointeeTy = PT->getPointeeType();
80fe1eca51SAnna Zaks     if (PointeeTy.isConstQualified())
81fe1eca51SAnna Zaks       return false;
82fe1eca51SAnna Zaks     return PointeeTy->isVoidType();
83fe1eca51SAnna Zaks   } else
84fe1eca51SAnna Zaks     return false;
85fe1eca51SAnna Zaks }
86fe1eca51SAnna Zaks 
87fe1eca51SAnna Zaks bool CallEvent::hasNonNullArgumentsWithType(bool (*Condition)(QualType)) const {
884f7df9beSJordan Rose   unsigned NumOfArgs = getNumArgs();
894f7df9beSJordan Rose 
904f7df9beSJordan Rose   // If calling using a function pointer, assume the function does not
91fe1eca51SAnna Zaks   // satisfy the callback.
92fe1eca51SAnna Zaks   // TODO: We could check the types of the arguments here.
934f7df9beSJordan Rose   if (!getDecl())
944f7df9beSJordan Rose     return false;
954f7df9beSJordan Rose 
964f7df9beSJordan Rose   unsigned Idx = 0;
974f7df9beSJordan Rose   for (CallEvent::param_type_iterator I = param_type_begin(),
984f7df9beSJordan Rose                                       E = param_type_end();
994f7df9beSJordan Rose        I != E && Idx < NumOfArgs; ++I, ++Idx) {
1004f7df9beSJordan Rose     if (NumOfArgs <= Idx)
1014f7df9beSJordan Rose       break;
1024f7df9beSJordan Rose 
103fe1eca51SAnna Zaks     // If the parameter is 0, it's harmless.
104fe1eca51SAnna Zaks     if (getArgSVal(Idx).isZeroConstant())
105fe1eca51SAnna Zaks       continue;
106fe1eca51SAnna Zaks 
107fe1eca51SAnna Zaks     if (Condition(*I))
1084f7df9beSJordan Rose       return true;
1094f7df9beSJordan Rose   }
1104f7df9beSJordan Rose   return false;
1114f7df9beSJordan Rose }
1124f7df9beSJordan Rose 
113fe1eca51SAnna Zaks bool CallEvent::hasNonZeroCallbackArg() const {
114fe1eca51SAnna Zaks   return hasNonNullArgumentsWithType(isCallback);
115fe1eca51SAnna Zaks }
116fe1eca51SAnna Zaks 
117fe1eca51SAnna Zaks bool CallEvent::hasVoidPointerToNonConstArg() const {
118fe1eca51SAnna Zaks   return hasNonNullArgumentsWithType(isVoidPointerToNonConst);
119fe1eca51SAnna Zaks }
120fe1eca51SAnna Zaks 
121829c3831SJordan Rose bool CallEvent::isGlobalCFunction(StringRef FunctionName) const {
122829c3831SJordan Rose   const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(getDecl());
123829c3831SJordan Rose   if (!FD)
124829c3831SJordan Rose     return false;
125829c3831SJordan Rose 
126829c3831SJordan Rose   return CheckerContext::isCLibraryFunction(FD, FunctionName);
127829c3831SJordan Rose }
128829c3831SJordan Rose 
1294f7df9beSJordan Rose /// \brief Returns true if a type is a pointer-to-const or reference-to-const
1304f7df9beSJordan Rose /// with no further indirection.
1314f7df9beSJordan Rose static bool isPointerToConst(QualType Ty) {
1324f7df9beSJordan Rose   QualType PointeeTy = Ty->getPointeeType();
1334f7df9beSJordan Rose   if (PointeeTy == QualType())
1344f7df9beSJordan Rose     return false;
1354f7df9beSJordan Rose   if (!PointeeTy.isConstQualified())
1364f7df9beSJordan Rose     return false;
1374f7df9beSJordan Rose   if (PointeeTy->isAnyPointerType())
1384f7df9beSJordan Rose     return false;
1394f7df9beSJordan Rose   return true;
1404f7df9beSJordan Rose }
1414f7df9beSJordan Rose 
1424f7df9beSJordan Rose // Try to retrieve the function declaration and find the function parameter
1434f7df9beSJordan Rose // types which are pointers/references to a non-pointer const.
1444f7df9beSJordan Rose // We will not invalidate the corresponding argument regions.
1455413aaa7SJordan Rose static void findPtrToConstParams(llvm::SmallSet<unsigned, 4> &PreserveArgs,
1464f7df9beSJordan Rose                                  const CallEvent &Call) {
1474f7df9beSJordan Rose   unsigned Idx = 0;
1484f7df9beSJordan Rose   for (CallEvent::param_type_iterator I = Call.param_type_begin(),
1494f7df9beSJordan Rose                                       E = Call.param_type_end();
1504f7df9beSJordan Rose        I != E; ++I, ++Idx) {
1514f7df9beSJordan Rose     if (isPointerToConst(*I))
1524f7df9beSJordan Rose       PreserveArgs.insert(Idx);
1534f7df9beSJordan Rose   }
1544f7df9beSJordan Rose }
1554f7df9beSJordan Rose 
1564f7df9beSJordan Rose ProgramStateRef CallEvent::invalidateRegions(unsigned BlockCount,
1574f7df9beSJordan Rose                                              ProgramStateRef Orig) const {
1584f7df9beSJordan Rose   ProgramStateRef Result = (Orig ? Orig : getState());
1594f7df9beSJordan Rose 
1602741654bSJordan Rose   // Don't invalidate anything if the callee is marked pure/const.
1612741654bSJordan Rose   if (const Decl *callee = getDecl())
1622741654bSJordan Rose     if (callee->hasAttr<PureAttr>() || callee->hasAttr<ConstAttr>())
1632741654bSJordan Rose       return Result;
1642741654bSJordan Rose 
16560bf5f45SAnna Zaks   SmallVector<SVal, 8> ValuesToInvalidate;
166424ad95fSAnton Yartsev   RegionAndSymbolInvalidationTraits ETraits;
16760bf5f45SAnna Zaks 
1684f770deeSDevin Coughlin   getExtraInvalidatedValues(ValuesToInvalidate, &ETraits);
1694f7df9beSJordan Rose 
1704f7df9beSJordan Rose   // Indexes of arguments whose values will be preserved by the call.
1715413aaa7SJordan Rose   llvm::SmallSet<unsigned, 4> PreserveArgs;
1724f7df9beSJordan Rose   if (!argumentsMayEscape())
1734f7df9beSJordan Rose     findPtrToConstParams(PreserveArgs, *this);
1744f7df9beSJordan Rose 
1754f7df9beSJordan Rose   for (unsigned Idx = 0, Count = getNumArgs(); Idx != Count; ++Idx) {
1764f7df9beSJordan Rose     // Mark this region for invalidation.  We batch invalidate regions
1774f7df9beSJordan Rose     // below for efficiency.
1785413aaa7SJordan Rose     if (PreserveArgs.count(Idx))
179424ad95fSAnton Yartsev       if (const MemRegion *MR = getArgSVal(Idx).getAsRegion())
18070247e69SArtem Dergachev         ETraits.setTrait(MR->getBaseRegion(),
181424ad95fSAnton Yartsev                         RegionAndSymbolInvalidationTraits::TK_PreserveContents);
182424ad95fSAnton Yartsev         // TODO: Factor this out + handle the lower level const pointers.
183424ad95fSAnton Yartsev 
18460bf5f45SAnna Zaks     ValuesToInvalidate.push_back(getArgSVal(Idx));
1854f7df9beSJordan Rose   }
1864f7df9beSJordan Rose 
1874f7df9beSJordan Rose   // Invalidate designated regions using the batch invalidation API.
1884f7df9beSJordan Rose   // NOTE: Even if RegionsToInvalidate is empty, we may still invalidate
1894f7df9beSJordan Rose   //  global variables.
19060bf5f45SAnna Zaks   return Result->invalidateRegions(ValuesToInvalidate, getOriginExpr(),
1914f7df9beSJordan Rose                                    BlockCount, getLocationContext(),
1929747febbSAnna Zaks                                    /*CausedByPointerEscape*/ true,
1930dbb783cSCraig Topper                                    /*Symbols=*/nullptr, this, &ETraits);
1944f7df9beSJordan Rose }
1954f7df9beSJordan Rose 
1964f7df9beSJordan Rose ProgramPoint CallEvent::getProgramPoint(bool IsPreVisit,
1974f7df9beSJordan Rose                                         const ProgramPointTag *Tag) const {
1984f7df9beSJordan Rose   if (const Expr *E = getOriginExpr()) {
1994f7df9beSJordan Rose     if (IsPreVisit)
2004f7df9beSJordan Rose       return PreStmt(E, getLocationContext(), Tag);
2014f7df9beSJordan Rose     return PostStmt(E, getLocationContext(), Tag);
2024f7df9beSJordan Rose   }
2034f7df9beSJordan Rose 
2044f7df9beSJordan Rose   const Decl *D = getDecl();
2054f7df9beSJordan Rose   assert(D && "Cannot get a program point without a statement or decl");
2064f7df9beSJordan Rose 
2074f7df9beSJordan Rose   SourceLocation Loc = getSourceRange().getBegin();
2084f7df9beSJordan Rose   if (IsPreVisit)
2094f7df9beSJordan Rose     return PreImplicitCall(D, Loc, getLocationContext(), Tag);
2104f7df9beSJordan Rose   return PostImplicitCall(D, Loc, getLocationContext(), Tag);
2114f7df9beSJordan Rose }
2124f7df9beSJordan Rose 
213343730c5SGabor Horvath bool CallEvent::isCalled(const CallDescription &CD) const {
214343730c5SGabor Horvath   assert(getKind() != CE_ObjCMessage && "Obj-C methods are not supported");
215343730c5SGabor Horvath   if (!CD.II)
216343730c5SGabor Horvath     CD.II = &getState()->getStateManager().getContext().Idents.get(CD.FuncName);
217343730c5SGabor Horvath   if (getCalleeIdentifier() != CD.II)
218343730c5SGabor Horvath     return false;
219343730c5SGabor Horvath   return (CD.RequiredArgs == CallDescription::NoArgRequirement ||
220343730c5SGabor Horvath           CD.RequiredArgs == getNumArgs());
221343730c5SGabor Horvath }
222343730c5SGabor Horvath 
22372ce8e2dSJordan Rose SVal CallEvent::getArgSVal(unsigned Index) const {
22472ce8e2dSJordan Rose   const Expr *ArgE = getArgExpr(Index);
22572ce8e2dSJordan Rose   if (!ArgE)
22672ce8e2dSJordan Rose     return UnknownVal();
22772ce8e2dSJordan Rose   return getSVal(ArgE);
22872ce8e2dSJordan Rose }
22972ce8e2dSJordan Rose 
23072ce8e2dSJordan Rose SourceRange CallEvent::getArgSourceRange(unsigned Index) const {
23172ce8e2dSJordan Rose   const Expr *ArgE = getArgExpr(Index);
23272ce8e2dSJordan Rose   if (!ArgE)
23372ce8e2dSJordan Rose     return SourceRange();
23472ce8e2dSJordan Rose   return ArgE->getSourceRange();
23572ce8e2dSJordan Rose }
23672ce8e2dSJordan Rose 
237829c3831SJordan Rose SVal CallEvent::getReturnValue() const {
238829c3831SJordan Rose   const Expr *E = getOriginExpr();
239829c3831SJordan Rose   if (!E)
240829c3831SJordan Rose     return UndefinedVal();
241829c3831SJordan Rose   return getSVal(E);
242829c3831SJordan Rose }
243829c3831SJordan Rose 
244ef6b007dSAlp Toker LLVM_DUMP_METHOD void CallEvent::dump() const { dump(llvm::errs()); }
2459299d8c2SBenjamin Kramer 
24672ce8e2dSJordan Rose void CallEvent::dump(raw_ostream &Out) const {
24772ce8e2dSJordan Rose   ASTContext &Ctx = getState()->getStateManager().getContext();
24872ce8e2dSJordan Rose   if (const Expr *E = getOriginExpr()) {
2490dbb783cSCraig Topper     E->printPretty(Out, nullptr, Ctx.getPrintingPolicy());
25072ce8e2dSJordan Rose     Out << "\n";
25172ce8e2dSJordan Rose     return;
25272ce8e2dSJordan Rose   }
25372ce8e2dSJordan Rose 
25472ce8e2dSJordan Rose   if (const Decl *D = getDecl()) {
25572ce8e2dSJordan Rose     Out << "Call to ";
25672ce8e2dSJordan Rose     D->print(Out, Ctx.getPrintingPolicy());
25772ce8e2dSJordan Rose     return;
25872ce8e2dSJordan Rose   }
25972ce8e2dSJordan Rose 
26072ce8e2dSJordan Rose   // FIXME: a string representation of the kind would be nice.
26172ce8e2dSJordan Rose   Out << "Unknown call (type " << getKind() << ")";
26272ce8e2dSJordan Rose }
26372ce8e2dSJordan Rose 
2644f7df9beSJordan Rose 
265e537cc05SJordan Rose bool CallEvent::isCallStmt(const Stmt *S) {
26672ce8e2dSJordan Rose   return isa<CallExpr>(S) || isa<ObjCMessageExpr>(S)
267e537cc05SJordan Rose                           || isa<CXXConstructExpr>(S)
268e537cc05SJordan Rose                           || isa<CXXNewExpr>(S);
2694f7df9beSJordan Rose }
2704f7df9beSJordan Rose 
2715d2964e7SAnna Zaks QualType CallEvent::getDeclaredResultType(const Decl *D) {
2725d2964e7SAnna Zaks   assert(D);
2735d2964e7SAnna Zaks   if (const FunctionDecl* FD = dyn_cast<FunctionDecl>(D))
274314cc81bSAlp Toker     return FD->getReturnType();
275add14263SJordan Rose   if (const ObjCMethodDecl* MD = dyn_cast<ObjCMethodDecl>(D))
276314cc81bSAlp Toker     return MD->getReturnType();
277add14263SJordan Rose   if (const BlockDecl *BD = dyn_cast<BlockDecl>(D)) {
278add14263SJordan Rose     // Blocks are difficult because the return type may not be stored in the
279add14263SJordan Rose     // BlockDecl itself. The AST should probably be enhanced, but for now we
280add14263SJordan Rose     // just do what we can.
281278d9de3SJordan Rose     // If the block is declared without an explicit argument list, the
282278d9de3SJordan Rose     // signature-as-written just includes the return type, not the entire
283278d9de3SJordan Rose     // function type.
2841bfe9c78SJordan Rose     // FIXME: All blocks should have signatures-as-written, even if the return
285278d9de3SJordan Rose     // type is inferred. (That's signified with a dependent result type.)
2861bfe9c78SJordan Rose     if (const TypeSourceInfo *TSI = BD->getSignatureAsWritten()) {
287278d9de3SJordan Rose       QualType Ty = TSI->getType();
288278d9de3SJordan Rose       if (const FunctionType *FT = Ty->getAs<FunctionType>())
289314cc81bSAlp Toker         Ty = FT->getReturnType();
290278d9de3SJordan Rose       if (!Ty->isDependentType())
291278d9de3SJordan Rose         return Ty;
2921bfe9c78SJordan Rose     }
293add14263SJordan Rose 
294add14263SJordan Rose     return QualType();
295add14263SJordan Rose   }
296add14263SJordan Rose 
2973553bb38SJordan Rose   llvm_unreachable("unknown callable kind");
2983553bb38SJordan Rose }
2993553bb38SJordan Rose 
3003553bb38SJordan Rose bool CallEvent::isVariadic(const Decl *D) {
3013553bb38SJordan Rose   assert(D);
3023553bb38SJordan Rose 
3033553bb38SJordan Rose   if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
3043553bb38SJordan Rose     return FD->isVariadic();
3053553bb38SJordan Rose   if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
3063553bb38SJordan Rose     return MD->isVariadic();
3073553bb38SJordan Rose   if (const BlockDecl *BD = dyn_cast<BlockDecl>(D))
3083553bb38SJordan Rose     return BD->isVariadic();
3093553bb38SJordan Rose 
3103553bb38SJordan Rose   llvm_unreachable("unknown callable kind");
3115d2964e7SAnna Zaks }
3125d2964e7SAnna Zaks 
31342e8d649SJordan Rose static void addParameterValuesToBindings(const StackFrameContext *CalleeCtx,
31442e8d649SJordan Rose                                          CallEvent::BindingsTy &Bindings,
31542e8d649SJordan Rose                                          SValBuilder &SVB,
31642e8d649SJordan Rose                                          const CallEvent &Call,
3172ff16004STed Kremenek                                          ArrayRef<ParmVarDecl*> parameters) {
31842e8d649SJordan Rose   MemRegionManager &MRMgr = SVB.getRegionManager();
3194f7df9beSJordan Rose 
320963f91b3SPavel Labath   // If the function has fewer parameters than the call has arguments, we simply
321963f91b3SPavel Labath   // do not bind any values to them.
322963f91b3SPavel Labath   unsigned NumArgs = Call.getNumArgs();
32342e8d649SJordan Rose   unsigned Idx = 0;
3242ff16004STed Kremenek   ArrayRef<ParmVarDecl*>::iterator I = parameters.begin(), E = parameters.end();
325963f91b3SPavel Labath   for (; I != E && Idx < NumArgs; ++I, ++Idx) {
32642e8d649SJordan Rose     const ParmVarDecl *ParamDecl = *I;
32742e8d649SJordan Rose     assert(ParamDecl && "Formal parameter has no decl?");
3284f7df9beSJordan Rose 
32942e8d649SJordan Rose     SVal ArgVal = Call.getArgSVal(Idx);
33042e8d649SJordan Rose     if (!ArgVal.isUnknown()) {
33142e8d649SJordan Rose       Loc ParamLoc = SVB.makeLoc(MRMgr.getVarRegion(ParamDecl, CalleeCtx));
33242e8d649SJordan Rose       Bindings.push_back(std::make_pair(ParamLoc, ArgVal));
33342e8d649SJordan Rose     }
3344f7df9beSJordan Rose   }
3354f7df9beSJordan Rose 
33642e8d649SJordan Rose   // FIXME: Variadic arguments are not handled at all right now.
33742e8d649SJordan Rose }
33842e8d649SJordan Rose 
3392ff16004STed Kremenek ArrayRef<ParmVarDecl*> AnyFunctionCall::parameters() const {
34042e8d649SJordan Rose   const FunctionDecl *D = getDecl();
3414f7df9beSJordan Rose   if (!D)
34200bbdcf9SCraig Topper     return None;
3432ff16004STed Kremenek   return D->parameters();
34442e8d649SJordan Rose }
34542e8d649SJordan Rose 
34642e8d649SJordan Rose void AnyFunctionCall::getInitialStackFrameContents(
34742e8d649SJordan Rose                                         const StackFrameContext *CalleeCtx,
34842e8d649SJordan Rose                                         BindingsTy &Bindings) const {
34942e8d649SJordan Rose   const FunctionDecl *D = cast<FunctionDecl>(CalleeCtx->getDecl());
35042e8d649SJordan Rose   SValBuilder &SVB = getState()->getStateManager().getSValBuilder();
35142e8d649SJordan Rose   addParameterValuesToBindings(CalleeCtx, Bindings, SVB, *this,
3522ff16004STed Kremenek                                D->parameters());
3534f7df9beSJordan Rose }
3544f7df9beSJordan Rose 
3554f7df9beSJordan Rose bool AnyFunctionCall::argumentsMayEscape() const {
356fe1eca51SAnna Zaks   if (CallEvent::argumentsMayEscape() || hasVoidPointerToNonConstArg())
3574f7df9beSJordan Rose     return true;
3584f7df9beSJordan Rose 
3594f7df9beSJordan Rose   const FunctionDecl *D = getDecl();
3604f7df9beSJordan Rose   if (!D)
3614f7df9beSJordan Rose     return true;
3624f7df9beSJordan Rose 
3634f7df9beSJordan Rose   const IdentifierInfo *II = D->getIdentifier();
3644f7df9beSJordan Rose   if (!II)
3657bd0674dSAnna Zaks     return false;
3664f7df9beSJordan Rose 
3674f7df9beSJordan Rose   // This set of "escaping" APIs is
3684f7df9beSJordan Rose 
3694f7df9beSJordan Rose   // - 'int pthread_setspecific(ptheread_key k, const void *)' stores a
3704f7df9beSJordan Rose   //   value into thread local storage. The value can later be retrieved with
3714f7df9beSJordan Rose   //   'void *ptheread_getspecific(pthread_key)'. So even thought the
3724f7df9beSJordan Rose   //   parameter is 'const void *', the region escapes through the call.
3734f7df9beSJordan Rose   if (II->isStr("pthread_setspecific"))
3744f7df9beSJordan Rose     return true;
3754f7df9beSJordan Rose 
3764f7df9beSJordan Rose   // - xpc_connection_set_context stores a value which can be retrieved later
3774f7df9beSJordan Rose   //   with xpc_connection_get_context.
3784f7df9beSJordan Rose   if (II->isStr("xpc_connection_set_context"))
3794f7df9beSJordan Rose     return true;
3804f7df9beSJordan Rose 
3814f7df9beSJordan Rose   // - funopen - sets a buffer for future IO calls.
3824f7df9beSJordan Rose   if (II->isStr("funopen"))
3834f7df9beSJordan Rose     return true;
3844f7df9beSJordan Rose 
38544cdeb1dSAnna Zaks   // - __cxa_demangle - can reallocate memory and can return the pointer to
38644cdeb1dSAnna Zaks   // the input buffer.
38744cdeb1dSAnna Zaks   if (II->isStr("__cxa_demangle"))
38844cdeb1dSAnna Zaks     return true;
38944cdeb1dSAnna Zaks 
3904f7df9beSJordan Rose   StringRef FName = II->getName();
3914f7df9beSJordan Rose 
3924f7df9beSJordan Rose   // - CoreFoundation functions that end with "NoCopy" can free a passed-in
3934f7df9beSJordan Rose   //   buffer even if it is const.
3944f7df9beSJordan Rose   if (FName.endswith("NoCopy"))
3954f7df9beSJordan Rose     return true;
3964f7df9beSJordan Rose 
3974f7df9beSJordan Rose   // - NSXXInsertXX, for example NSMapInsertIfAbsent, since they can
3984f7df9beSJordan Rose   //   be deallocated by NSMapRemove.
3994f7df9beSJordan Rose   if (FName.startswith("NS") && (FName.find("Insert") != StringRef::npos))
4004f7df9beSJordan Rose     return true;
4014f7df9beSJordan Rose 
4024f7df9beSJordan Rose   // - Many CF containers allow objects to escape through custom
4034f7df9beSJordan Rose   //   allocators/deallocators upon container construction. (PR12101)
4044f7df9beSJordan Rose   if (FName.startswith("CF") || FName.startswith("CG")) {
4054f7df9beSJordan Rose     return StrInStrNoCase(FName, "InsertValue")  != StringRef::npos ||
4064f7df9beSJordan Rose            StrInStrNoCase(FName, "AddValue")     != StringRef::npos ||
4074f7df9beSJordan Rose            StrInStrNoCase(FName, "SetValue")     != StringRef::npos ||
4084f7df9beSJordan Rose            StrInStrNoCase(FName, "WithData")     != StringRef::npos ||
4094f7df9beSJordan Rose            StrInStrNoCase(FName, "AppendValue")  != StringRef::npos ||
4104f7df9beSJordan Rose            StrInStrNoCase(FName, "SetAttribute") != StringRef::npos;
4114f7df9beSJordan Rose   }
4124f7df9beSJordan Rose 
4134f7df9beSJordan Rose   return false;
4144f7df9beSJordan Rose }
4154f7df9beSJordan Rose 
4164f7df9beSJordan Rose 
4172a833ca5SJordan Rose const FunctionDecl *SimpleFunctionCall::getDecl() const {
4184f7df9beSJordan Rose   const FunctionDecl *D = getOriginExpr()->getDirectCallee();
4194f7df9beSJordan Rose   if (D)
4204f7df9beSJordan Rose     return D;
4214f7df9beSJordan Rose 
4224f7df9beSJordan Rose   return getSVal(getOriginExpr()->getCallee()).getAsFunctionDecl();
4234f7df9beSJordan Rose }
4244f7df9beSJordan Rose 
4254f7df9beSJordan Rose 
426ce6c99a5SJordan Rose const FunctionDecl *CXXInstanceCall::getDecl() const {
427ce6c99a5SJordan Rose   const CallExpr *CE = cast_or_null<CallExpr>(getOriginExpr());
428ce6c99a5SJordan Rose   if (!CE)
429ce6c99a5SJordan Rose     return AnyFunctionCall::getDecl();
430ce6c99a5SJordan Rose 
431ce6c99a5SJordan Rose   const FunctionDecl *D = CE->getDirectCallee();
432ce6c99a5SJordan Rose   if (D)
433ce6c99a5SJordan Rose     return D;
434ce6c99a5SJordan Rose 
435ce6c99a5SJordan Rose   return getSVal(CE->getCallee()).getAsFunctionDecl();
436ce6c99a5SJordan Rose }
437ce6c99a5SJordan Rose 
43800e780e1SSean Eveson void CXXInstanceCall::getExtraInvalidatedValues(
43900e780e1SSean Eveson     ValueList &Values, RegionAndSymbolInvalidationTraits *ETraits) const {
4404f770deeSDevin Coughlin   SVal ThisVal = getCXXThisVal();
4414f770deeSDevin Coughlin   Values.push_back(ThisVal);
4424f770deeSDevin Coughlin 
4433f072ef8SSean Eveson   // Don't invalidate if the method is const and there are no mutable fields.
4444f770deeSDevin Coughlin   if (const CXXMethodDecl *D = cast_or_null<CXXMethodDecl>(getDecl())) {
4454f770deeSDevin Coughlin     if (!D->isConst())
4464f770deeSDevin Coughlin       return;
4474f770deeSDevin Coughlin     // Get the record decl for the class of 'This'. D->getParent() may return a
4484f770deeSDevin Coughlin     // base class decl, rather than the class of the instance which needs to be
4494f770deeSDevin Coughlin     // checked for mutable fields.
4504f770deeSDevin Coughlin     const Expr *Ex = getCXXThisExpr()->ignoreParenBaseCasts();
4514f770deeSDevin Coughlin     const CXXRecordDecl *ParentRecord = Ex->getType()->getAsCXXRecordDecl();
4524f770deeSDevin Coughlin     if (!ParentRecord || ParentRecord->hasMutableFields())
4534f770deeSDevin Coughlin       return;
4544f770deeSDevin Coughlin     // Preserve CXXThis.
4554f770deeSDevin Coughlin     const MemRegion *ThisRegion = ThisVal.getAsRegion();
4569c76869bSDevin Coughlin     if (!ThisRegion)
4579c76869bSDevin Coughlin       return;
4589c76869bSDevin Coughlin 
4594f770deeSDevin Coughlin     ETraits->setTrait(ThisRegion->getBaseRegion(),
4604f770deeSDevin Coughlin                       RegionAndSymbolInvalidationTraits::TK_PreserveContents);
4614f770deeSDevin Coughlin   }
4624f7df9beSJordan Rose }
4634f7df9beSJordan Rose 
464fcdda361SJordan Rose SVal CXXInstanceCall::getCXXThisVal() const {
465fcdda361SJordan Rose   const Expr *Base = getCXXThisExpr();
466fcdda361SJordan Rose   // FIXME: This doesn't handle an overloaded ->* operator.
467fcdda361SJordan Rose   if (!Base)
468fcdda361SJordan Rose     return UnknownVal();
469fcdda361SJordan Rose 
470fcdda361SJordan Rose   SVal ThisVal = getSVal(Base);
4712fdacbc5SDavid Blaikie   assert(ThisVal.isUnknownOrUndef() || ThisVal.getAs<Loc>());
472fcdda361SJordan Rose   return ThisVal;
473fcdda361SJordan Rose }
474fcdda361SJordan Rose 
4754f7df9beSJordan Rose 
476089c5510STed Kremenek RuntimeDefinition CXXInstanceCall::getRuntimeDefinition() const {
4770f6d63beSJordan Rose   // Do we have a decl at all?
47851bcb226SJordan Rose   const Decl *D = getDecl();
4794f7df9beSJordan Rose   if (!D)
480123af098SAnna Zaks     return RuntimeDefinition();
4814f7df9beSJordan Rose 
4820f6d63beSJordan Rose   // If the method is non-virtual, we know we can inline it.
4834f7df9beSJordan Rose   const CXXMethodDecl *MD = cast<CXXMethodDecl>(D);
4844f7df9beSJordan Rose   if (!MD->isVirtual())
485089c5510STed Kremenek     return AnyFunctionCall::getRuntimeDefinition();
4864f7df9beSJordan Rose 
4870f6d63beSJordan Rose   // Do we know the implicit 'this' object being called?
4880f6d63beSJordan Rose   const MemRegion *R = getCXXThisVal().getAsRegion();
4890f6d63beSJordan Rose   if (!R)
490123af098SAnna Zaks     return RuntimeDefinition();
4910f6d63beSJordan Rose 
4920f6d63beSJordan Rose   // Do we know anything about the type of 'this'?
4934df9d812SGabor Horvath   DynamicTypeInfo DynType = getDynamicTypeInfo(getState(), R);
4940f6d63beSJordan Rose   if (!DynType.isValid())
4950f6d63beSJordan Rose     return RuntimeDefinition();
4960f6d63beSJordan Rose 
4970f6d63beSJordan Rose   // Is the type a C++ class? (This is mostly a defensive check.)
4980f6d63beSJordan Rose   QualType RegionType = DynType.getType()->getPointeeType();
499d1a08b6eSJordan Rose   assert(!RegionType.isNull() && "DynamicTypeInfo should always be a pointer.");
500d1a08b6eSJordan Rose 
5010f6d63beSJordan Rose   const CXXRecordDecl *RD = RegionType->getAsCXXRecordDecl();
50299107208SJordan Rose   if (!RD || !RD->hasDefinition())
5030f6d63beSJordan Rose     return RuntimeDefinition();
5040f6d63beSJordan Rose 
50599c6c2b4SJordan Rose   // Find the decl for this method in that class.
50699c6c2b4SJordan Rose   const CXXMethodDecl *Result = MD->getCorrespondingMethodInClass(RD, true);
50781456d9fSJordan Rose   if (!Result) {
50881456d9fSJordan Rose     // We might not even get the original statically-resolved method due to
50981456d9fSJordan Rose     // some particularly nasty casting (e.g. casts to sister classes).
51081456d9fSJordan Rose     // However, we should at least be able to search up and down our own class
51181456d9fSJordan Rose     // hierarchy, and some real bugs have been caught by checking this.
51281456d9fSJordan Rose     assert(!RD->isDerivedFrom(MD->getParent()) && "Couldn't find known method");
513d44977efSJordan Rose 
514d44977efSJordan Rose     // FIXME: This is checking that our DynamicTypeInfo is at least as good as
515d44977efSJordan Rose     // the static type. However, because we currently don't update
516d44977efSJordan Rose     // DynamicTypeInfo when an object is cast, we can't actually be sure the
517d44977efSJordan Rose     // DynamicTypeInfo is up to date. This assert should be re-enabled once
518d44977efSJordan Rose     // this is fixed. <rdar://problem/12287087>
519d44977efSJordan Rose     //assert(!MD->getParent()->isDerivedFrom(RD) && "Bad DynamicTypeInfo");
520d44977efSJordan Rose 
52181456d9fSJordan Rose     return RuntimeDefinition();
52281456d9fSJordan Rose   }
5230f6d63beSJordan Rose 
5240f6d63beSJordan Rose   // Does the decl that we found have an implementation?
5250f6d63beSJordan Rose   const FunctionDecl *Definition;
5260f6d63beSJordan Rose   if (!Result->hasBody(Definition))
5270f6d63beSJordan Rose     return RuntimeDefinition();
5280f6d63beSJordan Rose 
5290f6d63beSJordan Rose   // We found a definition. If we're not sure that this devirtualization is
5300f6d63beSJordan Rose   // actually what will happen at runtime, make sure to provide the region so
5310f6d63beSJordan Rose   // that ExprEngine can decide what to do with it.
5320f6d63beSJordan Rose   if (DynType.canBeASubClass())
5330f6d63beSJordan Rose     return RuntimeDefinition(Definition, R->StripCasts());
5340dbb783cSCraig Topper   return RuntimeDefinition(Definition, /*DispatchRegion=*/nullptr);
5354f7df9beSJordan Rose }
5364f7df9beSJordan Rose 
53742e8d649SJordan Rose void CXXInstanceCall::getInitialStackFrameContents(
53842e8d649SJordan Rose                                             const StackFrameContext *CalleeCtx,
53942e8d649SJordan Rose                                             BindingsTy &Bindings) const {
54042e8d649SJordan Rose   AnyFunctionCall::getInitialStackFrameContents(CalleeCtx, Bindings);
54142e8d649SJordan Rose 
54202e5309bSJordan Rose   // Handle the binding of 'this' in the new stack frame.
54342e8d649SJordan Rose   SVal ThisVal = getCXXThisVal();
54442e8d649SJordan Rose   if (!ThisVal.isUnknown()) {
54502e5309bSJordan Rose     ProgramStateManager &StateMgr = getState()->getStateManager();
54602e5309bSJordan Rose     SValBuilder &SVB = StateMgr.getSValBuilder();
54702e5309bSJordan Rose 
54842e8d649SJordan Rose     const CXXMethodDecl *MD = cast<CXXMethodDecl>(CalleeCtx->getDecl());
54942e8d649SJordan Rose     Loc ThisLoc = SVB.getCXXThis(MD, CalleeCtx);
55002e5309bSJordan Rose 
55131c3fa9cSJordan Rose     // If we devirtualized to a different member function, we need to make sure
55231c3fa9cSJordan Rose     // we have the proper layering of CXXBaseObjectRegions.
55331c3fa9cSJordan Rose     if (MD->getCanonicalDecl() != getDecl()->getCanonicalDecl()) {
554710f6b12SJordan Rose       ASTContext &Ctx = SVB.getContext();
55502e5309bSJordan Rose       const CXXRecordDecl *Class = MD->getParent();
556710f6b12SJordan Rose       QualType Ty = Ctx.getPointerType(Ctx.getRecordType(Class));
55702e5309bSJordan Rose 
558710f6b12SJordan Rose       // FIXME: CallEvent maybe shouldn't be directly accessing StoreManager.
559710f6b12SJordan Rose       bool Failed;
56044583ce6SGabor Horvath       ThisVal = StateMgr.getStoreManager().attemptDownCast(ThisVal, Ty, Failed);
561710f6b12SJordan Rose       assert(!Failed && "Calling an incorrectly devirtualized method");
56202e5309bSJordan Rose     }
56302e5309bSJordan Rose 
56431c3fa9cSJordan Rose     if (!ThisVal.isUnknown())
56542e8d649SJordan Rose       Bindings.push_back(std::make_pair(ThisLoc, ThisVal));
56642e8d649SJordan Rose   }
56742e8d649SJordan Rose }
56842e8d649SJordan Rose 
56942e8d649SJordan Rose 
5704f7df9beSJordan Rose 
57192e1449bSJordan Rose const Expr *CXXMemberCall::getCXXThisExpr() const {
57292e1449bSJordan Rose   return getOriginExpr()->getImplicitObjectArgument();
5734f7df9beSJordan Rose }
5744f7df9beSJordan Rose 
575089c5510STed Kremenek RuntimeDefinition CXXMemberCall::getRuntimeDefinition() const {
57612f669e3SJordan Rose   // C++11 [expr.call]p1: ...If the selected function is non-virtual, or if the
57712f669e3SJordan Rose   // id-expression in the class member access expression is a qualified-id,
57812f669e3SJordan Rose   // that function is called. Otherwise, its final overrider in the dynamic type
57912f669e3SJordan Rose   // of the object expression is called.
58012f669e3SJordan Rose   if (const MemberExpr *ME = dyn_cast<MemberExpr>(getOriginExpr()->getCallee()))
58112f669e3SJordan Rose     if (ME->hasQualifier())
582089c5510STed Kremenek       return AnyFunctionCall::getRuntimeDefinition();
58312f669e3SJordan Rose 
584089c5510STed Kremenek   return CXXInstanceCall::getRuntimeDefinition();
58512f669e3SJordan Rose }
58612f669e3SJordan Rose 
5874f7df9beSJordan Rose 
58892e1449bSJordan Rose const Expr *CXXMemberOperatorCall::getCXXThisExpr() const {
58992e1449bSJordan Rose   return getOriginExpr()->getArg(0);
5904f7df9beSJordan Rose }
5914f7df9beSJordan Rose 
5924f7df9beSJordan Rose 
5934f7df9beSJordan Rose const BlockDataRegion *BlockCall::getBlockRegion() const {
5944f7df9beSJordan Rose   const Expr *Callee = getOriginExpr()->getCallee();
5954f7df9beSJordan Rose   const MemRegion *DataReg = getSVal(Callee).getAsRegion();
5964f7df9beSJordan Rose 
5974f7df9beSJordan Rose   return dyn_cast_or_null<BlockDataRegion>(DataReg);
5984f7df9beSJordan Rose }
5994f7df9beSJordan Rose 
6002ff16004STed Kremenek ArrayRef<ParmVarDecl*> BlockCall::parameters() const {
6012a833ca5SJordan Rose   const BlockDecl *D = getDecl();
6024f7df9beSJordan Rose   if (!D)
6030dbb783cSCraig Topper     return nullptr;
6042ff16004STed Kremenek   return D->parameters();
6054f7df9beSJordan Rose }
6064f7df9beSJordan Rose 
6074f770deeSDevin Coughlin void BlockCall::getExtraInvalidatedValues(ValueList &Values,
6084f770deeSDevin Coughlin                   RegionAndSymbolInvalidationTraits *ETraits) const {
6094f7df9beSJordan Rose   // FIXME: This also needs to invalidate captured globals.
6104f7df9beSJordan Rose   if (const MemRegion *R = getBlockRegion())
61160bf5f45SAnna Zaks     Values.push_back(loc::MemRegionVal(R));
6124f7df9beSJordan Rose }
6134f7df9beSJordan Rose 
61442e8d649SJordan Rose void BlockCall::getInitialStackFrameContents(const StackFrameContext *CalleeCtx,
61542e8d649SJordan Rose                                              BindingsTy &Bindings) const {
61642e8d649SJordan Rose   SValBuilder &SVB = getState()->getStateManager().getSValBuilder();
617ebeed880SDevin Coughlin   ArrayRef<ParmVarDecl*> Params;
618ebeed880SDevin Coughlin   if (isConversionFromLambda()) {
619ebeed880SDevin Coughlin     auto *LambdaOperatorDecl = cast<CXXMethodDecl>(CalleeCtx->getDecl());
620ebeed880SDevin Coughlin     Params = LambdaOperatorDecl->parameters();
621ebeed880SDevin Coughlin 
622ebeed880SDevin Coughlin     // For blocks converted from a C++ lambda, the callee declaration is the
6235690454bSSanjay Patel     // operator() method on the lambda so we bind "this" to
624ebeed880SDevin Coughlin     // the lambda captured by the block.
625ebeed880SDevin Coughlin     const VarRegion *CapturedLambdaRegion = getRegionStoringCapturedLambda();
626ebeed880SDevin Coughlin     SVal ThisVal = loc::MemRegionVal(CapturedLambdaRegion);
627ebeed880SDevin Coughlin     Loc ThisLoc = SVB.getCXXThis(LambdaOperatorDecl, CalleeCtx);
628ebeed880SDevin Coughlin     Bindings.push_back(std::make_pair(ThisLoc, ThisVal));
629ebeed880SDevin Coughlin   } else {
630ebeed880SDevin Coughlin     Params = cast<BlockDecl>(CalleeCtx->getDecl())->parameters();
631ebeed880SDevin Coughlin   }
632ebeed880SDevin Coughlin 
63342e8d649SJordan Rose   addParameterValuesToBindings(CalleeCtx, Bindings, SVB, *this,
634ebeed880SDevin Coughlin                                Params);
63542e8d649SJordan Rose }
63642e8d649SJordan Rose 
63742e8d649SJordan Rose 
6384f7df9beSJordan Rose SVal CXXConstructorCall::getCXXThisVal() const {
6394f7df9beSJordan Rose   if (Data)
6404f7df9beSJordan Rose     return loc::MemRegionVal(static_cast<const MemRegion *>(Data));
6414f7df9beSJordan Rose   return UnknownVal();
6424f7df9beSJordan Rose }
6434f7df9beSJordan Rose 
6444f770deeSDevin Coughlin void CXXConstructorCall::getExtraInvalidatedValues(ValueList &Values,
6454f770deeSDevin Coughlin                            RegionAndSymbolInvalidationTraits *ETraits) const {
6464f7df9beSJordan Rose   if (Data)
64760bf5f45SAnna Zaks     Values.push_back(loc::MemRegionVal(static_cast<const MemRegion *>(Data)));
6484f7df9beSJordan Rose }
6494f7df9beSJordan Rose 
65042e8d649SJordan Rose void CXXConstructorCall::getInitialStackFrameContents(
65142e8d649SJordan Rose                                              const StackFrameContext *CalleeCtx,
65242e8d649SJordan Rose                                              BindingsTy &Bindings) const {
65342e8d649SJordan Rose   AnyFunctionCall::getInitialStackFrameContents(CalleeCtx, Bindings);
65442e8d649SJordan Rose 
65542e8d649SJordan Rose   SVal ThisVal = getCXXThisVal();
65642e8d649SJordan Rose   if (!ThisVal.isUnknown()) {
65742e8d649SJordan Rose     SValBuilder &SVB = getState()->getStateManager().getSValBuilder();
65842e8d649SJordan Rose     const CXXMethodDecl *MD = cast<CXXMethodDecl>(CalleeCtx->getDecl());
65942e8d649SJordan Rose     Loc ThisLoc = SVB.getCXXThis(MD, CalleeCtx);
66042e8d649SJordan Rose     Bindings.push_back(std::make_pair(ThisLoc, ThisVal));
66142e8d649SJordan Rose   }
66242e8d649SJordan Rose }
66342e8d649SJordan Rose 
6644f7df9beSJordan Rose SVal CXXDestructorCall::getCXXThisVal() const {
6654f7df9beSJordan Rose   if (Data)
6662bc9674bSJordan Rose     return loc::MemRegionVal(DtorDataTy::getFromOpaqueValue(Data).getPointer());
6674f7df9beSJordan Rose   return UnknownVal();
6684f7df9beSJordan Rose }
6694f7df9beSJordan Rose 
670089c5510STed Kremenek RuntimeDefinition CXXDestructorCall::getRuntimeDefinition() const {
6712bc9674bSJordan Rose   // Base destructors are always called non-virtually.
6722bc9674bSJordan Rose   // Skip CXXInstanceCall's devirtualization logic in this case.
6732bc9674bSJordan Rose   if (isBaseDestructor())
674089c5510STed Kremenek     return AnyFunctionCall::getRuntimeDefinition();
6752bc9674bSJordan Rose 
676089c5510STed Kremenek   return CXXInstanceCall::getRuntimeDefinition();
6772bc9674bSJordan Rose }
6782bc9674bSJordan Rose 
6792ff16004STed Kremenek ArrayRef<ParmVarDecl*> ObjCMethodCall::parameters() const {
68042e8d649SJordan Rose   const ObjCMethodDecl *D = getDecl();
6814f7df9beSJordan Rose   if (!D)
6825fc8fc2dSCraig Topper     return None;
6832ff16004STed Kremenek   return D->parameters();
6844f7df9beSJordan Rose }
6854f7df9beSJordan Rose 
686069a1073SDevin Coughlin void ObjCMethodCall::getExtraInvalidatedValues(
687069a1073SDevin Coughlin     ValueList &Values, RegionAndSymbolInvalidationTraits *ETraits) const {
688069a1073SDevin Coughlin 
689069a1073SDevin Coughlin   // If the method call is a setter for property known to be backed by
690069a1073SDevin Coughlin   // an instance variable, don't invalidate the entire receiver, just
691069a1073SDevin Coughlin   // the storage for that instance variable.
692069a1073SDevin Coughlin   if (const ObjCPropertyDecl *PropDecl = getAccessedProperty()) {
693069a1073SDevin Coughlin     if (const ObjCIvarDecl *PropIvar = PropDecl->getPropertyIvarDecl()) {
694069a1073SDevin Coughlin       SVal IvarLVal = getState()->getLValue(PropIvar, getReceiverSVal());
695069a1073SDevin Coughlin       const MemRegion *IvarRegion = IvarLVal.getAsRegion();
696069a1073SDevin Coughlin       ETraits->setTrait(
697069a1073SDevin Coughlin           IvarRegion,
698069a1073SDevin Coughlin           RegionAndSymbolInvalidationTraits::TK_DoNotInvalidateSuperRegion);
699069a1073SDevin Coughlin       ETraits->setTrait(IvarRegion,
700069a1073SDevin Coughlin                         RegionAndSymbolInvalidationTraits::TK_SuppressEscape);
701069a1073SDevin Coughlin       Values.push_back(IvarLVal);
702069a1073SDevin Coughlin       return;
703069a1073SDevin Coughlin     }
704069a1073SDevin Coughlin   }
705069a1073SDevin Coughlin 
70660bf5f45SAnna Zaks   Values.push_back(getReceiverSVal());
7074f7df9beSJordan Rose }
7084f7df9beSJordan Rose 
7093d5d3d3eSAnna Zaks SVal ObjCMethodCall::getSelfSVal() const {
7103d5d3d3eSAnna Zaks   const LocationContext *LCtx = getLocationContext();
7113d5d3d3eSAnna Zaks   const ImplicitParamDecl *SelfDecl = LCtx->getSelfDecl();
7123d5d3d3eSAnna Zaks   if (!SelfDecl)
7133d5d3d3eSAnna Zaks     return SVal();
7143d5d3d3eSAnna Zaks   return getState()->getSVal(getState()->getRegion(SelfDecl, LCtx));
7153d5d3d3eSAnna Zaks }
7163d5d3d3eSAnna Zaks 
7174f7df9beSJordan Rose SVal ObjCMethodCall::getReceiverSVal() const {
7184f7df9beSJordan Rose   // FIXME: Is this the best way to handle class receivers?
7194f7df9beSJordan Rose   if (!isInstanceMessage())
7204f7df9beSJordan Rose     return UnknownVal();
7214f7df9beSJordan Rose 
722472dbcf1SAnna Zaks   if (const Expr *RecE = getOriginExpr()->getInstanceReceiver())
723472dbcf1SAnna Zaks     return getSVal(RecE);
7244f7df9beSJordan Rose 
7254f7df9beSJordan Rose   // An instance message with no expression means we are sending to super.
7264f7df9beSJordan Rose   // In this case the object reference is the same as 'self'.
7273d5d3d3eSAnna Zaks   assert(getOriginExpr()->getReceiverKind() == ObjCMessageExpr::SuperInstance);
7283d5d3d3eSAnna Zaks   SVal SelfVal = getSelfSVal();
7293d5d3d3eSAnna Zaks   assert(SelfVal.isValid() && "Calling super but not in ObjC method");
7303d5d3d3eSAnna Zaks   return SelfVal;
7313d5d3d3eSAnna Zaks }
7323d5d3d3eSAnna Zaks 
7333d5d3d3eSAnna Zaks bool ObjCMethodCall::isReceiverSelfOrSuper() const {
7343d5d3d3eSAnna Zaks   if (getOriginExpr()->getReceiverKind() == ObjCMessageExpr::SuperInstance ||
7353d5d3d3eSAnna Zaks       getOriginExpr()->getReceiverKind() == ObjCMessageExpr::SuperClass)
7363d5d3d3eSAnna Zaks       return true;
7373d5d3d3eSAnna Zaks 
7383d5d3d3eSAnna Zaks   if (!isInstanceMessage())
7393d5d3d3eSAnna Zaks     return false;
7403d5d3d3eSAnna Zaks 
7413d5d3d3eSAnna Zaks   SVal RecVal = getSVal(getOriginExpr()->getInstanceReceiver());
7423d5d3d3eSAnna Zaks 
7433d5d3d3eSAnna Zaks   return (RecVal == getSelfSVal());
7444f7df9beSJordan Rose }
7454f7df9beSJordan Rose 
7464f7df9beSJordan Rose SourceRange ObjCMethodCall::getSourceRange() const {
7474f7df9beSJordan Rose   switch (getMessageKind()) {
7484f7df9beSJordan Rose   case OCM_Message:
7494f7df9beSJordan Rose     return getOriginExpr()->getSourceRange();
7504f7df9beSJordan Rose   case OCM_PropertyAccess:
7514f7df9beSJordan Rose   case OCM_Subscript:
7524f7df9beSJordan Rose     return getContainingPseudoObjectExpr()->getSourceRange();
7534f7df9beSJordan Rose   }
7544f7df9beSJordan Rose   llvm_unreachable("unknown message kind");
7554f7df9beSJordan Rose }
7564f7df9beSJordan Rose 
7574f7df9beSJordan Rose typedef llvm::PointerIntPair<const PseudoObjectExpr *, 2> ObjCMessageDataTy;
7584f7df9beSJordan Rose 
7594f7df9beSJordan Rose const PseudoObjectExpr *ObjCMethodCall::getContainingPseudoObjectExpr() const {
7600dbb783cSCraig Topper   assert(Data && "Lazy lookup not yet performed.");
7614f7df9beSJordan Rose   assert(getMessageKind() != OCM_Message && "Explicit message send.");
7624f7df9beSJordan Rose   return ObjCMessageDataTy::getFromOpaqueValue(Data).getPointer();
7634f7df9beSJordan Rose }
7644f7df9beSJordan Rose 
765069a1073SDevin Coughlin static const Expr *
766069a1073SDevin Coughlin getSyntacticFromForPseudoObjectExpr(const PseudoObjectExpr *POE) {
767069a1073SDevin Coughlin   const Expr *Syntactic = POE->getSyntacticForm();
768069a1073SDevin Coughlin 
769069a1073SDevin Coughlin   // This handles the funny case of assigning to the result of a getter.
770069a1073SDevin Coughlin   // This can happen if the getter returns a non-const reference.
771069a1073SDevin Coughlin   if (const BinaryOperator *BO = dyn_cast<BinaryOperator>(Syntactic))
772069a1073SDevin Coughlin     Syntactic = BO->getLHS();
773069a1073SDevin Coughlin 
774069a1073SDevin Coughlin   return Syntactic;
775069a1073SDevin Coughlin }
776069a1073SDevin Coughlin 
7774f7df9beSJordan Rose ObjCMessageKind ObjCMethodCall::getMessageKind() const {
7780dbb783cSCraig Topper   if (!Data) {
779226a56faSAnna Zaks 
780226a56faSAnna Zaks     // Find the parent, ignoring implicit casts.
7814f7df9beSJordan Rose     ParentMap &PM = getLocationContext()->getParentMap();
7825770c038SJordan Rose     const Stmt *S = PM.getParentIgnoreParenCasts(getOriginExpr());
783226a56faSAnna Zaks 
784226a56faSAnna Zaks     // Check if parent is a PseudoObjectExpr.
7854f7df9beSJordan Rose     if (const PseudoObjectExpr *POE = dyn_cast_or_null<PseudoObjectExpr>(S)) {
786069a1073SDevin Coughlin       const Expr *Syntactic = getSyntacticFromForPseudoObjectExpr(POE);
7874f7df9beSJordan Rose 
7884f7df9beSJordan Rose       ObjCMessageKind K;
7894f7df9beSJordan Rose       switch (Syntactic->getStmtClass()) {
7904f7df9beSJordan Rose       case Stmt::ObjCPropertyRefExprClass:
7914f7df9beSJordan Rose         K = OCM_PropertyAccess;
7924f7df9beSJordan Rose         break;
7934f7df9beSJordan Rose       case Stmt::ObjCSubscriptRefExprClass:
7944f7df9beSJordan Rose         K = OCM_Subscript;
7954f7df9beSJordan Rose         break;
7964f7df9beSJordan Rose       default:
7974f7df9beSJordan Rose         // FIXME: Can this ever happen?
7984f7df9beSJordan Rose         K = OCM_Message;
7994f7df9beSJordan Rose         break;
8004f7df9beSJordan Rose       }
8014f7df9beSJordan Rose 
8024f7df9beSJordan Rose       if (K != OCM_Message) {
8034f7df9beSJordan Rose         const_cast<ObjCMethodCall *>(this)->Data
8044f7df9beSJordan Rose           = ObjCMessageDataTy(POE, K).getOpaqueValue();
8054f7df9beSJordan Rose         assert(getMessageKind() == K);
8064f7df9beSJordan Rose         return K;
8074f7df9beSJordan Rose       }
8084f7df9beSJordan Rose     }
8094f7df9beSJordan Rose 
8104f7df9beSJordan Rose     const_cast<ObjCMethodCall *>(this)->Data
8110dbb783cSCraig Topper       = ObjCMessageDataTy(nullptr, 1).getOpaqueValue();
8124f7df9beSJordan Rose     assert(getMessageKind() == OCM_Message);
8134f7df9beSJordan Rose     return OCM_Message;
8144f7df9beSJordan Rose   }
8154f7df9beSJordan Rose 
8164f7df9beSJordan Rose   ObjCMessageDataTy Info = ObjCMessageDataTy::getFromOpaqueValue(Data);
8174f7df9beSJordan Rose   if (!Info.getPointer())
8184f7df9beSJordan Rose     return OCM_Message;
8194f7df9beSJordan Rose   return static_cast<ObjCMessageKind>(Info.getInt());
8204f7df9beSJordan Rose }
8214f7df9beSJordan Rose 
822069a1073SDevin Coughlin const ObjCPropertyDecl *ObjCMethodCall::getAccessedProperty() const {
823069a1073SDevin Coughlin   // Look for properties accessed with property syntax (foo.bar = ...)
824069a1073SDevin Coughlin   if ( getMessageKind() == OCM_PropertyAccess) {
825069a1073SDevin Coughlin     const PseudoObjectExpr *POE = getContainingPseudoObjectExpr();
826069a1073SDevin Coughlin     assert(POE && "Property access without PseudoObjectExpr?");
827069a1073SDevin Coughlin 
828069a1073SDevin Coughlin     const Expr *Syntactic = getSyntacticFromForPseudoObjectExpr(POE);
829069a1073SDevin Coughlin     auto *RefExpr = cast<ObjCPropertyRefExpr>(Syntactic);
830069a1073SDevin Coughlin 
831069a1073SDevin Coughlin     if (RefExpr->isExplicitProperty())
832069a1073SDevin Coughlin       return RefExpr->getExplicitProperty();
833069a1073SDevin Coughlin   }
834069a1073SDevin Coughlin 
835069a1073SDevin Coughlin   // Look for properties accessed with method syntax ([foo setBar:...]).
836069a1073SDevin Coughlin   const ObjCMethodDecl *MD = getDecl();
837069a1073SDevin Coughlin   if (!MD || !MD->isPropertyAccessor())
838069a1073SDevin Coughlin     return nullptr;
839069a1073SDevin Coughlin 
840069a1073SDevin Coughlin   // Note: This is potentially quite slow.
841069a1073SDevin Coughlin   return MD->findPropertyDecl();
842069a1073SDevin Coughlin }
843920af014SAnna Zaks 
844920af014SAnna Zaks bool ObjCMethodCall::canBeOverridenInSubclass(ObjCInterfaceDecl *IDecl,
845920af014SAnna Zaks                                              Selector Sel) const {
846920af014SAnna Zaks   assert(IDecl);
847920af014SAnna Zaks   const SourceManager &SM =
848920af014SAnna Zaks     getState()->getStateManager().getContext().getSourceManager();
849920af014SAnna Zaks 
850920af014SAnna Zaks   // If the class interface is declared inside the main file, assume it is not
851920af014SAnna Zaks   // subcassed.
852920af014SAnna Zaks   // TODO: It could actually be subclassed if the subclass is private as well.
853920af014SAnna Zaks   // This is probably very rare.
854920af014SAnna Zaks   SourceLocation InterfLoc = IDecl->getEndOfDefinitionLoc();
8555ba37d52SEli Friedman   if (InterfLoc.isValid() && SM.isInMainFile(InterfLoc))
856920af014SAnna Zaks     return false;
857920af014SAnna Zaks 
8586ddb6b1aSAnna Zaks   // Assume that property accessors are not overridden.
8596ddb6b1aSAnna Zaks   if (getMessageKind() == OCM_PropertyAccess)
8606ddb6b1aSAnna Zaks     return false;
861920af014SAnna Zaks 
862920af014SAnna Zaks   // We assume that if the method is public (declared outside of main file) or
863920af014SAnna Zaks   // has a parent which publicly declares the method, the method could be
864920af014SAnna Zaks   // overridden in a subclass.
865920af014SAnna Zaks 
866920af014SAnna Zaks   // Find the first declaration in the class hierarchy that declares
867920af014SAnna Zaks   // the selector.
8680dbb783cSCraig Topper   ObjCMethodDecl *D = nullptr;
869920af014SAnna Zaks   while (true) {
870920af014SAnna Zaks     D = IDecl->lookupMethod(Sel, true);
871920af014SAnna Zaks 
872920af014SAnna Zaks     // Cannot find a public definition.
873920af014SAnna Zaks     if (!D)
874920af014SAnna Zaks       return false;
875920af014SAnna Zaks 
876920af014SAnna Zaks     // If outside the main file,
8775ba37d52SEli Friedman     if (D->getLocation().isValid() && !SM.isInMainFile(D->getLocation()))
878920af014SAnna Zaks       return true;
879920af014SAnna Zaks 
880920af014SAnna Zaks     if (D->isOverriding()) {
881920af014SAnna Zaks       // Search in the superclass on the next iteration.
882920af014SAnna Zaks       IDecl = D->getClassInterface();
883920af014SAnna Zaks       if (!IDecl)
884920af014SAnna Zaks         return false;
885920af014SAnna Zaks 
886920af014SAnna Zaks       IDecl = IDecl->getSuperClass();
887920af014SAnna Zaks       if (!IDecl)
888920af014SAnna Zaks         return false;
889920af014SAnna Zaks 
890920af014SAnna Zaks       continue;
891920af014SAnna Zaks     }
892920af014SAnna Zaks 
893920af014SAnna Zaks     return false;
894920af014SAnna Zaks   };
895920af014SAnna Zaks 
896920af014SAnna Zaks   llvm_unreachable("The while loop should always terminate.");
897920af014SAnna Zaks }
898920af014SAnna Zaks 
899*dcfc1914SAnna Zaks static const ObjCMethodDecl *findDefiningRedecl(const ObjCMethodDecl *MD) {
900*dcfc1914SAnna Zaks   if (!MD)
901*dcfc1914SAnna Zaks     return MD;
902*dcfc1914SAnna Zaks 
903*dcfc1914SAnna Zaks   // Find the redeclaration that defines the method.
904*dcfc1914SAnna Zaks   if (!MD->hasBody()) {
905*dcfc1914SAnna Zaks     for (auto I : MD->redecls())
906*dcfc1914SAnna Zaks       if (I->hasBody())
907*dcfc1914SAnna Zaks         MD = cast<ObjCMethodDecl>(I);
908*dcfc1914SAnna Zaks   }
909*dcfc1914SAnna Zaks   return MD;
910*dcfc1914SAnna Zaks }
911*dcfc1914SAnna Zaks 
912*dcfc1914SAnna Zaks static bool isCallToSelfClass(const ObjCMessageExpr *ME) {
913*dcfc1914SAnna Zaks   const Expr* InstRec = ME->getInstanceReceiver();
914*dcfc1914SAnna Zaks   if (!InstRec)
915*dcfc1914SAnna Zaks     return false;
916*dcfc1914SAnna Zaks   const auto *InstRecIg = dyn_cast<DeclRefExpr>(InstRec->IgnoreParenImpCasts());
917*dcfc1914SAnna Zaks 
918*dcfc1914SAnna Zaks   // Check that receiver is called 'self'.
919*dcfc1914SAnna Zaks   if (!InstRecIg || !InstRecIg->getFoundDecl() ||
920*dcfc1914SAnna Zaks       !InstRecIg->getFoundDecl()->getName().equals("self"))
921*dcfc1914SAnna Zaks     return false;
922*dcfc1914SAnna Zaks 
923*dcfc1914SAnna Zaks   // Check that the method name is 'class'.
924*dcfc1914SAnna Zaks   if (ME->getSelector().getNumArgs() != 0 ||
925*dcfc1914SAnna Zaks       !ME->getSelector().getNameForSlot(0).equals("class"))
926*dcfc1914SAnna Zaks     return false;
927*dcfc1914SAnna Zaks 
928*dcfc1914SAnna Zaks   return true;
929*dcfc1914SAnna Zaks }
930*dcfc1914SAnna Zaks 
931089c5510STed Kremenek RuntimeDefinition ObjCMethodCall::getRuntimeDefinition() const {
93263282aefSAnna Zaks   const ObjCMessageExpr *E = getOriginExpr();
93363282aefSAnna Zaks   assert(E);
9345808eb80SAnna Zaks   Selector Sel = E->getSelector();
9354f7df9beSJordan Rose 
93663282aefSAnna Zaks   if (E->isInstanceMessage()) {
9375808eb80SAnna Zaks 
9382c4555adSEric Christopher     // Find the receiver type.
9390dbb783cSCraig Topper     const ObjCObjectPointerType *ReceiverT = nullptr;
94075f49a9cSAnna Zaks     bool CanBeSubClassed = false;
9415808eb80SAnna Zaks     QualType SupersType = E->getSuperType();
9420dbb783cSCraig Topper     const MemRegion *Receiver = nullptr;
943123af098SAnna Zaks 
9445808eb80SAnna Zaks     if (!SupersType.isNull()) {
945*dcfc1914SAnna Zaks       // The receiver is guaranteed to be 'super' in this case.
946123af098SAnna Zaks       // Super always means the type of immediate predecessor to the method
947123af098SAnna Zaks       // where the call occurs.
94875930b65SAnna Zaks       ReceiverT = cast<ObjCObjectPointerType>(SupersType);
9495808eb80SAnna Zaks     } else {
950123af098SAnna Zaks       Receiver = getReceiverSVal().getAsRegion();
9516a97d92eSJordan Rose       if (!Receiver)
952123af098SAnna Zaks         return RuntimeDefinition();
9536a97d92eSJordan Rose 
9544df9d812SGabor Horvath       DynamicTypeInfo DTI = getDynamicTypeInfo(getState(), Receiver);
95575f49a9cSAnna Zaks       QualType DynType = DTI.getType();
95675f49a9cSAnna Zaks       CanBeSubClassed = DTI.canBeASubClass();
957*dcfc1914SAnna Zaks       ReceiverT = dyn_cast<ObjCObjectPointerType>(DynType.getCanonicalType());
95875f49a9cSAnna Zaks 
95975f49a9cSAnna Zaks       if (ReceiverT && CanBeSubClassed)
96075f49a9cSAnna Zaks         if (ObjCInterfaceDecl *IDecl = ReceiverT->getInterfaceDecl())
96175f49a9cSAnna Zaks           if (!canBeOverridenInSubclass(IDecl, Sel))
96275f49a9cSAnna Zaks             CanBeSubClassed = false;
9634f7df9beSJordan Rose     }
9644f7df9beSJordan Rose 
965*dcfc1914SAnna Zaks     // Handle special cases of '[self classMethod]' and
966*dcfc1914SAnna Zaks     // '[[self class] classMethod]', which are treated by the compiler as
967*dcfc1914SAnna Zaks     // instance (not class) messages. We will statically dispatch to those.
968*dcfc1914SAnna Zaks     if (auto *PT = dyn_cast_or_null<ObjCObjectPointerType>(ReceiverT)) {
969*dcfc1914SAnna Zaks       // For [self classMethod], return the compiler visible declaration.
970*dcfc1914SAnna Zaks       if (PT->getObjectType()->isObjCClass() &&
971*dcfc1914SAnna Zaks           Receiver == getSelfSVal().getAsRegion())
972*dcfc1914SAnna Zaks         return RuntimeDefinition(findDefiningRedecl(E->getMethodDecl()));
973*dcfc1914SAnna Zaks 
974*dcfc1914SAnna Zaks       // Similarly, handle [[self class] classMethod].
975*dcfc1914SAnna Zaks       // TODO: We are currently doing a syntactic match for this pattern with is
976*dcfc1914SAnna Zaks       // limiting as the test cases in Analysis/inlining/InlineObjCClassMethod.m
977*dcfc1914SAnna Zaks       // shows. A better way would be to associate the meta type with the symbol
978*dcfc1914SAnna Zaks       // using the dynamic type info tracking and use it here. We can add a new
979*dcfc1914SAnna Zaks       // SVal for ObjC 'Class' values that know what interface declaration they
980*dcfc1914SAnna Zaks       // come from. Then 'self' in a class method would be filled in with
981*dcfc1914SAnna Zaks       // something meaningful in ObjCMethodCall::getReceiverSVal() and we could
982*dcfc1914SAnna Zaks       // do proper dynamic dispatch for class methods just like we do for
983*dcfc1914SAnna Zaks       // instance methods now.
984*dcfc1914SAnna Zaks       if (E->getInstanceReceiver())
985*dcfc1914SAnna Zaks         if (const auto *M = dyn_cast<ObjCMessageExpr>(E->getInstanceReceiver()))
986*dcfc1914SAnna Zaks           if (isCallToSelfClass(M))
987*dcfc1914SAnna Zaks             return RuntimeDefinition(findDefiningRedecl(E->getMethodDecl()));
988*dcfc1914SAnna Zaks     }
989*dcfc1914SAnna Zaks 
990*dcfc1914SAnna Zaks     // Lookup the instance method implementation.
9915808eb80SAnna Zaks     if (ReceiverT)
992920af014SAnna Zaks       if (ObjCInterfaceDecl *IDecl = ReceiverT->getInterfaceDecl()) {
993245e45afSTed Kremenek         // Repeatedly calling lookupPrivateMethod() is expensive, especially
994245e45afSTed Kremenek         // when in many cases it returns null.  We cache the results so
995245e45afSTed Kremenek         // that repeated queries on the same ObjCIntefaceDecl and Selector
996245e45afSTed Kremenek         // don't incur the same cost.  On some test cases, we can see the
997245e45afSTed Kremenek         // same query being issued thousands of times.
998245e45afSTed Kremenek         //
999245e45afSTed Kremenek         // NOTE: This cache is essentially a "global" variable, but it
1000245e45afSTed Kremenek         // only gets lazily created when we get here.  The value of the
1001245e45afSTed Kremenek         // cache probably comes from it being global across ExprEngines,
1002245e45afSTed Kremenek         // where the same queries may get issued.  If we are worried about
1003245e45afSTed Kremenek         // concurrency, or possibly loading/unloading ASTs, etc., we may
1004245e45afSTed Kremenek         // need to revisit this someday.  In terms of memory, this table
1005245e45afSTed Kremenek         // stays around until clang quits, which also may be bad if we
1006245e45afSTed Kremenek         // need to release memory.
1007245e45afSTed Kremenek         typedef std::pair<const ObjCInterfaceDecl*, Selector>
1008245e45afSTed Kremenek                 PrivateMethodKey;
1009245e45afSTed Kremenek         typedef llvm::DenseMap<PrivateMethodKey,
101005785d16SDavid Blaikie                                Optional<const ObjCMethodDecl *> >
1011245e45afSTed Kremenek                 PrivateMethodCache;
1012245e45afSTed Kremenek 
1013245e45afSTed Kremenek         static PrivateMethodCache PMC;
101405785d16SDavid Blaikie         Optional<const ObjCMethodDecl *> &Val = PMC[std::make_pair(IDecl, Sel)];
1015245e45afSTed Kremenek 
1016245e45afSTed Kremenek         // Query lookupPrivateMethod() if the cache does not hit.
10171a866cd5SJordan Rose         if (!Val.hasValue()) {
1018245e45afSTed Kremenek           Val = IDecl->lookupPrivateMethod(Sel);
1019245e45afSTed Kremenek 
10201a866cd5SJordan Rose           // If the method is a property accessor, we should try to "inline" it
10211a866cd5SJordan Rose           // even if we don't actually have an implementation.
10221a866cd5SJordan Rose           if (!*Val)
10231a866cd5SJordan Rose             if (const ObjCMethodDecl *CompileTimeMD = E->getMethodDecl())
1024c239dd13SDevin Coughlin               if (CompileTimeMD->isPropertyAccessor()) {
1025c239dd13SDevin Coughlin                 if (!CompileTimeMD->getSelfDecl() &&
1026c239dd13SDevin Coughlin                     isa<ObjCCategoryDecl>(CompileTimeMD->getDeclContext())) {
1027c239dd13SDevin Coughlin                   // If the method is an accessor in a category, and it doesn't
1028c239dd13SDevin Coughlin                   // have a self declaration, first
1029c239dd13SDevin Coughlin                   // try to find the method in a class extension. This
1030c239dd13SDevin Coughlin                   // works around a bug in Sema where multiple accessors
1031c239dd13SDevin Coughlin                   // are synthesized for properties in class
1032c239dd13SDevin Coughlin                   // extensions that are redeclared in a category and the
1033c239dd13SDevin Coughlin                   // the implicit parameters are not filled in for
1034c239dd13SDevin Coughlin                   // the method on the category.
1035c239dd13SDevin Coughlin                   // This ensures we find the accessor in the extension, which
1036c239dd13SDevin Coughlin                   // has the implicit parameters filled in.
1037c239dd13SDevin Coughlin                   auto *ID = CompileTimeMD->getClassInterface();
1038c239dd13SDevin Coughlin                   for (auto *CatDecl : ID->visible_extensions()) {
1039c239dd13SDevin Coughlin                     Val = CatDecl->getMethod(Sel,
1040c239dd13SDevin Coughlin                                              CompileTimeMD->isInstanceMethod());
1041c239dd13SDevin Coughlin                     if (*Val)
1042c239dd13SDevin Coughlin                       break;
1043c239dd13SDevin Coughlin                   }
1044c239dd13SDevin Coughlin                 }
1045c239dd13SDevin Coughlin                 if (!*Val)
10461a866cd5SJordan Rose                   Val = IDecl->lookupInstanceMethod(Sel);
10471a866cd5SJordan Rose               }
1048c239dd13SDevin Coughlin         }
10491a866cd5SJordan Rose 
1050245e45afSTed Kremenek         const ObjCMethodDecl *MD = Val.getValue();
105175f49a9cSAnna Zaks         if (CanBeSubClassed)
105275f49a9cSAnna Zaks           return RuntimeDefinition(MD, Receiver);
1053920af014SAnna Zaks         else
10540dbb783cSCraig Topper           return RuntimeDefinition(MD, nullptr);
1055920af014SAnna Zaks       }
10565808eb80SAnna Zaks 
105763282aefSAnna Zaks   } else {
105863282aefSAnna Zaks     // This is a class method.
105963282aefSAnna Zaks     // If we have type info for the receiver class, we are calling via
106063282aefSAnna Zaks     // class name.
106163282aefSAnna Zaks     if (ObjCInterfaceDecl *IDecl = E->getReceiverInterface()) {
106263282aefSAnna Zaks       // Find/Return the method implementation.
106385383182SAnna Zaks       return RuntimeDefinition(IDecl->lookupPrivateClassMethod(Sel));
10644f7df9beSJordan Rose     }
106563282aefSAnna Zaks   }
106663282aefSAnna Zaks 
1067123af098SAnna Zaks   return RuntimeDefinition();
10684f7df9beSJordan Rose }
10694f7df9beSJordan Rose 
1070514f9354SJordan Rose bool ObjCMethodCall::argumentsMayEscape() const {
1071514f9354SJordan Rose   if (isInSystemHeader() && !isInstanceMessage()) {
1072514f9354SJordan Rose     Selector Sel = getSelector();
1073514f9354SJordan Rose     if (Sel.getNumArgs() == 1 &&
1074514f9354SJordan Rose         Sel.getIdentifierInfoForSlot(0)->isStr("valueWithPointer"))
1075514f9354SJordan Rose       return true;
1076514f9354SJordan Rose   }
1077514f9354SJordan Rose 
1078514f9354SJordan Rose   return CallEvent::argumentsMayEscape();
1079514f9354SJordan Rose }
1080514f9354SJordan Rose 
108142e8d649SJordan Rose void ObjCMethodCall::getInitialStackFrameContents(
108242e8d649SJordan Rose                                              const StackFrameContext *CalleeCtx,
108342e8d649SJordan Rose                                              BindingsTy &Bindings) const {
108442e8d649SJordan Rose   const ObjCMethodDecl *D = cast<ObjCMethodDecl>(CalleeCtx->getDecl());
108542e8d649SJordan Rose   SValBuilder &SVB = getState()->getStateManager().getSValBuilder();
108642e8d649SJordan Rose   addParameterValuesToBindings(CalleeCtx, Bindings, SVB, *this,
10872ff16004STed Kremenek                                D->parameters());
108842e8d649SJordan Rose 
108942e8d649SJordan Rose   SVal SelfVal = getReceiverSVal();
109042e8d649SJordan Rose   if (!SelfVal.isUnknown()) {
109142e8d649SJordan Rose     const VarDecl *SelfD = CalleeCtx->getAnalysisDeclContext()->getSelfDecl();
109242e8d649SJordan Rose     MemRegionManager &MRMgr = SVB.getRegionManager();
109342e8d649SJordan Rose     Loc SelfLoc = SVB.makeLoc(MRMgr.getVarRegion(SelfD, CalleeCtx));
109442e8d649SJordan Rose     Bindings.push_back(std::make_pair(SelfLoc, SelfVal));
109542e8d649SJordan Rose   }
109642e8d649SJordan Rose }
109742e8d649SJordan Rose 
1098ce6c99a5SJordan Rose CallEventRef<>
1099fcd016e5SJordan Rose CallEventManager::getSimpleCall(const CallExpr *CE, ProgramStateRef State,
1100fcd016e5SJordan Rose                                 const LocationContext *LCtx) {
1101fcd016e5SJordan Rose   if (const CXXMemberCallExpr *MCE = dyn_cast<CXXMemberCallExpr>(CE))
1102fcd016e5SJordan Rose     return create<CXXMemberCall>(MCE, State, LCtx);
1103fcd016e5SJordan Rose 
1104fcd016e5SJordan Rose   if (const CXXOperatorCallExpr *OpCE = dyn_cast<CXXOperatorCallExpr>(CE)) {
1105fcd016e5SJordan Rose     const FunctionDecl *DirectCallee = OpCE->getDirectCallee();
1106fcd016e5SJordan Rose     if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(DirectCallee))
1107fcd016e5SJordan Rose       if (MD->isInstance())
1108fcd016e5SJordan Rose         return create<CXXMemberOperatorCall>(OpCE, State, LCtx);
1109fcd016e5SJordan Rose 
1110fcd016e5SJordan Rose   } else if (CE->getCallee()->getType()->isBlockPointerType()) {
1111fcd016e5SJordan Rose     return create<BlockCall>(CE, State, LCtx);
1112fcd016e5SJordan Rose   }
1113fcd016e5SJordan Rose 
1114fcd016e5SJordan Rose   // Otherwise, it's a normal function call, static member function call, or
1115fcd016e5SJordan Rose   // something we can't reason about.
11162a833ca5SJordan Rose   return create<SimpleFunctionCall>(CE, State, LCtx);
1117fcd016e5SJordan Rose }
1118c2d249ceSJordan Rose 
1119c2d249ceSJordan Rose 
1120c2d249ceSJordan Rose CallEventRef<>
1121c2d249ceSJordan Rose CallEventManager::getCaller(const StackFrameContext *CalleeCtx,
1122c2d249ceSJordan Rose                             ProgramStateRef State) {
1123c2d249ceSJordan Rose   const LocationContext *ParentCtx = CalleeCtx->getParent();
1124c2d249ceSJordan Rose   const LocationContext *CallerCtx = ParentCtx->getCurrentStackFrame();
1125c2d249ceSJordan Rose   assert(CallerCtx && "This should not be used for top-level stack frames");
1126c2d249ceSJordan Rose 
1127c2d249ceSJordan Rose   const Stmt *CallSite = CalleeCtx->getCallSite();
1128c2d249ceSJordan Rose 
1129c2d249ceSJordan Rose   if (CallSite) {
1130c2d249ceSJordan Rose     if (const CallExpr *CE = dyn_cast<CallExpr>(CallSite))
1131c2d249ceSJordan Rose       return getSimpleCall(CE, State, CallerCtx);
1132c2d249ceSJordan Rose 
1133c2d249ceSJordan Rose     switch (CallSite->getStmtClass()) {
11348d48938bSJordan Rose     case Stmt::CXXConstructExprClass:
11358d48938bSJordan Rose     case Stmt::CXXTemporaryObjectExprClass: {
1136c2d249ceSJordan Rose       SValBuilder &SVB = State->getStateManager().getSValBuilder();
1137c2d249ceSJordan Rose       const CXXMethodDecl *Ctor = cast<CXXMethodDecl>(CalleeCtx->getDecl());
1138c2d249ceSJordan Rose       Loc ThisPtr = SVB.getCXXThis(Ctor, CalleeCtx);
1139c2d249ceSJordan Rose       SVal ThisVal = State->getSVal(ThisPtr);
1140c2d249ceSJordan Rose 
1141c2d249ceSJordan Rose       return getCXXConstructorCall(cast<CXXConstructExpr>(CallSite),
1142c2d249ceSJordan Rose                                    ThisVal.getAsRegion(), State, CallerCtx);
1143c2d249ceSJordan Rose     }
1144c2d249ceSJordan Rose     case Stmt::CXXNewExprClass:
1145c2d249ceSJordan Rose       return getCXXAllocatorCall(cast<CXXNewExpr>(CallSite), State, CallerCtx);
1146c2d249ceSJordan Rose     case Stmt::ObjCMessageExprClass:
1147c2d249ceSJordan Rose       return getObjCMethodCall(cast<ObjCMessageExpr>(CallSite),
1148c2d249ceSJordan Rose                                State, CallerCtx);
1149c2d249ceSJordan Rose     default:
1150c2d249ceSJordan Rose       llvm_unreachable("This is not an inlineable statement.");
1151c2d249ceSJordan Rose     }
1152c2d249ceSJordan Rose   }
1153c2d249ceSJordan Rose 
1154c2d249ceSJordan Rose   // Fall back to the CFG. The only thing we haven't handled yet is
1155c2d249ceSJordan Rose   // destructors, though this could change in the future.
1156c2d249ceSJordan Rose   const CFGBlock *B = CalleeCtx->getCallSiteBlock();
1157c2d249ceSJordan Rose   CFGElement E = (*B)[CalleeCtx->getIndex()];
11582a01f5d4SDavid Blaikie   assert(E.getAs<CFGImplicitDtor>() &&
11592a01f5d4SDavid Blaikie          "All other CFG elements should have exprs");
11602a01f5d4SDavid Blaikie   assert(!E.getAs<CFGTemporaryDtor>() && "We don't handle temporaries yet");
1161c2d249ceSJordan Rose 
1162c2d249ceSJordan Rose   SValBuilder &SVB = State->getStateManager().getSValBuilder();
1163c2d249ceSJordan Rose   const CXXDestructorDecl *Dtor = cast<CXXDestructorDecl>(CalleeCtx->getDecl());
1164c2d249ceSJordan Rose   Loc ThisPtr = SVB.getCXXThis(Dtor, CalleeCtx);
1165c2d249ceSJordan Rose   SVal ThisVal = State->getSVal(ThisPtr);
1166c2d249ceSJordan Rose 
1167c2d249ceSJordan Rose   const Stmt *Trigger;
116800be69abSDavid Blaikie   if (Optional<CFGAutomaticObjDtor> AutoDtor = E.getAs<CFGAutomaticObjDtor>())
116900be69abSDavid Blaikie     Trigger = AutoDtor->getTriggerStmt();
11701ccc43d5SJordan Rose   else if (Optional<CFGDeleteDtor> DeleteDtor = E.getAs<CFGDeleteDtor>())
11711ccc43d5SJordan Rose     Trigger = cast<Stmt>(DeleteDtor->getDeleteExpr());
1172c2d249ceSJordan Rose   else
1173c2d249ceSJordan Rose     Trigger = Dtor->getBody();
1174c2d249ceSJordan Rose 
1175c2d249ceSJordan Rose   return getCXXDestructorCall(Dtor, Trigger, ThisVal.getAsRegion(),
117600be69abSDavid Blaikie                               E.getAs<CFGBaseDtor>().hasValue(), State,
117700be69abSDavid Blaikie                               CallerCtx);
1178c2d249ceSJordan Rose }
1179