CallEvent.cpp revision b7a23e05d1d8f07f2a6edce5c88c728fe894c2c7
16f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin//===- Calls.cpp - Wrapper for all function and method calls ------*- C++ -*--//
26f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin//
36f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin//                     The LLVM Compiler Infrastructure
46f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin//
56f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin// This file is distributed under the University of Illinois Open Source
66f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin// License. See LICENSE.TXT for details.
76f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin//
86f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin//===----------------------------------------------------------------------===//
96f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin//
106f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin/// \file This file defines CallEvent and its subclasses, which represent path-
116f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin/// sensitive instances of different kinds of function and method calls
126f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin/// (C, C++, and Objective-C).
136f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin//
146f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin//===----------------------------------------------------------------------===//
156f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
166f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin#include "clang/StaticAnalyzer/Core/PathSensitive/Calls.h"
176f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin#include "clang/Analysis/ProgramPoint.h"
186f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin#include "clang/AST/ParentMap.h"
196f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin#include "llvm/ADT/SmallSet.h"
206f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin#include "llvm/ADT/StringExtras.h"
216f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
226f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkinusing namespace clang;
236f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkinusing namespace ento;
246f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
256f12fff925188ced26e518cd2252aff3e93bb04eAlexander GutkinQualType CallEvent::getResultType() const {
266f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  QualType ResultTy = getDeclaredResultType();
276f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
286f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  if (ResultTy.isNull())
296f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    ResultTy = getOriginExpr()->getType();
306f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
316f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  return ResultTy;
326f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin}
336f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
346f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkinstatic bool isCallbackArg(SVal V, QualType T) {
356f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  // If the parameter is 0, it's harmless.
366f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  if (V.isZeroConstant())
376f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    return false;
386f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
396f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  // If a parameter is a block or a callback, assume it can modify pointer.
406f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  if (T->isBlockPointerType() ||
416f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      T->isFunctionPointerType() ||
426f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      T->isObjCSelType())
436f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    return true;
446f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
456f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  // Check if a callback is passed inside a struct (for both, struct passed by
466f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  // reference and by value). Dig just one level into the struct for now.
476f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
486f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  if (isa<PointerType>(T) || isa<ReferenceType>(T))
496f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    T = T->getPointeeType();
506f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
516f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  if (const RecordType *RT = T->getAsStructureType()) {
526f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    const RecordDecl *RD = RT->getDecl();
536f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    for (RecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end();
546f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin         I != E; ++I) {
556f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      QualType FieldT = I->getType();
566f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      if (FieldT->isBlockPointerType() || FieldT->isFunctionPointerType())
576f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        return true;
586f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    }
596f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  }
606f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
616f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  return false;
626f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin}
636f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
646f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkinbool CallEvent::hasNonZeroCallbackArg() const {
656f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  unsigned NumOfArgs = getNumArgs();
666f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
676f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  // If calling using a function pointer, assume the function does not
686f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  // have a callback. TODO: We could check the types of the arguments here.
696f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  if (!getDecl())
706f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    return false;
716f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
726f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  unsigned Idx = 0;
736f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  for (CallEvent::param_type_iterator I = param_type_begin(),
746f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin                                       E = param_type_end();
756f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin       I != E && Idx < NumOfArgs; ++I, ++Idx) {
766f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    if (NumOfArgs <= Idx)
776f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      break;
786f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
796f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    if (isCallbackArg(getArgSVal(Idx), *I))
806f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      return true;
816f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  }
826f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
836f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  return false;
846f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin}
856f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
866f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin/// \brief Returns true if a type is a pointer-to-const or reference-to-const
876f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin/// with no further indirection.
886f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkinstatic bool isPointerToConst(QualType Ty) {
896f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  QualType PointeeTy = Ty->getPointeeType();
906f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  if (PointeeTy == QualType())
916f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    return false;
926f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  if (!PointeeTy.isConstQualified())
936f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    return false;
946f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  if (PointeeTy->isAnyPointerType())
956f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    return false;
966f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  return true;
976f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin}
986f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
996f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin// Try to retrieve the function declaration and find the function parameter
1006f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin// types which are pointers/references to a non-pointer const.
1016f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin// We will not invalidate the corresponding argument regions.
1026f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkinstatic void findPtrToConstParams(llvm::SmallSet<unsigned, 1> &PreserveArgs,
1036f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin                                 const CallEvent &Call) {
1046f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  unsigned Idx = 0;
1056f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  for (CallEvent::param_type_iterator I = Call.param_type_begin(),
1066f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin                                      E = Call.param_type_end();
1076f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin       I != E; ++I, ++Idx) {
1086f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    if (isPointerToConst(*I))
1096f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      PreserveArgs.insert(Idx);
1106f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  }
1116f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin}
1126f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
1136f12fff925188ced26e518cd2252aff3e93bb04eAlexander GutkinProgramStateRef CallEvent::invalidateRegions(unsigned BlockCount,
1146f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin                                              ProgramStateRef Orig) const {
1156f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  ProgramStateRef Result = (Orig ? Orig : getState());
1166f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
1176f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  SmallVector<const MemRegion *, 8> RegionsToInvalidate;
1186f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  addExtraInvalidatedRegions(RegionsToInvalidate);
1196f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
1206f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  // Indexes of arguments whose values will be preserved by the call.
1216f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  llvm::SmallSet<unsigned, 1> PreserveArgs;
1226f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  if (!argumentsMayEscape())
1236f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    findPtrToConstParams(PreserveArgs, *this);
1246f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
1256f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  for (unsigned Idx = 0, Count = getNumArgs(); Idx != Count; ++Idx) {
1266f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    if (PreserveArgs.count(Idx))
1276f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      continue;
1286f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
1296f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    SVal V = getArgSVal(Idx);
1306f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
1316f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    // If we are passing a location wrapped as an integer, unwrap it and
1326f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    // invalidate the values referred by the location.
1336f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    if (nonloc::LocAsInteger *Wrapped = dyn_cast<nonloc::LocAsInteger>(&V))
1346f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      V = Wrapped->getLoc();
1356f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    else if (!isa<Loc>(V))
1366f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      continue;
1376f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
1386f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    if (const MemRegion *R = V.getAsRegion()) {
1396f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      // Invalidate the value of the variable passed by reference.
1406f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
1416f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      // Are we dealing with an ElementRegion?  If the element type is
1426f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      // a basic integer type (e.g., char, int) and the underlying region
1436f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      // is a variable region then strip off the ElementRegion.
1446f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      // FIXME: We really need to think about this for the general case
1456f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      //   as sometimes we are reasoning about arrays and other times
1466f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      //   about (char*), etc., is just a form of passing raw bytes.
1476f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      //   e.g., void *p = alloca(); foo((char*)p);
1486f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      if (const ElementRegion *ER = dyn_cast<ElementRegion>(R)) {
1496f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        // Checking for 'integral type' is probably too promiscuous, but
1506f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        // we'll leave it in for now until we have a systematic way of
1516f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        // handling all of these cases.  Eventually we need to come up
1526f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        // with an interface to StoreManager so that this logic can be
1536f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        // appropriately delegated to the respective StoreManagers while
1546f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        // still allowing us to do checker-specific logic (e.g.,
1556f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        // invalidating reference counts), probably via callbacks.
1566f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        if (ER->getElementType()->isIntegralOrEnumerationType()) {
1576f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin          const MemRegion *superReg = ER->getSuperRegion();
1586f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin          if (isa<VarRegion>(superReg) || isa<FieldRegion>(superReg) ||
1596f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin              isa<ObjCIvarRegion>(superReg))
1606f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin            R = cast<TypedRegion>(superReg);
1616f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        }
1626f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin        // FIXME: What about layers of ElementRegions?
1636f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      }
1646f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
1656f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      // Mark this region for invalidation.  We batch invalidate regions
1666f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      // below for efficiency.
1676f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      RegionsToInvalidate.push_back(R);
1686f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    }
1696f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  }
1706f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
1716f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  // Invalidate designated regions using the batch invalidation API.
1726f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  // NOTE: Even if RegionsToInvalidate is empty, we may still invalidate
1736f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  //  global variables.
1746f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  return Result->invalidateRegions(RegionsToInvalidate, getOriginExpr(),
1756f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin                                   BlockCount, getLocationContext(),
1766f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin                                   /*Symbols=*/0, this);
1776f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin}
1786f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
1796f12fff925188ced26e518cd2252aff3e93bb04eAlexander GutkinProgramPoint CallEvent::getProgramPoint(bool IsPreVisit,
1806f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin                                        const ProgramPointTag *Tag) const {
1816f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  if (const Expr *E = getOriginExpr()) {
1826f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    if (IsPreVisit)
1836f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin      return PreStmt(E, getLocationContext(), Tag);
1846f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    return PostStmt(E, getLocationContext(), Tag);
1856f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  }
1866f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
1876f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  const Decl *D = getDecl();
1886f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  assert(D && "Cannot get a program point without a statement or decl");
1896f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
1906f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  SourceLocation Loc = getSourceRange().getBegin();
1916f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  if (IsPreVisit)
1926f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    return PreImplicitCall(D, Loc, getLocationContext(), Tag);
1936f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  return PostImplicitCall(D, Loc, getLocationContext(), Tag);
1946f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin}
1956f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
1966f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
1976f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkinbool CallEvent::mayBeInlined(const Stmt *S) {
1986f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  return isa<CallExpr>(S);
1996f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin}
2006f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
2016f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
2026f12fff925188ced26e518cd2252aff3e93bb04eAlexander GutkinCallEvent::param_iterator
2036f12fff925188ced26e518cd2252aff3e93bb04eAlexander GutkinAnyFunctionCall::param_begin(bool UseDefinitionParams) const {
2046f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  bool IgnoredDynamicDispatch;
2056f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  const Decl *D = UseDefinitionParams ? getDefinition(IgnoredDynamicDispatch)
2066f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin                                      : getDecl();
2076f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  if (!D)
2086f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    return 0;
2096f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
2106f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  return cast<FunctionDecl>(D)->param_begin();
2116f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin}
2126f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
2136f12fff925188ced26e518cd2252aff3e93bb04eAlexander GutkinCallEvent::param_iterator
2146f12fff925188ced26e518cd2252aff3e93bb04eAlexander GutkinAnyFunctionCall::param_end(bool UseDefinitionParams) const {
2156f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  bool IgnoredDynamicDispatch;
2166f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  const Decl *D = UseDefinitionParams ? getDefinition(IgnoredDynamicDispatch)
2176f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin                                      : getDecl();
2186f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  if (!D)
2196f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    return 0;
2206f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
2216f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  return cast<FunctionDecl>(D)->param_end();
2226f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin}
2236f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
2246f12fff925188ced26e518cd2252aff3e93bb04eAlexander GutkinQualType AnyFunctionCall::getDeclaredResultType() const {
2256f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  const FunctionDecl *D = getDecl();
2266f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  if (!D)
2276f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    return QualType();
2286f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
2296f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  return D->getResultType();
2306f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin}
2316f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
2326f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkinbool AnyFunctionCall::argumentsMayEscape() const {
2336f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  if (hasNonZeroCallbackArg())
2346f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    return true;
2356f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
2366f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  const FunctionDecl *D = getDecl();
2376f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  if (!D)
2386f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    return true;
2396f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
2406f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  const IdentifierInfo *II = D->getIdentifier();
2416f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  if (!II)
2426f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    return true;
2436f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
2446f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  // This set of "escaping" APIs is
2456f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
2466f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  // - 'int pthread_setspecific(ptheread_key k, const void *)' stores a
2476f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  //   value into thread local storage. The value can later be retrieved with
2486f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  //   'void *ptheread_getspecific(pthread_key)'. So even thought the
2496f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  //   parameter is 'const void *', the region escapes through the call.
2506f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  if (II->isStr("pthread_setspecific"))
2516f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    return true;
2526f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
2536f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  // - xpc_connection_set_context stores a value which can be retrieved later
2546f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  //   with xpc_connection_get_context.
2556f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  if (II->isStr("xpc_connection_set_context"))
2566f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    return true;
2576f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
2586f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  // - funopen - sets a buffer for future IO calls.
2596f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  if (II->isStr("funopen"))
2606f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    return true;
2616f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
2626f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  StringRef FName = II->getName();
2636f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
2646f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  // - CoreFoundation functions that end with "NoCopy" can free a passed-in
2656f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  //   buffer even if it is const.
2666f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  if (FName.endswith("NoCopy"))
2676f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    return true;
2686f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
2696f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  // - NSXXInsertXX, for example NSMapInsertIfAbsent, since they can
2706f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  //   be deallocated by NSMapRemove.
2716f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  if (FName.startswith("NS") && (FName.find("Insert") != StringRef::npos))
2726f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    return true;
2736f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
2746f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  // - Many CF containers allow objects to escape through custom
2756f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  //   allocators/deallocators upon container construction. (PR12101)
2766f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  if (FName.startswith("CF") || FName.startswith("CG")) {
2776f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    return StrInStrNoCase(FName, "InsertValue")  != StringRef::npos ||
2786f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin           StrInStrNoCase(FName, "AddValue")     != StringRef::npos ||
2796f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin           StrInStrNoCase(FName, "SetValue")     != StringRef::npos ||
2806f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin           StrInStrNoCase(FName, "WithData")     != StringRef::npos ||
2816f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin           StrInStrNoCase(FName, "AppendValue")  != StringRef::npos ||
2826f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin           StrInStrNoCase(FName, "SetAttribute") != StringRef::npos;
2836f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  }
2846f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
2856f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  return false;
2866f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin}
2876f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
2886f12fff925188ced26e518cd2252aff3e93bb04eAlexander GutkinSVal AnyFunctionCall::getArgSVal(unsigned Index) const {
2896f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  const Expr *ArgE = getArgExpr(Index);
2906f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  if (!ArgE)
2916f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    return UnknownVal();
2926f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  return getSVal(ArgE);
2936f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin}
2946f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
2956f12fff925188ced26e518cd2252aff3e93bb04eAlexander GutkinSourceRange AnyFunctionCall::getArgSourceRange(unsigned Index) const {
2966f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  const Expr *ArgE = getArgExpr(Index);
2976f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  if (!ArgE)
2986f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    return SourceRange();
2996f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  return ArgE->getSourceRange();
3006f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin}
3016f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
3026f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
3036f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkinconst FunctionDecl *SimpleCall::getDecl() const {
3046f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  const FunctionDecl *D = getOriginExpr()->getDirectCallee();
3056f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  if (D)
3066f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    return D;
3076f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
3086f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  return getSVal(getOriginExpr()->getCallee()).getAsFunctionDecl();
3096f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin}
3106f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
3116f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkinvoid CallEvent::dump(raw_ostream &Out) const {
3126f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  ASTContext &Ctx = getState()->getStateManager().getContext();
3136f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  if (const Expr *E = getOriginExpr()) {
3146f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    E->printPretty(Out, Ctx, 0, Ctx.getLangOpts());
3156f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    Out << "\n";
3166f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    return;
3176f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  }
3186f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
3196f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  if (const Decl *D = getDecl()) {
3206f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    Out << "Call to ";
3216f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    D->print(Out, Ctx.getLangOpts());
3226f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    return;
3236f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  }
3246f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
3256f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  // FIXME: a string representation of the kind would be nice.
3266f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  Out << "Unknown call (type " << getKind() << ")";
3276f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin}
3286f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
3296f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
3306f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkinvoid CXXInstanceCall::addExtraInvalidatedRegions(RegionList &Regions) const {
3316f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  if (const MemRegion *R = getCXXThisVal().getAsRegion())
3326f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    Regions.push_back(R);
3336f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin}
3346f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
3356f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkinstatic const CXXMethodDecl *devirtualize(const CXXMethodDecl *MD, SVal ThisVal){
3366f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  const MemRegion *R = ThisVal.getAsRegion();
3376f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  if (!R)
3386f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    return 0;
3396f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
3406f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  const TypedValueRegion *TR = dyn_cast<TypedValueRegion>(R->StripCasts());
3416f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  if (!TR)
3426f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    return 0;
3436f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
3446f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  const CXXRecordDecl *RD = TR->getValueType()->getAsCXXRecordDecl();
3456f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  if (!RD)
3466f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    return 0;
3476f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
3486f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  const CXXMethodDecl *Result = MD->getCorrespondingMethodInClass(RD);
3496f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  const FunctionDecl *Definition;
3506f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  if (!Result->hasBody(Definition))
3516f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    return 0;
3526f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
3536f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  return cast<CXXMethodDecl>(Definition);
3546f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin}
3556f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
3566f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
3576f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkinconst Decl *CXXInstanceCall::getDefinition(bool &IsDynamicDispatch) const {
3586f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  const Decl *D = SimpleCall::getDefinition(IsDynamicDispatch);
3596f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  if (!D)
3606f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    return 0;
3616f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
3626f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  const CXXMethodDecl *MD = cast<CXXMethodDecl>(D);
3636f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  if (!MD->isVirtual())
3646f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    return MD;
3656f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
3666f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  // If the method is virtual, see if we can find the actual implementation
3676f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  // based on context-sensitivity.
3686f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  if (const CXXMethodDecl *Devirtualized = devirtualize(MD, getCXXThisVal()))
3696f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    return Devirtualized;
3706f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
3716f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  IsDynamicDispatch = true;
3726f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  return MD;
3736f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin}
3746f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
3756f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
3766f12fff925188ced26e518cd2252aff3e93bb04eAlexander GutkinSVal CXXMemberCall::getCXXThisVal() const {
3776f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  const Expr *Base = getOriginExpr()->getImplicitObjectArgument();
3786f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
3796f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  // FIXME: Will eventually need to cope with member pointers.  This is
3806f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  // a limitation in getImplicitObjectArgument().
3816f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  if (!Base)
3826f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    return UnknownVal();
3836f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
3846f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  return getSVal(Base);
3856f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin}
3866f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
3876f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
3886f12fff925188ced26e518cd2252aff3e93bb04eAlexander GutkinSVal CXXMemberOperatorCall::getCXXThisVal() const {
3896f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  const Expr *Base = getOriginExpr()->getArg(0);
3906f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  return getSVal(Base);
3916f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin}
3926f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
3936f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
3946f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkinconst BlockDataRegion *BlockCall::getBlockRegion() const {
3956f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  const Expr *Callee = getOriginExpr()->getCallee();
3966f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  const MemRegion *DataReg = getSVal(Callee).getAsRegion();
3976f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
3986f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  return dyn_cast_or_null<BlockDataRegion>(DataReg);
3996f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin}
4006f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
4016f12fff925188ced26e518cd2252aff3e93bb04eAlexander GutkinCallEvent::param_iterator
4026f12fff925188ced26e518cd2252aff3e93bb04eAlexander GutkinBlockCall::param_begin(bool UseDefinitionParams) const {
4036f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  // Blocks don't have distinct declarations and definitions.
4046f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  (void)UseDefinitionParams;
4056f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
4066f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  const BlockDecl *D = getBlockDecl();
4076f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  if (!D)
4086f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    return 0;
4096f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  return D->param_begin();
4106f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin}
4116f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
4126f12fff925188ced26e518cd2252aff3e93bb04eAlexander GutkinCallEvent::param_iterator
4136f12fff925188ced26e518cd2252aff3e93bb04eAlexander GutkinBlockCall::param_end(bool UseDefinitionParams) const {
4146f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  // Blocks don't have distinct declarations and definitions.
4156f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  (void)UseDefinitionParams;
4166f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
4176f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  const BlockDecl *D = getBlockDecl();
4186f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  if (!D)
4196f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    return 0;
4206f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  return D->param_end();
4216f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin}
4226f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
4236f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkinvoid BlockCall::addExtraInvalidatedRegions(RegionList &Regions) const {
4246f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  // FIXME: This also needs to invalidate captured globals.
4256f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  if (const MemRegion *R = getBlockRegion())
4266f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    Regions.push_back(R);
4276f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin}
4286f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
4296f12fff925188ced26e518cd2252aff3e93bb04eAlexander GutkinQualType BlockCall::getDeclaredResultType() const {
4306f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  const BlockDataRegion *BR = getBlockRegion();
4316f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  if (!BR)
4326f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    return QualType();
4336f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  QualType BlockTy = BR->getCodeRegion()->getLocationType();
4346f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  return cast<FunctionType>(BlockTy->getPointeeType())->getResultType();
4356f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin}
4366f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
4376f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
4386f12fff925188ced26e518cd2252aff3e93bb04eAlexander GutkinSVal CXXConstructorCall::getCXXThisVal() const {
4396f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  if (Data)
4406f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    return loc::MemRegionVal(static_cast<const MemRegion *>(Data));
4416f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  return UnknownVal();
4426f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin}
4436f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
4446f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkinvoid CXXConstructorCall::addExtraInvalidatedRegions(RegionList &Regions) const {
4456f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  if (Data)
4466f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    Regions.push_back(static_cast<const MemRegion *>(Data));
4476f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin}
4486f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
4496f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
4506f12fff925188ced26e518cd2252aff3e93bb04eAlexander GutkinSVal CXXDestructorCall::getCXXThisVal() const {
4516f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  if (Data)
4526f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    return loc::MemRegionVal(static_cast<const MemRegion *>(Data));
4536f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  return UnknownVal();
4546f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin}
4556f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
4566f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkinvoid CXXDestructorCall::addExtraInvalidatedRegions(RegionList &Regions) const {
4576f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  if (Data)
4586f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    Regions.push_back(static_cast<const MemRegion *>(Data));
4596f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin}
4606f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
4616f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkinconst Decl *CXXDestructorCall::getDefinition(bool &IsDynamicDispatch) const {
4626f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  const Decl *D = AnyFunctionCall::getDefinition(IsDynamicDispatch);
4636f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  if (!D)
4646f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    return 0;
4656f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
4666f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  const CXXMethodDecl *MD = cast<CXXMethodDecl>(D);
4676f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  if (!MD->isVirtual())
4686f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    return MD;
4696f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
4706f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  // If the method is virtual, see if we can find the actual implementation
4716f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  // based on context-sensitivity.
4726f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  if (const CXXMethodDecl *Devirtualized = devirtualize(MD, getCXXThisVal()))
4736f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin    return Devirtualized;
4746f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin
4756f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  IsDynamicDispatch = true;
4766f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin  return MD;
4776f12fff925188ced26e518cd2252aff3e93bb04eAlexander Gutkin}
478
479
480CallEvent::param_iterator
481ObjCMethodCall::param_begin(bool UseDefinitionParams) const {
482  bool IgnoredDynamicDispatch;
483  const Decl *D = UseDefinitionParams ? getDefinition(IgnoredDynamicDispatch)
484                                      : getDecl();
485  if (!D)
486    return 0;
487
488  return cast<ObjCMethodDecl>(D)->param_begin();
489}
490
491CallEvent::param_iterator
492ObjCMethodCall::param_end(bool UseDefinitionParams) const {
493  bool IgnoredDynamicDispatch;
494  const Decl *D = UseDefinitionParams ? getDefinition(IgnoredDynamicDispatch)
495                                      : getDecl();
496  if (!D)
497    return 0;
498
499  return cast<ObjCMethodDecl>(D)->param_end();
500}
501
502void
503ObjCMethodCall::addExtraInvalidatedRegions(RegionList &Regions) const {
504  if (const MemRegion *R = getReceiverSVal().getAsRegion())
505    Regions.push_back(R);
506}
507
508QualType ObjCMethodCall::getDeclaredResultType() const {
509  const ObjCMethodDecl *D = getDecl();
510  if (!D)
511    return QualType();
512
513  return D->getResultType();
514}
515
516SVal ObjCMethodCall::getReceiverSVal() const {
517  // FIXME: Is this the best way to handle class receivers?
518  if (!isInstanceMessage())
519    return UnknownVal();
520
521  if (const Expr *Base = getInstanceReceiverExpr())
522    return getSVal(Base);
523
524  // An instance message with no expression means we are sending to super.
525  // In this case the object reference is the same as 'self'.
526  const LocationContext *LCtx = getLocationContext();
527  const ImplicitParamDecl *SelfDecl = LCtx->getSelfDecl();
528  assert(SelfDecl && "No message receiver Expr, but not in an ObjC method");
529  return getState()->getSVal(getState()->getRegion(SelfDecl, LCtx));
530}
531
532SourceRange ObjCPropertyAccess::getSourceRange() const {
533  const ParentMap &PM = getLocationContext()->getParentMap();
534  const ObjCMessageExpr *ME = getOriginExpr();
535  const PseudoObjectExpr *PO = cast<PseudoObjectExpr>(PM.getParent(ME));
536  return PO->getSourceRange();
537}
538
539