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/Analysis/ProgramPoint.h"
184f7df9beSJordan Rose #include "clang/AST/ParentMap.h"
194f7df9beSJordan Rose #include "llvm/ADT/SmallSet.h"
204f7df9beSJordan Rose #include "llvm/ADT/StringExtras.h"
214f7df9beSJordan Rose 
224f7df9beSJordan Rose using namespace clang;
234f7df9beSJordan Rose using namespace ento;
244f7df9beSJordan Rose 
254f7df9beSJordan Rose QualType CallEvent::getResultType() const {
264f7df9beSJordan Rose   QualType ResultTy = getDeclaredResultType();
274f7df9beSJordan Rose 
284f7df9beSJordan Rose   if (ResultTy.isNull())
294f7df9beSJordan Rose     ResultTy = getOriginExpr()->getType();
304f7df9beSJordan Rose 
314f7df9beSJordan Rose   return ResultTy;
324f7df9beSJordan Rose }
334f7df9beSJordan Rose 
344f7df9beSJordan Rose static bool isCallbackArg(SVal V, QualType T) {
354f7df9beSJordan Rose   // If the parameter is 0, it's harmless.
364f7df9beSJordan Rose   if (V.isZeroConstant())
374f7df9beSJordan Rose     return false;
384f7df9beSJordan Rose 
394f7df9beSJordan Rose   // If a parameter is a block or a callback, assume it can modify pointer.
404f7df9beSJordan Rose   if (T->isBlockPointerType() ||
414f7df9beSJordan Rose       T->isFunctionPointerType() ||
424f7df9beSJordan Rose       T->isObjCSelType())
434f7df9beSJordan Rose     return true;
444f7df9beSJordan Rose 
454f7df9beSJordan Rose   // Check if a callback is passed inside a struct (for both, struct passed by
464f7df9beSJordan Rose   // reference and by value). Dig just one level into the struct for now.
474f7df9beSJordan Rose 
484f7df9beSJordan Rose   if (isa<PointerType>(T) || isa<ReferenceType>(T))
494f7df9beSJordan Rose     T = T->getPointeeType();
504f7df9beSJordan Rose 
514f7df9beSJordan Rose   if (const RecordType *RT = T->getAsStructureType()) {
524f7df9beSJordan Rose     const RecordDecl *RD = RT->getDecl();
534f7df9beSJordan Rose     for (RecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end();
544f7df9beSJordan Rose          I != E; ++I) {
554f7df9beSJordan Rose       QualType FieldT = I->getType();
564f7df9beSJordan Rose       if (FieldT->isBlockPointerType() || FieldT->isFunctionPointerType())
574f7df9beSJordan Rose         return true;
584f7df9beSJordan Rose     }
594f7df9beSJordan Rose   }
604f7df9beSJordan Rose 
614f7df9beSJordan Rose   return false;
624f7df9beSJordan Rose }
634f7df9beSJordan Rose 
644f7df9beSJordan Rose bool CallEvent::hasNonZeroCallbackArg() const {
654f7df9beSJordan Rose   unsigned NumOfArgs = getNumArgs();
664f7df9beSJordan Rose 
674f7df9beSJordan Rose   // If calling using a function pointer, assume the function does not
684f7df9beSJordan Rose   // have a callback. TODO: We could check the types of the arguments here.
694f7df9beSJordan Rose   if (!getDecl())
704f7df9beSJordan Rose     return false;
714f7df9beSJordan Rose 
724f7df9beSJordan Rose   unsigned Idx = 0;
734f7df9beSJordan Rose   for (CallEvent::param_type_iterator I = param_type_begin(),
744f7df9beSJordan Rose                                        E = param_type_end();
754f7df9beSJordan Rose        I != E && Idx < NumOfArgs; ++I, ++Idx) {
764f7df9beSJordan Rose     if (NumOfArgs <= Idx)
774f7df9beSJordan Rose       break;
784f7df9beSJordan Rose 
794f7df9beSJordan Rose     if (isCallbackArg(getArgSVal(Idx), *I))
804f7df9beSJordan Rose       return true;
814f7df9beSJordan Rose   }
824f7df9beSJordan Rose 
834f7df9beSJordan Rose   return false;
844f7df9beSJordan Rose }
854f7df9beSJordan Rose 
864f7df9beSJordan Rose /// \brief Returns true if a type is a pointer-to-const or reference-to-const
874f7df9beSJordan Rose /// with no further indirection.
884f7df9beSJordan Rose static bool isPointerToConst(QualType Ty) {
894f7df9beSJordan Rose   QualType PointeeTy = Ty->getPointeeType();
904f7df9beSJordan Rose   if (PointeeTy == QualType())
914f7df9beSJordan Rose     return false;
924f7df9beSJordan Rose   if (!PointeeTy.isConstQualified())
934f7df9beSJordan Rose     return false;
944f7df9beSJordan Rose   if (PointeeTy->isAnyPointerType())
954f7df9beSJordan Rose     return false;
964f7df9beSJordan Rose   return true;
974f7df9beSJordan Rose }
984f7df9beSJordan Rose 
994f7df9beSJordan Rose // Try to retrieve the function declaration and find the function parameter
1004f7df9beSJordan Rose // types which are pointers/references to a non-pointer const.
1014f7df9beSJordan Rose // We will not invalidate the corresponding argument regions.
1024f7df9beSJordan Rose static void findPtrToConstParams(llvm::SmallSet<unsigned, 1> &PreserveArgs,
1034f7df9beSJordan Rose                                  const CallEvent &Call) {
1044f7df9beSJordan Rose   unsigned Idx = 0;
1054f7df9beSJordan Rose   for (CallEvent::param_type_iterator I = Call.param_type_begin(),
1064f7df9beSJordan Rose                                       E = Call.param_type_end();
1074f7df9beSJordan Rose        I != E; ++I, ++Idx) {
1084f7df9beSJordan Rose     if (isPointerToConst(*I))
1094f7df9beSJordan Rose       PreserveArgs.insert(Idx);
1104f7df9beSJordan Rose   }
1114f7df9beSJordan Rose }
1124f7df9beSJordan Rose 
1134f7df9beSJordan Rose ProgramStateRef CallEvent::invalidateRegions(unsigned BlockCount,
1144f7df9beSJordan Rose                                               ProgramStateRef Orig) const {
1154f7df9beSJordan Rose   ProgramStateRef Result = (Orig ? Orig : getState());
1164f7df9beSJordan Rose 
1174f7df9beSJordan Rose   SmallVector<const MemRegion *, 8> RegionsToInvalidate;
1184f7df9beSJordan Rose   getExtraInvalidatedRegions(RegionsToInvalidate);
1194f7df9beSJordan Rose 
1204f7df9beSJordan Rose   // Indexes of arguments whose values will be preserved by the call.
1214f7df9beSJordan Rose   llvm::SmallSet<unsigned, 1> PreserveArgs;
1224f7df9beSJordan Rose   if (!argumentsMayEscape())
1234f7df9beSJordan Rose     findPtrToConstParams(PreserveArgs, *this);
1244f7df9beSJordan Rose 
1254f7df9beSJordan Rose   for (unsigned Idx = 0, Count = getNumArgs(); Idx != Count; ++Idx) {
1264f7df9beSJordan Rose     if (PreserveArgs.count(Idx))
1274f7df9beSJordan Rose       continue;
1284f7df9beSJordan Rose 
1294f7df9beSJordan Rose     SVal V = getArgSVal(Idx);
1304f7df9beSJordan Rose 
1314f7df9beSJordan Rose     // If we are passing a location wrapped as an integer, unwrap it and
1324f7df9beSJordan Rose     // invalidate the values referred by the location.
1334f7df9beSJordan Rose     if (nonloc::LocAsInteger *Wrapped = dyn_cast<nonloc::LocAsInteger>(&V))
1344f7df9beSJordan Rose       V = Wrapped->getLoc();
1354f7df9beSJordan Rose     else if (!isa<Loc>(V))
1364f7df9beSJordan Rose       continue;
1374f7df9beSJordan Rose 
1384f7df9beSJordan Rose     if (const MemRegion *R = V.getAsRegion()) {
1394f7df9beSJordan Rose       // Invalidate the value of the variable passed by reference.
1404f7df9beSJordan Rose 
1414f7df9beSJordan Rose       // Are we dealing with an ElementRegion?  If the element type is
1424f7df9beSJordan Rose       // a basic integer type (e.g., char, int) and the underlying region
1434f7df9beSJordan Rose       // is a variable region then strip off the ElementRegion.
1444f7df9beSJordan Rose       // FIXME: We really need to think about this for the general case
1454f7df9beSJordan Rose       //   as sometimes we are reasoning about arrays and other times
1464f7df9beSJordan Rose       //   about (char*), etc., is just a form of passing raw bytes.
1474f7df9beSJordan Rose       //   e.g., void *p = alloca(); foo((char*)p);
1484f7df9beSJordan Rose       if (const ElementRegion *ER = dyn_cast<ElementRegion>(R)) {
1494f7df9beSJordan Rose         // Checking for 'integral type' is probably too promiscuous, but
1504f7df9beSJordan Rose         // we'll leave it in for now until we have a systematic way of
1514f7df9beSJordan Rose         // handling all of these cases.  Eventually we need to come up
1524f7df9beSJordan Rose         // with an interface to StoreManager so that this logic can be
1534f7df9beSJordan Rose         // appropriately delegated to the respective StoreManagers while
1544f7df9beSJordan Rose         // still allowing us to do checker-specific logic (e.g.,
1554f7df9beSJordan Rose         // invalidating reference counts), probably via callbacks.
1564f7df9beSJordan Rose         if (ER->getElementType()->isIntegralOrEnumerationType()) {
1574f7df9beSJordan Rose           const MemRegion *superReg = ER->getSuperRegion();
1584f7df9beSJordan Rose           if (isa<VarRegion>(superReg) || isa<FieldRegion>(superReg) ||
1594f7df9beSJordan Rose               isa<ObjCIvarRegion>(superReg))
1604f7df9beSJordan Rose             R = cast<TypedRegion>(superReg);
1614f7df9beSJordan Rose         }
1624f7df9beSJordan Rose         // FIXME: What about layers of ElementRegions?
1634f7df9beSJordan Rose       }
1644f7df9beSJordan Rose 
1654f7df9beSJordan Rose       // Mark this region for invalidation.  We batch invalidate regions
1664f7df9beSJordan Rose       // below for efficiency.
1674f7df9beSJordan Rose       RegionsToInvalidate.push_back(R);
1684f7df9beSJordan Rose     }
1694f7df9beSJordan Rose   }
1704f7df9beSJordan Rose 
1714f7df9beSJordan Rose   // Invalidate designated regions using the batch invalidation API.
1724f7df9beSJordan Rose   // NOTE: Even if RegionsToInvalidate is empty, we may still invalidate
1734f7df9beSJordan Rose   //  global variables.
1744f7df9beSJordan Rose   return Result->invalidateRegions(RegionsToInvalidate, getOriginExpr(),
1754f7df9beSJordan Rose                                    BlockCount, getLocationContext(),
1764f7df9beSJordan Rose                                    /*Symbols=*/0, this);
1774f7df9beSJordan Rose }
1784f7df9beSJordan Rose 
1794f7df9beSJordan Rose ProgramPoint CallEvent::getProgramPoint(bool IsPreVisit,
1804f7df9beSJordan Rose                                         const ProgramPointTag *Tag) const {
1814f7df9beSJordan Rose   if (const Expr *E = getOriginExpr()) {
1824f7df9beSJordan Rose     if (IsPreVisit)
1834f7df9beSJordan Rose       return PreStmt(E, getLocationContext(), Tag);
1844f7df9beSJordan Rose     return PostStmt(E, getLocationContext(), Tag);
1854f7df9beSJordan Rose   }
1864f7df9beSJordan Rose 
1874f7df9beSJordan Rose   const Decl *D = getDecl();
1884f7df9beSJordan Rose   assert(D && "Cannot get a program point without a statement or decl");
1894f7df9beSJordan Rose 
1904f7df9beSJordan Rose   SourceLocation Loc = getSourceRange().getBegin();
1914f7df9beSJordan Rose   if (IsPreVisit)
1924f7df9beSJordan Rose     return PreImplicitCall(D, Loc, getLocationContext(), Tag);
1934f7df9beSJordan Rose   return PostImplicitCall(D, Loc, getLocationContext(), Tag);
1944f7df9beSJordan Rose }
1954f7df9beSJordan Rose 
19672ce8e2dSJordan Rose SVal CallEvent::getArgSVal(unsigned Index) const {
19772ce8e2dSJordan Rose   const Expr *ArgE = getArgExpr(Index);
19872ce8e2dSJordan Rose   if (!ArgE)
19972ce8e2dSJordan Rose     return UnknownVal();
20072ce8e2dSJordan Rose   return getSVal(ArgE);
20172ce8e2dSJordan Rose }
20272ce8e2dSJordan Rose 
20372ce8e2dSJordan Rose SourceRange CallEvent::getArgSourceRange(unsigned Index) const {
20472ce8e2dSJordan Rose   const Expr *ArgE = getArgExpr(Index);
20572ce8e2dSJordan Rose   if (!ArgE)
20672ce8e2dSJordan Rose     return SourceRange();
20772ce8e2dSJordan Rose   return ArgE->getSourceRange();
20872ce8e2dSJordan Rose }
20972ce8e2dSJordan Rose 
2109299d8c2SBenjamin Kramer void CallEvent::dump() const {
2119299d8c2SBenjamin Kramer   dump(llvm::errs());
2129299d8c2SBenjamin Kramer }
2139299d8c2SBenjamin Kramer 
21472ce8e2dSJordan Rose void CallEvent::dump(raw_ostream &Out) const {
21572ce8e2dSJordan Rose   ASTContext &Ctx = getState()->getStateManager().getContext();
21672ce8e2dSJordan Rose   if (const Expr *E = getOriginExpr()) {
217235341bcSRichard Smith     E->printPretty(Out, 0, Ctx.getPrintingPolicy());
21872ce8e2dSJordan Rose     Out << "\n";
21972ce8e2dSJordan Rose     return;
22072ce8e2dSJordan Rose   }
22172ce8e2dSJordan Rose 
22272ce8e2dSJordan Rose   if (const Decl *D = getDecl()) {
22372ce8e2dSJordan Rose     Out << "Call to ";
22472ce8e2dSJordan Rose     D->print(Out, Ctx.getPrintingPolicy());
22572ce8e2dSJordan Rose     return;
22672ce8e2dSJordan Rose   }
22772ce8e2dSJordan Rose 
22872ce8e2dSJordan Rose   // FIXME: a string representation of the kind would be nice.
22972ce8e2dSJordan Rose   Out << "Unknown call (type " << getKind() << ")";
23072ce8e2dSJordan Rose }
23172ce8e2dSJordan Rose 
2324f7df9beSJordan Rose 
233e537cc05SJordan Rose bool CallEvent::isCallStmt(const Stmt *S) {
23472ce8e2dSJordan Rose   return isa<CallExpr>(S) || isa<ObjCMessageExpr>(S)
235e537cc05SJordan Rose                           || isa<CXXConstructExpr>(S)
236e537cc05SJordan Rose                           || isa<CXXNewExpr>(S);
2374f7df9beSJordan Rose }
2384f7df9beSJordan Rose 
23942e8d649SJordan Rose static void addParameterValuesToBindings(const StackFrameContext *CalleeCtx,
24042e8d649SJordan Rose                                          CallEvent::BindingsTy &Bindings,
24142e8d649SJordan Rose                                          SValBuilder &SVB,
24242e8d649SJordan Rose                                          const CallEvent &Call,
24342e8d649SJordan Rose                                          CallEvent::param_iterator I,
24442e8d649SJordan Rose                                          CallEvent::param_iterator E) {
24542e8d649SJordan Rose   MemRegionManager &MRMgr = SVB.getRegionManager();
2464f7df9beSJordan Rose 
24742e8d649SJordan Rose   unsigned Idx = 0;
24842e8d649SJordan Rose   for (; I != E; ++I, ++Idx) {
24942e8d649SJordan Rose     const ParmVarDecl *ParamDecl = *I;
25042e8d649SJordan Rose     assert(ParamDecl && "Formal parameter has no decl?");
2514f7df9beSJordan Rose 
25242e8d649SJordan Rose     SVal ArgVal = Call.getArgSVal(Idx);
25342e8d649SJordan Rose     if (!ArgVal.isUnknown()) {
25442e8d649SJordan Rose       Loc ParamLoc = SVB.makeLoc(MRMgr.getVarRegion(ParamDecl, CalleeCtx));
25542e8d649SJordan Rose       Bindings.push_back(std::make_pair(ParamLoc, ArgVal));
25642e8d649SJordan Rose     }
2574f7df9beSJordan Rose   }
2584f7df9beSJordan Rose 
25942e8d649SJordan Rose   // FIXME: Variadic arguments are not handled at all right now.
26042e8d649SJordan Rose }
26142e8d649SJordan Rose 
26242e8d649SJordan Rose 
26342e8d649SJordan Rose CallEvent::param_iterator AnyFunctionCall::param_begin() const {
26442e8d649SJordan Rose   const FunctionDecl *D = getDecl();
2654f7df9beSJordan Rose   if (!D)
2664f7df9beSJordan Rose     return 0;
2674f7df9beSJordan Rose 
26842e8d649SJordan Rose   return D->param_begin();
26942e8d649SJordan Rose }
27042e8d649SJordan Rose 
27142e8d649SJordan Rose CallEvent::param_iterator AnyFunctionCall::param_end() const {
27242e8d649SJordan Rose   const FunctionDecl *D = getDecl();
27342e8d649SJordan Rose   if (!D)
27442e8d649SJordan Rose     return 0;
27542e8d649SJordan Rose 
27642e8d649SJordan Rose   return D->param_end();
27742e8d649SJordan Rose }
27842e8d649SJordan Rose 
27942e8d649SJordan Rose void AnyFunctionCall::getInitialStackFrameContents(
28042e8d649SJordan Rose                                         const StackFrameContext *CalleeCtx,
28142e8d649SJordan Rose                                         BindingsTy &Bindings) const {
28242e8d649SJordan Rose   const FunctionDecl *D = cast<FunctionDecl>(CalleeCtx->getDecl());
28342e8d649SJordan Rose   SValBuilder &SVB = getState()->getStateManager().getSValBuilder();
28442e8d649SJordan Rose   addParameterValuesToBindings(CalleeCtx, Bindings, SVB, *this,
28542e8d649SJordan Rose                                D->param_begin(), D->param_end());
2864f7df9beSJordan Rose }
2874f7df9beSJordan Rose 
2884f7df9beSJordan Rose QualType AnyFunctionCall::getDeclaredResultType() const {
2894f7df9beSJordan Rose   const FunctionDecl *D = getDecl();
2904f7df9beSJordan Rose   if (!D)
2914f7df9beSJordan Rose     return QualType();
2924f7df9beSJordan Rose 
2934f7df9beSJordan Rose   return D->getResultType();
2944f7df9beSJordan Rose }
2954f7df9beSJordan Rose 
2964f7df9beSJordan Rose bool AnyFunctionCall::argumentsMayEscape() const {
2974f7df9beSJordan Rose   if (hasNonZeroCallbackArg())
2984f7df9beSJordan Rose     return true;
2994f7df9beSJordan Rose 
3004f7df9beSJordan Rose   const FunctionDecl *D = getDecl();
3014f7df9beSJordan Rose   if (!D)
3024f7df9beSJordan Rose     return true;
3034f7df9beSJordan Rose 
3044f7df9beSJordan Rose   const IdentifierInfo *II = D->getIdentifier();
3054f7df9beSJordan Rose   if (!II)
3064f7df9beSJordan Rose     return true;
3074f7df9beSJordan Rose 
3084f7df9beSJordan Rose   // This set of "escaping" APIs is
3094f7df9beSJordan Rose 
3104f7df9beSJordan Rose   // - 'int pthread_setspecific(ptheread_key k, const void *)' stores a
3114f7df9beSJordan Rose   //   value into thread local storage. The value can later be retrieved with
3124f7df9beSJordan Rose   //   'void *ptheread_getspecific(pthread_key)'. So even thought the
3134f7df9beSJordan Rose   //   parameter is 'const void *', the region escapes through the call.
3144f7df9beSJordan Rose   if (II->isStr("pthread_setspecific"))
3154f7df9beSJordan Rose     return true;
3164f7df9beSJordan Rose 
3174f7df9beSJordan Rose   // - xpc_connection_set_context stores a value which can be retrieved later
3184f7df9beSJordan Rose   //   with xpc_connection_get_context.
3194f7df9beSJordan Rose   if (II->isStr("xpc_connection_set_context"))
3204f7df9beSJordan Rose     return true;
3214f7df9beSJordan Rose 
3224f7df9beSJordan Rose   // - funopen - sets a buffer for future IO calls.
3234f7df9beSJordan Rose   if (II->isStr("funopen"))
3244f7df9beSJordan Rose     return true;
3254f7df9beSJordan Rose 
3264f7df9beSJordan Rose   StringRef FName = II->getName();
3274f7df9beSJordan Rose 
3284f7df9beSJordan Rose   // - CoreFoundation functions that end with "NoCopy" can free a passed-in
3294f7df9beSJordan Rose   //   buffer even if it is const.
3304f7df9beSJordan Rose   if (FName.endswith("NoCopy"))
3314f7df9beSJordan Rose     return true;
3324f7df9beSJordan Rose 
3334f7df9beSJordan Rose   // - NSXXInsertXX, for example NSMapInsertIfAbsent, since they can
3344f7df9beSJordan Rose   //   be deallocated by NSMapRemove.
3354f7df9beSJordan Rose   if (FName.startswith("NS") && (FName.find("Insert") != StringRef::npos))
3364f7df9beSJordan Rose     return true;
3374f7df9beSJordan Rose 
3384f7df9beSJordan Rose   // - Many CF containers allow objects to escape through custom
3394f7df9beSJordan Rose   //   allocators/deallocators upon container construction. (PR12101)
3404f7df9beSJordan Rose   if (FName.startswith("CF") || FName.startswith("CG")) {
3414f7df9beSJordan Rose     return StrInStrNoCase(FName, "InsertValue")  != StringRef::npos ||
3424f7df9beSJordan Rose            StrInStrNoCase(FName, "AddValue")     != StringRef::npos ||
3434f7df9beSJordan Rose            StrInStrNoCase(FName, "SetValue")     != StringRef::npos ||
3444f7df9beSJordan Rose            StrInStrNoCase(FName, "WithData")     != StringRef::npos ||
3454f7df9beSJordan Rose            StrInStrNoCase(FName, "AppendValue")  != StringRef::npos ||
3464f7df9beSJordan Rose            StrInStrNoCase(FName, "SetAttribute") != StringRef::npos;
3474f7df9beSJordan Rose   }
3484f7df9beSJordan Rose 
3494f7df9beSJordan Rose   return false;
3504f7df9beSJordan Rose }
3514f7df9beSJordan Rose 
3524f7df9beSJordan Rose 
3534f7df9beSJordan Rose const FunctionDecl *SimpleCall::getDecl() const {
3544f7df9beSJordan Rose   const FunctionDecl *D = getOriginExpr()->getDirectCallee();
3554f7df9beSJordan Rose   if (D)
3564f7df9beSJordan Rose     return D;
3574f7df9beSJordan Rose 
3584f7df9beSJordan Rose   return getSVal(getOriginExpr()->getCallee()).getAsFunctionDecl();
3594f7df9beSJordan Rose }
3604f7df9beSJordan Rose 
3614f7df9beSJordan Rose 
362ce6c99a5SJordan Rose const FunctionDecl *CXXInstanceCall::getDecl() const {
363ce6c99a5SJordan Rose   const CallExpr *CE = cast_or_null<CallExpr>(getOriginExpr());
364ce6c99a5SJordan Rose   if (!CE)
365ce6c99a5SJordan Rose     return AnyFunctionCall::getDecl();
366ce6c99a5SJordan Rose 
367ce6c99a5SJordan Rose   const FunctionDecl *D = CE->getDirectCallee();
368ce6c99a5SJordan Rose   if (D)
369ce6c99a5SJordan Rose     return D;
370ce6c99a5SJordan Rose 
371ce6c99a5SJordan Rose   return getSVal(CE->getCallee()).getAsFunctionDecl();
372ce6c99a5SJordan Rose }
373ce6c99a5SJordan Rose 
3744f7df9beSJordan Rose void CXXInstanceCall::getExtraInvalidatedRegions(RegionList &Regions) const {
3754f7df9beSJordan Rose   if (const MemRegion *R = getCXXThisVal().getAsRegion())
3764f7df9beSJordan Rose     Regions.push_back(R);
3774f7df9beSJordan Rose }
3784f7df9beSJordan Rose 
3794f7df9beSJordan Rose 
380123af098SAnna Zaks RuntimeDefinition CXXInstanceCall::getRuntimeDefinition() const {
3810f6d63beSJordan Rose   // Do we have a decl at all?
38251bcb226SJordan Rose   const Decl *D = getDecl();
3834f7df9beSJordan Rose   if (!D)
384123af098SAnna Zaks     return RuntimeDefinition();
3854f7df9beSJordan Rose 
3860f6d63beSJordan Rose   // If the method is non-virtual, we know we can inline it.
3874f7df9beSJordan Rose   const CXXMethodDecl *MD = cast<CXXMethodDecl>(D);
3884f7df9beSJordan Rose   if (!MD->isVirtual())
389ce6c99a5SJordan Rose     return AnyFunctionCall::getRuntimeDefinition();
3904f7df9beSJordan Rose 
3910f6d63beSJordan Rose   // Do we know the implicit 'this' object being called?
3920f6d63beSJordan Rose   const MemRegion *R = getCXXThisVal().getAsRegion();
3930f6d63beSJordan Rose   if (!R)
394123af098SAnna Zaks     return RuntimeDefinition();
3950f6d63beSJordan Rose 
3960f6d63beSJordan Rose   // Do we know anything about the type of 'this'?
3970f6d63beSJordan Rose   DynamicTypeInfo DynType = getState()->getDynamicTypeInfo(R);
3980f6d63beSJordan Rose   if (!DynType.isValid())
3990f6d63beSJordan Rose     return RuntimeDefinition();
4000f6d63beSJordan Rose 
4010f6d63beSJordan Rose   // Is the type a C++ class? (This is mostly a defensive check.)
4020f6d63beSJordan Rose   QualType RegionType = DynType.getType()->getPointeeType();
4030f6d63beSJordan Rose   const CXXRecordDecl *RD = RegionType->getAsCXXRecordDecl();
40499107208SJordan Rose   if (!RD || !RD->hasDefinition())
4050f6d63beSJordan Rose     return RuntimeDefinition();
4060f6d63beSJordan Rose 
4070f6d63beSJordan Rose   // Find the decl for this method in that class.
4085fc5da05SJordan Rose   const CXXMethodDecl *Result = MD->getCorrespondingMethodInClass(RD, true);
4090f6d63beSJordan Rose   assert(Result && "At the very least the static decl should show up.");
4100f6d63beSJordan Rose 
4110f6d63beSJordan Rose   // Does the decl that we found have an implementation?
4120f6d63beSJordan Rose   const FunctionDecl *Definition;
4130f6d63beSJordan Rose   if (!Result->hasBody(Definition))
4140f6d63beSJordan Rose     return RuntimeDefinition();
4150f6d63beSJordan Rose 
4160f6d63beSJordan Rose   // We found a definition. If we're not sure that this devirtualization is
4170f6d63beSJordan Rose   // actually what will happen at runtime, make sure to provide the region so
4180f6d63beSJordan Rose   // that ExprEngine can decide what to do with it.
4190f6d63beSJordan Rose   if (DynType.canBeASubClass())
4200f6d63beSJordan Rose     return RuntimeDefinition(Definition, R->StripCasts());
4210f6d63beSJordan Rose   return RuntimeDefinition(Definition, /*DispatchRegion=*/0);
4224f7df9beSJordan Rose }
4234f7df9beSJordan Rose 
42442e8d649SJordan Rose void CXXInstanceCall::getInitialStackFrameContents(
42542e8d649SJordan Rose                                             const StackFrameContext *CalleeCtx,
42642e8d649SJordan Rose                                             BindingsTy &Bindings) const {
42742e8d649SJordan Rose   AnyFunctionCall::getInitialStackFrameContents(CalleeCtx, Bindings);
42842e8d649SJordan Rose 
42902e5309bSJordan Rose   // Handle the binding of 'this' in the new stack frame.
43042e8d649SJordan Rose   SVal ThisVal = getCXXThisVal();
43142e8d649SJordan Rose   if (!ThisVal.isUnknown()) {
43202e5309bSJordan Rose     ProgramStateManager &StateMgr = getState()->getStateManager();
43302e5309bSJordan Rose     SValBuilder &SVB = StateMgr.getSValBuilder();
43402e5309bSJordan Rose 
43542e8d649SJordan Rose     const CXXMethodDecl *MD = cast<CXXMethodDecl>(CalleeCtx->getDecl());
43642e8d649SJordan Rose     Loc ThisLoc = SVB.getCXXThis(MD, CalleeCtx);
43702e5309bSJordan Rose 
43831c3fa9cSJordan Rose     // If we devirtualized to a different member function, we need to make sure
43931c3fa9cSJordan Rose     // we have the proper layering of CXXBaseObjectRegions.
44031c3fa9cSJordan Rose     if (MD->getCanonicalDecl() != getDecl()->getCanonicalDecl()) {
441710f6b12SJordan Rose       ASTContext &Ctx = SVB.getContext();
44202e5309bSJordan Rose       const CXXRecordDecl *Class = MD->getParent();
443710f6b12SJordan Rose       QualType Ty = Ctx.getPointerType(Ctx.getRecordType(Class));
44402e5309bSJordan Rose 
445710f6b12SJordan Rose       // FIXME: CallEvent maybe shouldn't be directly accessing StoreManager.
446710f6b12SJordan Rose       bool Failed;
447710f6b12SJordan Rose       ThisVal = StateMgr.getStoreManager().evalDynamicCast(ThisVal, Ty, Failed);
448710f6b12SJordan Rose       assert(!Failed && "Calling an incorrectly devirtualized method");
44902e5309bSJordan Rose     }
45002e5309bSJordan Rose 
45131c3fa9cSJordan Rose     if (!ThisVal.isUnknown())
45242e8d649SJordan Rose       Bindings.push_back(std::make_pair(ThisLoc, ThisVal));
45342e8d649SJordan Rose   }
45442e8d649SJordan Rose }
45542e8d649SJordan Rose 
45642e8d649SJordan Rose 
4574f7df9beSJordan Rose 
45892e1449bSJordan Rose const Expr *CXXMemberCall::getCXXThisExpr() const {
45992e1449bSJordan Rose   return getOriginExpr()->getImplicitObjectArgument();
4604f7df9beSJordan Rose }
4614f7df9beSJordan Rose 
4624f7df9beSJordan Rose 
46392e1449bSJordan Rose const Expr *CXXMemberOperatorCall::getCXXThisExpr() const {
46492e1449bSJordan Rose   return getOriginExpr()->getArg(0);
4654f7df9beSJordan Rose }
4664f7df9beSJordan Rose 
4674f7df9beSJordan Rose 
4684f7df9beSJordan Rose const BlockDataRegion *BlockCall::getBlockRegion() const {
4694f7df9beSJordan Rose   const Expr *Callee = getOriginExpr()->getCallee();
4704f7df9beSJordan Rose   const MemRegion *DataReg = getSVal(Callee).getAsRegion();
4714f7df9beSJordan Rose 
4724f7df9beSJordan Rose   return dyn_cast_or_null<BlockDataRegion>(DataReg);
4734f7df9beSJordan Rose }
4744f7df9beSJordan Rose 
47542e8d649SJordan Rose CallEvent::param_iterator BlockCall::param_begin() const {
4764f7df9beSJordan Rose   const BlockDecl *D = getBlockDecl();
4774f7df9beSJordan Rose   if (!D)
4784f7df9beSJordan Rose     return 0;
4794f7df9beSJordan Rose   return D->param_begin();
4804f7df9beSJordan Rose }
4814f7df9beSJordan Rose 
48242e8d649SJordan Rose CallEvent::param_iterator BlockCall::param_end() const {
4834f7df9beSJordan Rose   const BlockDecl *D = getBlockDecl();
4844f7df9beSJordan Rose   if (!D)
4854f7df9beSJordan Rose     return 0;
4864f7df9beSJordan Rose   return D->param_end();
4874f7df9beSJordan Rose }
4884f7df9beSJordan Rose 
4894f7df9beSJordan Rose void BlockCall::getExtraInvalidatedRegions(RegionList &Regions) const {
4904f7df9beSJordan Rose   // FIXME: This also needs to invalidate captured globals.
4914f7df9beSJordan Rose   if (const MemRegion *R = getBlockRegion())
4924f7df9beSJordan Rose     Regions.push_back(R);
4934f7df9beSJordan Rose }
4944f7df9beSJordan Rose 
49542e8d649SJordan Rose void BlockCall::getInitialStackFrameContents(const StackFrameContext *CalleeCtx,
49642e8d649SJordan Rose                                              BindingsTy &Bindings) const {
49742e8d649SJordan Rose   const BlockDecl *D = cast<BlockDecl>(CalleeCtx->getDecl());
49842e8d649SJordan Rose   SValBuilder &SVB = getState()->getStateManager().getSValBuilder();
49942e8d649SJordan Rose   addParameterValuesToBindings(CalleeCtx, Bindings, SVB, *this,
50042e8d649SJordan Rose                                D->param_begin(), D->param_end());
50142e8d649SJordan Rose }
50242e8d649SJordan Rose 
50342e8d649SJordan Rose 
5044f7df9beSJordan Rose QualType BlockCall::getDeclaredResultType() const {
5054f7df9beSJordan Rose   const BlockDataRegion *BR = getBlockRegion();
5064f7df9beSJordan Rose   if (!BR)
5074f7df9beSJordan Rose     return QualType();
5084f7df9beSJordan Rose   QualType BlockTy = BR->getCodeRegion()->getLocationType();
5094f7df9beSJordan Rose   return cast<FunctionType>(BlockTy->getPointeeType())->getResultType();
5104f7df9beSJordan Rose }
5114f7df9beSJordan Rose 
5124f7df9beSJordan Rose 
5134f7df9beSJordan Rose SVal CXXConstructorCall::getCXXThisVal() const {
5144f7df9beSJordan Rose   if (Data)
5154f7df9beSJordan Rose     return loc::MemRegionVal(static_cast<const MemRegion *>(Data));
5164f7df9beSJordan Rose   return UnknownVal();
5174f7df9beSJordan Rose }
5184f7df9beSJordan Rose 
5194f7df9beSJordan Rose void CXXConstructorCall::getExtraInvalidatedRegions(RegionList &Regions) const {
5204f7df9beSJordan Rose   if (Data)
5214f7df9beSJordan Rose     Regions.push_back(static_cast<const MemRegion *>(Data));
5224f7df9beSJordan Rose }
5234f7df9beSJordan Rose 
52442e8d649SJordan Rose void CXXConstructorCall::getInitialStackFrameContents(
52542e8d649SJordan Rose                                              const StackFrameContext *CalleeCtx,
52642e8d649SJordan Rose                                              BindingsTy &Bindings) const {
52742e8d649SJordan Rose   AnyFunctionCall::getInitialStackFrameContents(CalleeCtx, Bindings);
52842e8d649SJordan Rose 
52942e8d649SJordan Rose   SVal ThisVal = getCXXThisVal();
53042e8d649SJordan Rose   if (!ThisVal.isUnknown()) {
53142e8d649SJordan Rose     SValBuilder &SVB = getState()->getStateManager().getSValBuilder();
53242e8d649SJordan Rose     const CXXMethodDecl *MD = cast<CXXMethodDecl>(CalleeCtx->getDecl());
53342e8d649SJordan Rose     Loc ThisLoc = SVB.getCXXThis(MD, CalleeCtx);
53442e8d649SJordan Rose     Bindings.push_back(std::make_pair(ThisLoc, ThisVal));
53542e8d649SJordan Rose   }
53642e8d649SJordan Rose }
53742e8d649SJordan Rose 
53842e8d649SJordan Rose 
5394f7df9beSJordan Rose 
5404f7df9beSJordan Rose SVal CXXDestructorCall::getCXXThisVal() const {
5414f7df9beSJordan Rose   if (Data)
5424f7df9beSJordan Rose     return loc::MemRegionVal(static_cast<const MemRegion *>(Data));
5434f7df9beSJordan Rose   return UnknownVal();
5444f7df9beSJordan Rose }
5454f7df9beSJordan Rose 
54642e8d649SJordan Rose 
54742e8d649SJordan Rose CallEvent::param_iterator ObjCMethodCall::param_begin() const {
54842e8d649SJordan Rose   const ObjCMethodDecl *D = getDecl();
5494f7df9beSJordan Rose   if (!D)
5504f7df9beSJordan Rose     return 0;
5514f7df9beSJordan Rose 
55242e8d649SJordan Rose   return D->param_begin();
55342e8d649SJordan Rose }
55442e8d649SJordan Rose 
55542e8d649SJordan Rose CallEvent::param_iterator ObjCMethodCall::param_end() const {
55642e8d649SJordan Rose   const ObjCMethodDecl *D = getDecl();
55742e8d649SJordan Rose   if (!D)
55842e8d649SJordan Rose     return 0;
55942e8d649SJordan Rose 
56042e8d649SJordan Rose   return D->param_end();
5614f7df9beSJordan Rose }
5624f7df9beSJordan Rose 
5634f7df9beSJordan Rose void
5644f7df9beSJordan Rose ObjCMethodCall::getExtraInvalidatedRegions(RegionList &Regions) const {
5654f7df9beSJordan Rose   if (const MemRegion *R = getReceiverSVal().getAsRegion())
5664f7df9beSJordan Rose     Regions.push_back(R);
5674f7df9beSJordan Rose }
5684f7df9beSJordan Rose 
5694f7df9beSJordan Rose QualType ObjCMethodCall::getDeclaredResultType() const {
5704f7df9beSJordan Rose   const ObjCMethodDecl *D = getDecl();
5714f7df9beSJordan Rose   if (!D)
5724f7df9beSJordan Rose     return QualType();
5734f7df9beSJordan Rose 
5744f7df9beSJordan Rose   return D->getResultType();
5754f7df9beSJordan Rose }
5764f7df9beSJordan Rose 
5773d5d3d3eSAnna Zaks SVal ObjCMethodCall::getSelfSVal() const {
5783d5d3d3eSAnna Zaks   const LocationContext *LCtx = getLocationContext();
5793d5d3d3eSAnna Zaks   const ImplicitParamDecl *SelfDecl = LCtx->getSelfDecl();
5803d5d3d3eSAnna Zaks   if (!SelfDecl)
5813d5d3d3eSAnna Zaks     return SVal();
5823d5d3d3eSAnna Zaks   return getState()->getSVal(getState()->getRegion(SelfDecl, LCtx));
5833d5d3d3eSAnna Zaks }
5843d5d3d3eSAnna Zaks 
5854f7df9beSJordan Rose SVal ObjCMethodCall::getReceiverSVal() const {
5864f7df9beSJordan Rose   // FIXME: Is this the best way to handle class receivers?
5874f7df9beSJordan Rose   if (!isInstanceMessage())
5884f7df9beSJordan Rose     return UnknownVal();
5894f7df9beSJordan Rose 
590472dbcf1SAnna Zaks   if (const Expr *RecE = getOriginExpr()->getInstanceReceiver())
591472dbcf1SAnna Zaks     return getSVal(RecE);
5924f7df9beSJordan Rose 
5934f7df9beSJordan Rose   // An instance message with no expression means we are sending to super.
5944f7df9beSJordan Rose   // In this case the object reference is the same as 'self'.
5953d5d3d3eSAnna Zaks   assert(getOriginExpr()->getReceiverKind() == ObjCMessageExpr::SuperInstance);
5963d5d3d3eSAnna Zaks   SVal SelfVal = getSelfSVal();
5973d5d3d3eSAnna Zaks   assert(SelfVal.isValid() && "Calling super but not in ObjC method");
5983d5d3d3eSAnna Zaks   return SelfVal;
5993d5d3d3eSAnna Zaks }
6003d5d3d3eSAnna Zaks 
6013d5d3d3eSAnna Zaks bool ObjCMethodCall::isReceiverSelfOrSuper() const {
6023d5d3d3eSAnna Zaks   if (getOriginExpr()->getReceiverKind() == ObjCMessageExpr::SuperInstance ||
6033d5d3d3eSAnna Zaks       getOriginExpr()->getReceiverKind() == ObjCMessageExpr::SuperClass)
6043d5d3d3eSAnna Zaks       return true;
6053d5d3d3eSAnna Zaks 
6063d5d3d3eSAnna Zaks   if (!isInstanceMessage())
6073d5d3d3eSAnna Zaks     return false;
6083d5d3d3eSAnna Zaks 
6093d5d3d3eSAnna Zaks   SVal RecVal = getSVal(getOriginExpr()->getInstanceReceiver());
6103d5d3d3eSAnna Zaks 
6113d5d3d3eSAnna Zaks   return (RecVal == getSelfSVal());
6124f7df9beSJordan Rose }
6134f7df9beSJordan Rose 
6144f7df9beSJordan Rose SourceRange ObjCMethodCall::getSourceRange() const {
6154f7df9beSJordan Rose   switch (getMessageKind()) {
6164f7df9beSJordan Rose   case OCM_Message:
6174f7df9beSJordan Rose     return getOriginExpr()->getSourceRange();
6184f7df9beSJordan Rose   case OCM_PropertyAccess:
6194f7df9beSJordan Rose   case OCM_Subscript:
6204f7df9beSJordan Rose     return getContainingPseudoObjectExpr()->getSourceRange();
6214f7df9beSJordan Rose   }
6224f7df9beSJordan Rose   llvm_unreachable("unknown message kind");
6234f7df9beSJordan Rose }
6244f7df9beSJordan Rose 
6254f7df9beSJordan Rose typedef llvm::PointerIntPair<const PseudoObjectExpr *, 2> ObjCMessageDataTy;
6264f7df9beSJordan Rose 
6274f7df9beSJordan Rose const PseudoObjectExpr *ObjCMethodCall::getContainingPseudoObjectExpr() const {
6284f7df9beSJordan Rose   assert(Data != 0 && "Lazy lookup not yet performed.");
6294f7df9beSJordan Rose   assert(getMessageKind() != OCM_Message && "Explicit message send.");
6304f7df9beSJordan Rose   return ObjCMessageDataTy::getFromOpaqueValue(Data).getPointer();
6314f7df9beSJordan Rose }
6324f7df9beSJordan Rose 
6334f7df9beSJordan Rose ObjCMessageKind ObjCMethodCall::getMessageKind() const {
6344f7df9beSJordan Rose   if (Data == 0) {
6354f7df9beSJordan Rose     ParentMap &PM = getLocationContext()->getParentMap();
6364f7df9beSJordan Rose     const Stmt *S = PM.getParent(getOriginExpr());
6374f7df9beSJordan Rose     if (const PseudoObjectExpr *POE = dyn_cast_or_null<PseudoObjectExpr>(S)) {
6384f7df9beSJordan Rose       const Expr *Syntactic = POE->getSyntacticForm();
6394f7df9beSJordan Rose 
6404f7df9beSJordan Rose       // This handles the funny case of assigning to the result of a getter.
6414f7df9beSJordan Rose       // This can happen if the getter returns a non-const reference.
6424f7df9beSJordan Rose       if (const BinaryOperator *BO = dyn_cast<BinaryOperator>(Syntactic))
6434f7df9beSJordan Rose         Syntactic = BO->getLHS();
6444f7df9beSJordan Rose 
6454f7df9beSJordan Rose       ObjCMessageKind K;
6464f7df9beSJordan Rose       switch (Syntactic->getStmtClass()) {
6474f7df9beSJordan Rose       case Stmt::ObjCPropertyRefExprClass:
6484f7df9beSJordan Rose         K = OCM_PropertyAccess;
6494f7df9beSJordan Rose         break;
6504f7df9beSJordan Rose       case Stmt::ObjCSubscriptRefExprClass:
6514f7df9beSJordan Rose         K = OCM_Subscript;
6524f7df9beSJordan Rose         break;
6534f7df9beSJordan Rose       default:
6544f7df9beSJordan Rose         // FIXME: Can this ever happen?
6554f7df9beSJordan Rose         K = OCM_Message;
6564f7df9beSJordan Rose         break;
6574f7df9beSJordan Rose       }
6584f7df9beSJordan Rose 
6594f7df9beSJordan Rose       if (K != OCM_Message) {
6604f7df9beSJordan Rose         const_cast<ObjCMethodCall *>(this)->Data
6614f7df9beSJordan Rose           = ObjCMessageDataTy(POE, K).getOpaqueValue();
6624f7df9beSJordan Rose         assert(getMessageKind() == K);
6634f7df9beSJordan Rose         return K;
6644f7df9beSJordan Rose       }
6654f7df9beSJordan Rose     }
6664f7df9beSJordan Rose 
6674f7df9beSJordan Rose     const_cast<ObjCMethodCall *>(this)->Data
6684f7df9beSJordan Rose       = ObjCMessageDataTy(0, 1).getOpaqueValue();
6694f7df9beSJordan Rose     assert(getMessageKind() == OCM_Message);
6704f7df9beSJordan Rose     return OCM_Message;
6714f7df9beSJordan Rose   }
6724f7df9beSJordan Rose 
6734f7df9beSJordan Rose   ObjCMessageDataTy Info = ObjCMessageDataTy::getFromOpaqueValue(Data);
6744f7df9beSJordan Rose   if (!Info.getPointer())
6754f7df9beSJordan Rose     return OCM_Message;
6764f7df9beSJordan Rose   return static_cast<ObjCMessageKind>(Info.getInt());
6774f7df9beSJordan Rose }
6784f7df9beSJordan Rose 
679920af014SAnna Zaks 
680920af014SAnna Zaks bool ObjCMethodCall::canBeOverridenInSubclass(ObjCInterfaceDecl *IDecl,
681920af014SAnna Zaks                                              Selector Sel) const {
682920af014SAnna Zaks   assert(IDecl);
683920af014SAnna Zaks   const SourceManager &SM =
684920af014SAnna Zaks     getState()->getStateManager().getContext().getSourceManager();
685920af014SAnna Zaks 
686920af014SAnna Zaks   // If the class interface is declared inside the main file, assume it is not
687920af014SAnna Zaks   // subcassed.
688920af014SAnna Zaks   // TODO: It could actually be subclassed if the subclass is private as well.
689920af014SAnna Zaks   // This is probably very rare.
690920af014SAnna Zaks   SourceLocation InterfLoc = IDecl->getEndOfDefinitionLoc();
691920af014SAnna Zaks   if (InterfLoc.isValid() && SM.isFromMainFile(InterfLoc))
692920af014SAnna Zaks     return false;
693920af014SAnna Zaks 
6946ddb6b1aSAnna Zaks   // Assume that property accessors are not overridden.
6956ddb6b1aSAnna Zaks   if (getMessageKind() == OCM_PropertyAccess)
6966ddb6b1aSAnna Zaks     return false;
697920af014SAnna Zaks 
698920af014SAnna Zaks   // We assume that if the method is public (declared outside of main file) or
699920af014SAnna Zaks   // has a parent which publicly declares the method, the method could be
700920af014SAnna Zaks   // overridden in a subclass.
701920af014SAnna Zaks 
702920af014SAnna Zaks   // Find the first declaration in the class hierarchy that declares
703920af014SAnna Zaks   // the selector.
704920af014SAnna Zaks   ObjCMethodDecl *D = 0;
705920af014SAnna Zaks   while (true) {
706920af014SAnna Zaks     D = IDecl->lookupMethod(Sel, true);
707920af014SAnna Zaks 
708920af014SAnna Zaks     // Cannot find a public definition.
709920af014SAnna Zaks     if (!D)
710920af014SAnna Zaks       return false;
711920af014SAnna Zaks 
712920af014SAnna Zaks     // If outside the main file,
713920af014SAnna Zaks     if (D->getLocation().isValid() && !SM.isFromMainFile(D->getLocation()))
714920af014SAnna Zaks       return true;
715920af014SAnna Zaks 
716920af014SAnna Zaks     if (D->isOverriding()) {
717920af014SAnna Zaks       // Search in the superclass on the next iteration.
718920af014SAnna Zaks       IDecl = D->getClassInterface();
719920af014SAnna Zaks       if (!IDecl)
720920af014SAnna Zaks         return false;
721920af014SAnna Zaks 
722920af014SAnna Zaks       IDecl = IDecl->getSuperClass();
723920af014SAnna Zaks       if (!IDecl)
724920af014SAnna Zaks         return false;
725920af014SAnna Zaks 
726920af014SAnna Zaks       continue;
727920af014SAnna Zaks     }
728920af014SAnna Zaks 
729920af014SAnna Zaks     return false;
730920af014SAnna Zaks   };
731920af014SAnna Zaks 
732920af014SAnna Zaks   llvm_unreachable("The while loop should always terminate.");
733920af014SAnna Zaks }
734920af014SAnna Zaks 
735123af098SAnna Zaks RuntimeDefinition ObjCMethodCall::getRuntimeDefinition() const {
73663282aefSAnna Zaks   const ObjCMessageExpr *E = getOriginExpr();
73763282aefSAnna Zaks   assert(E);
7385808eb80SAnna Zaks   Selector Sel = E->getSelector();
7394f7df9beSJordan Rose 
74063282aefSAnna Zaks   if (E->isInstanceMessage()) {
7415808eb80SAnna Zaks 
7425808eb80SAnna Zaks     // Find the the receiver type.
7435808eb80SAnna Zaks     const ObjCObjectPointerType *ReceiverT = 0;
74475f49a9cSAnna Zaks     bool CanBeSubClassed = false;
7455808eb80SAnna Zaks     QualType SupersType = E->getSuperType();
746123af098SAnna Zaks     const MemRegion *Receiver = 0;
747123af098SAnna Zaks 
7485808eb80SAnna Zaks     if (!SupersType.isNull()) {
749123af098SAnna Zaks       // Super always means the type of immediate predecessor to the method
750123af098SAnna Zaks       // where the call occurs.
75175930b65SAnna Zaks       ReceiverT = cast<ObjCObjectPointerType>(SupersType);
7525808eb80SAnna Zaks     } else {
753123af098SAnna Zaks       Receiver = getReceiverSVal().getAsRegion();
7546a97d92eSJordan Rose       if (!Receiver)
755123af098SAnna Zaks         return RuntimeDefinition();
7566a97d92eSJordan Rose 
75775f49a9cSAnna Zaks       DynamicTypeInfo DTI = getState()->getDynamicTypeInfo(Receiver);
75875f49a9cSAnna Zaks       QualType DynType = DTI.getType();
75975f49a9cSAnna Zaks       CanBeSubClassed = DTI.canBeASubClass();
76075930b65SAnna Zaks       ReceiverT = dyn_cast<ObjCObjectPointerType>(DynType);
76175f49a9cSAnna Zaks 
76275f49a9cSAnna Zaks       if (ReceiverT && CanBeSubClassed)
76375f49a9cSAnna Zaks         if (ObjCInterfaceDecl *IDecl = ReceiverT->getInterfaceDecl())
76475f49a9cSAnna Zaks           if (!canBeOverridenInSubclass(IDecl, Sel))
76575f49a9cSAnna Zaks             CanBeSubClassed = false;
7664f7df9beSJordan Rose     }
7674f7df9beSJordan Rose 
7685808eb80SAnna Zaks     // Lookup the method implementation.
7695808eb80SAnna Zaks     if (ReceiverT)
770920af014SAnna Zaks       if (ObjCInterfaceDecl *IDecl = ReceiverT->getInterfaceDecl()) {
77175f49a9cSAnna Zaks         const ObjCMethodDecl *MD = IDecl->lookupPrivateMethod(Sel);
77275f49a9cSAnna Zaks         if (CanBeSubClassed)
77375f49a9cSAnna Zaks           return RuntimeDefinition(MD, Receiver);
774920af014SAnna Zaks         else
77575f49a9cSAnna Zaks           return RuntimeDefinition(MD, 0);
776920af014SAnna Zaks       }
7775808eb80SAnna Zaks 
77863282aefSAnna Zaks   } else {
77963282aefSAnna Zaks     // This is a class method.
78063282aefSAnna Zaks     // If we have type info for the receiver class, we are calling via
78163282aefSAnna Zaks     // class name.
78263282aefSAnna Zaks     if (ObjCInterfaceDecl *IDecl = E->getReceiverInterface()) {
78363282aefSAnna Zaks       // Find/Return the method implementation.
78485383182SAnna Zaks       return RuntimeDefinition(IDecl->lookupPrivateClassMethod(Sel));
7854f7df9beSJordan Rose     }
78663282aefSAnna Zaks   }
78763282aefSAnna Zaks 
788123af098SAnna Zaks   return RuntimeDefinition();
7894f7df9beSJordan Rose }
7904f7df9beSJordan Rose 
79142e8d649SJordan Rose void ObjCMethodCall::getInitialStackFrameContents(
79242e8d649SJordan Rose                                              const StackFrameContext *CalleeCtx,
79342e8d649SJordan Rose                                              BindingsTy &Bindings) const {
79442e8d649SJordan Rose   const ObjCMethodDecl *D = cast<ObjCMethodDecl>(CalleeCtx->getDecl());
79542e8d649SJordan Rose   SValBuilder &SVB = getState()->getStateManager().getSValBuilder();
79642e8d649SJordan Rose   addParameterValuesToBindings(CalleeCtx, Bindings, SVB, *this,
79742e8d649SJordan Rose                                D->param_begin(), D->param_end());
79842e8d649SJordan Rose 
79942e8d649SJordan Rose   SVal SelfVal = getReceiverSVal();
80042e8d649SJordan Rose   if (!SelfVal.isUnknown()) {
80142e8d649SJordan Rose     const VarDecl *SelfD = CalleeCtx->getAnalysisDeclContext()->getSelfDecl();
80242e8d649SJordan Rose     MemRegionManager &MRMgr = SVB.getRegionManager();
80342e8d649SJordan Rose     Loc SelfLoc = SVB.makeLoc(MRMgr.getVarRegion(SelfD, CalleeCtx));
80442e8d649SJordan Rose     Bindings.push_back(std::make_pair(SelfLoc, SelfVal));
80542e8d649SJordan Rose   }
80642e8d649SJordan Rose }
80742e8d649SJordan Rose 
808ce6c99a5SJordan Rose CallEventRef<>
809fcd016e5SJordan Rose CallEventManager::getSimpleCall(const CallExpr *CE, ProgramStateRef State,
810fcd016e5SJordan Rose                                 const LocationContext *LCtx) {
811fcd016e5SJordan Rose   if (const CXXMemberCallExpr *MCE = dyn_cast<CXXMemberCallExpr>(CE))
812fcd016e5SJordan Rose     return create<CXXMemberCall>(MCE, State, LCtx);
813fcd016e5SJordan Rose 
814fcd016e5SJordan Rose   if (const CXXOperatorCallExpr *OpCE = dyn_cast<CXXOperatorCallExpr>(CE)) {
815fcd016e5SJordan Rose     const FunctionDecl *DirectCallee = OpCE->getDirectCallee();
816fcd016e5SJordan Rose     if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(DirectCallee))
817fcd016e5SJordan Rose       if (MD->isInstance())
818fcd016e5SJordan Rose         return create<CXXMemberOperatorCall>(OpCE, State, LCtx);
819fcd016e5SJordan Rose 
820fcd016e5SJordan Rose   } else if (CE->getCallee()->getType()->isBlockPointerType()) {
821fcd016e5SJordan Rose     return create<BlockCall>(CE, State, LCtx);
822fcd016e5SJordan Rose   }
823fcd016e5SJordan Rose 
824fcd016e5SJordan Rose   // Otherwise, it's a normal function call, static member function call, or
825fcd016e5SJordan Rose   // something we can't reason about.
826fcd016e5SJordan Rose   return create<FunctionCall>(CE, State, LCtx);
827fcd016e5SJordan Rose }
828c2d249ceSJordan Rose 
829c2d249ceSJordan Rose 
830c2d249ceSJordan Rose CallEventRef<>
831c2d249ceSJordan Rose CallEventManager::getCaller(const StackFrameContext *CalleeCtx,
832c2d249ceSJordan Rose                             ProgramStateRef State) {
833c2d249ceSJordan Rose   const LocationContext *ParentCtx = CalleeCtx->getParent();
834c2d249ceSJordan Rose   const LocationContext *CallerCtx = ParentCtx->getCurrentStackFrame();
835c2d249ceSJordan Rose   assert(CallerCtx && "This should not be used for top-level stack frames");
836c2d249ceSJordan Rose 
837c2d249ceSJordan Rose   const Stmt *CallSite = CalleeCtx->getCallSite();
838c2d249ceSJordan Rose 
839c2d249ceSJordan Rose   if (CallSite) {
840c2d249ceSJordan Rose     if (const CallExpr *CE = dyn_cast<CallExpr>(CallSite))
841c2d249ceSJordan Rose       return getSimpleCall(CE, State, CallerCtx);
842c2d249ceSJordan Rose 
843c2d249ceSJordan Rose     switch (CallSite->getStmtClass()) {
844*8d48938bSJordan Rose     case Stmt::CXXConstructExprClass:
845*8d48938bSJordan Rose     case Stmt::CXXTemporaryObjectExprClass: {
846c2d249ceSJordan Rose       SValBuilder &SVB = State->getStateManager().getSValBuilder();
847c2d249ceSJordan Rose       const CXXMethodDecl *Ctor = cast<CXXMethodDecl>(CalleeCtx->getDecl());
848c2d249ceSJordan Rose       Loc ThisPtr = SVB.getCXXThis(Ctor, CalleeCtx);
849c2d249ceSJordan Rose       SVal ThisVal = State->getSVal(ThisPtr);
850c2d249ceSJordan Rose 
851c2d249ceSJordan Rose       return getCXXConstructorCall(cast<CXXConstructExpr>(CallSite),
852c2d249ceSJordan Rose                                    ThisVal.getAsRegion(), State, CallerCtx);
853c2d249ceSJordan Rose     }
854c2d249ceSJordan Rose     case Stmt::CXXNewExprClass:
855c2d249ceSJordan Rose       return getCXXAllocatorCall(cast<CXXNewExpr>(CallSite), State, CallerCtx);
856c2d249ceSJordan Rose     case Stmt::ObjCMessageExprClass:
857c2d249ceSJordan Rose       return getObjCMethodCall(cast<ObjCMessageExpr>(CallSite),
858c2d249ceSJordan Rose                                State, CallerCtx);
859c2d249ceSJordan Rose     default:
860c2d249ceSJordan Rose       llvm_unreachable("This is not an inlineable statement.");
861c2d249ceSJordan Rose     }
862c2d249ceSJordan Rose   }
863c2d249ceSJordan Rose 
864c2d249ceSJordan Rose   // Fall back to the CFG. The only thing we haven't handled yet is
865c2d249ceSJordan Rose   // destructors, though this could change in the future.
866c2d249ceSJordan Rose   const CFGBlock *B = CalleeCtx->getCallSiteBlock();
867c2d249ceSJordan Rose   CFGElement E = (*B)[CalleeCtx->getIndex()];
868c2d249ceSJordan Rose   assert(isa<CFGImplicitDtor>(E) && "All other CFG elements should have exprs");
869c2d249ceSJordan Rose   assert(!isa<CFGTemporaryDtor>(E) && "We don't handle temporaries yet");
870c2d249ceSJordan Rose 
871c2d249ceSJordan Rose   SValBuilder &SVB = State->getStateManager().getSValBuilder();
872c2d249ceSJordan Rose   const CXXDestructorDecl *Dtor = cast<CXXDestructorDecl>(CalleeCtx->getDecl());
873c2d249ceSJordan Rose   Loc ThisPtr = SVB.getCXXThis(Dtor, CalleeCtx);
874c2d249ceSJordan Rose   SVal ThisVal = State->getSVal(ThisPtr);
875c2d249ceSJordan Rose 
876c2d249ceSJordan Rose   const Stmt *Trigger;
877c2d249ceSJordan Rose   if (const CFGAutomaticObjDtor *AutoDtor = dyn_cast<CFGAutomaticObjDtor>(&E))
878c2d249ceSJordan Rose     Trigger = AutoDtor->getTriggerStmt();
879c2d249ceSJordan Rose   else
880c2d249ceSJordan Rose     Trigger = Dtor->getBody();
881c2d249ceSJordan Rose 
882c2d249ceSJordan Rose   return getCXXDestructorCall(Dtor, Trigger, ThisVal.getAsRegion(),
883c2d249ceSJordan Rose                               State, CallerCtx);
884c2d249ceSJordan Rose }
885