CallEvent.cpp revision 740d490593e0de8732a697c9f77b90ddd463863b
1740d490593e0de8732a697c9f77b90ddd463863bJordan Rose//===- Calls.cpp - Wrapper for all function and method calls ------*- C++ -*--//
2740d490593e0de8732a697c9f77b90ddd463863bJordan Rose//
3740d490593e0de8732a697c9f77b90ddd463863bJordan Rose//                     The LLVM Compiler Infrastructure
4740d490593e0de8732a697c9f77b90ddd463863bJordan Rose//
5740d490593e0de8732a697c9f77b90ddd463863bJordan Rose// This file is distributed under the University of Illinois Open Source
6740d490593e0de8732a697c9f77b90ddd463863bJordan Rose// License. See LICENSE.TXT for details.
7740d490593e0de8732a697c9f77b90ddd463863bJordan Rose//
8740d490593e0de8732a697c9f77b90ddd463863bJordan Rose//===----------------------------------------------------------------------===//
9740d490593e0de8732a697c9f77b90ddd463863bJordan Rose//
10740d490593e0de8732a697c9f77b90ddd463863bJordan Rose/// \file This file defines CallEvent and its subclasses, which represent path-
11740d490593e0de8732a697c9f77b90ddd463863bJordan Rose/// sensitive instances of different kinds of function and method calls
12740d490593e0de8732a697c9f77b90ddd463863bJordan Rose/// (C, C++, and Objective-C).
13740d490593e0de8732a697c9f77b90ddd463863bJordan Rose//
14740d490593e0de8732a697c9f77b90ddd463863bJordan Rose//===----------------------------------------------------------------------===//
15740d490593e0de8732a697c9f77b90ddd463863bJordan Rose
16740d490593e0de8732a697c9f77b90ddd463863bJordan Rose#include "clang/StaticAnalyzer/Core/PathSensitive/Calls.h"
17740d490593e0de8732a697c9f77b90ddd463863bJordan Rose#include "clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h"
18740d490593e0de8732a697c9f77b90ddd463863bJordan Rose#include "llvm/ADT/SmallSet.h"
19740d490593e0de8732a697c9f77b90ddd463863bJordan Rose
20740d490593e0de8732a697c9f77b90ddd463863bJordan Roseusing namespace clang;
21740d490593e0de8732a697c9f77b90ddd463863bJordan Roseusing namespace ento;
22740d490593e0de8732a697c9f77b90ddd463863bJordan Rose
23740d490593e0de8732a697c9f77b90ddd463863bJordan RoseSVal CallEvent::getArgSVal(unsigned Index) const {
24740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  const Expr *ArgE = getArgExpr(Index);
25740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  if (!ArgE)
26740d490593e0de8732a697c9f77b90ddd463863bJordan Rose    return UnknownVal();
27740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  return getSVal(ArgE);
28740d490593e0de8732a697c9f77b90ddd463863bJordan Rose}
29740d490593e0de8732a697c9f77b90ddd463863bJordan Rose
30740d490593e0de8732a697c9f77b90ddd463863bJordan RoseSourceRange CallEvent::getArgSourceRange(unsigned Index) const {
31740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  const Expr *ArgE = getArgExpr(Index);
32740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  if (!ArgE)
33740d490593e0de8732a697c9f77b90ddd463863bJordan Rose    return SourceRange();
34740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  return ArgE->getSourceRange();
35740d490593e0de8732a697c9f77b90ddd463863bJordan Rose}
36740d490593e0de8732a697c9f77b90ddd463863bJordan Rose
37740d490593e0de8732a697c9f77b90ddd463863bJordan RoseQualType CallEvent::getResultType() const {
38740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  QualType ResultTy = getDeclaredResultType();
39740d490593e0de8732a697c9f77b90ddd463863bJordan Rose
40740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  if (const Expr *E = getOriginExpr()) {
41740d490593e0de8732a697c9f77b90ddd463863bJordan Rose    if (ResultTy.isNull())
42740d490593e0de8732a697c9f77b90ddd463863bJordan Rose      ResultTy = E->getType();
43740d490593e0de8732a697c9f77b90ddd463863bJordan Rose
44740d490593e0de8732a697c9f77b90ddd463863bJordan Rose    // FIXME: This is copied from CallOrObjCMessage, but it seems suspicious.
45740d490593e0de8732a697c9f77b90ddd463863bJordan Rose    if (E->isGLValue()) {
46740d490593e0de8732a697c9f77b90ddd463863bJordan Rose      ASTContext &Ctx = State->getStateManager().getContext();
47740d490593e0de8732a697c9f77b90ddd463863bJordan Rose      ResultTy = Ctx.getPointerType(ResultTy);
48740d490593e0de8732a697c9f77b90ddd463863bJordan Rose    }
49740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  }
50740d490593e0de8732a697c9f77b90ddd463863bJordan Rose
51740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  return ResultTy;
52740d490593e0de8732a697c9f77b90ddd463863bJordan Rose}
53740d490593e0de8732a697c9f77b90ddd463863bJordan Rose
54740d490593e0de8732a697c9f77b90ddd463863bJordan Rosestatic bool isCallbackArg(SVal V, QualType T) {
55740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  // If the parameter is 0, it's harmless.
56740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  if (V.isZeroConstant())
57740d490593e0de8732a697c9f77b90ddd463863bJordan Rose    return false;
58740d490593e0de8732a697c9f77b90ddd463863bJordan Rose
59740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  // If a parameter is a block or a callback, assume it can modify pointer.
60740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  if (T->isBlockPointerType() ||
61740d490593e0de8732a697c9f77b90ddd463863bJordan Rose      T->isFunctionPointerType() ||
62740d490593e0de8732a697c9f77b90ddd463863bJordan Rose      T->isObjCSelType())
63740d490593e0de8732a697c9f77b90ddd463863bJordan Rose    return true;
64740d490593e0de8732a697c9f77b90ddd463863bJordan Rose
65740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  // Check if a callback is passed inside a struct (for both, struct passed by
66740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  // reference and by value). Dig just one level into the struct for now.
67740d490593e0de8732a697c9f77b90ddd463863bJordan Rose
68740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  if (isa<PointerType>(T) || isa<ReferenceType>(T))
69740d490593e0de8732a697c9f77b90ddd463863bJordan Rose    T = T->getPointeeType();
70740d490593e0de8732a697c9f77b90ddd463863bJordan Rose
71740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  if (const RecordType *RT = T->getAsStructureType()) {
72740d490593e0de8732a697c9f77b90ddd463863bJordan Rose    const RecordDecl *RD = RT->getDecl();
73740d490593e0de8732a697c9f77b90ddd463863bJordan Rose    for (RecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end();
74740d490593e0de8732a697c9f77b90ddd463863bJordan Rose         I != E; ++I) {
75740d490593e0de8732a697c9f77b90ddd463863bJordan Rose      QualType FieldT = I->getType();
76740d490593e0de8732a697c9f77b90ddd463863bJordan Rose      if (FieldT->isBlockPointerType() || FieldT->isFunctionPointerType())
77740d490593e0de8732a697c9f77b90ddd463863bJordan Rose        return true;
78740d490593e0de8732a697c9f77b90ddd463863bJordan Rose    }
79740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  }
80740d490593e0de8732a697c9f77b90ddd463863bJordan Rose
81740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  return false;
82740d490593e0de8732a697c9f77b90ddd463863bJordan Rose}
83740d490593e0de8732a697c9f77b90ddd463863bJordan Rose
84740d490593e0de8732a697c9f77b90ddd463863bJordan Rosebool CallEvent::hasNonZeroCallbackArg() const {
85740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  unsigned NumOfArgs = getNumArgs();
86740d490593e0de8732a697c9f77b90ddd463863bJordan Rose
87740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  // If calling using a function pointer, assume the function does not
88740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  // have a callback. TODO: We could check the types of the arguments here.
89740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  if (!getDecl())
90740d490593e0de8732a697c9f77b90ddd463863bJordan Rose    return false;
91740d490593e0de8732a697c9f77b90ddd463863bJordan Rose
92740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  unsigned Idx = 0;
93740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  for (CallEvent::param_type_iterator I = param_type_begin(),
94740d490593e0de8732a697c9f77b90ddd463863bJordan Rose                                       E = param_type_end();
95740d490593e0de8732a697c9f77b90ddd463863bJordan Rose       I != E && Idx < NumOfArgs; ++I, ++Idx) {
96740d490593e0de8732a697c9f77b90ddd463863bJordan Rose    if (NumOfArgs <= Idx)
97740d490593e0de8732a697c9f77b90ddd463863bJordan Rose      break;
98740d490593e0de8732a697c9f77b90ddd463863bJordan Rose
99740d490593e0de8732a697c9f77b90ddd463863bJordan Rose    if (isCallbackArg(getArgSVal(Idx), *I))
100740d490593e0de8732a697c9f77b90ddd463863bJordan Rose      return true;
101740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  }
102740d490593e0de8732a697c9f77b90ddd463863bJordan Rose
103740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  return false;
104740d490593e0de8732a697c9f77b90ddd463863bJordan Rose}
105740d490593e0de8732a697c9f77b90ddd463863bJordan Rose
106740d490593e0de8732a697c9f77b90ddd463863bJordan Rose/// \brief Returns true if a type is a pointer-to-const or reference-to-const
107740d490593e0de8732a697c9f77b90ddd463863bJordan Rose/// with no further indirection.
108740d490593e0de8732a697c9f77b90ddd463863bJordan Rosestatic bool isPointerToConst(QualType Ty) {
109740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  QualType PointeeTy = Ty->getPointeeType();
110740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  if (PointeeTy == QualType())
111740d490593e0de8732a697c9f77b90ddd463863bJordan Rose    return false;
112740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  if (!PointeeTy.isConstQualified())
113740d490593e0de8732a697c9f77b90ddd463863bJordan Rose    return false;
114740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  if (PointeeTy->isAnyPointerType())
115740d490593e0de8732a697c9f77b90ddd463863bJordan Rose    return false;
116740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  return true;
117740d490593e0de8732a697c9f77b90ddd463863bJordan Rose}
118740d490593e0de8732a697c9f77b90ddd463863bJordan Rose
119740d490593e0de8732a697c9f77b90ddd463863bJordan Rose// Try to retrieve the function declaration and find the function parameter
120740d490593e0de8732a697c9f77b90ddd463863bJordan Rose// types which are pointers/references to a non-pointer const.
121740d490593e0de8732a697c9f77b90ddd463863bJordan Rose// We do not invalidate the corresponding argument regions.
122740d490593e0de8732a697c9f77b90ddd463863bJordan Rosestatic void findPtrToConstParams(llvm::SmallSet<unsigned, 1> &PreserveArgs,
123740d490593e0de8732a697c9f77b90ddd463863bJordan Rose                                 const CallEvent &Call) {
124740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  const Decl *CallDecl = Call.getDecl();
125740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  if (!CallDecl)
126740d490593e0de8732a697c9f77b90ddd463863bJordan Rose    return;
127740d490593e0de8732a697c9f77b90ddd463863bJordan Rose
128740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  if (Call.hasNonZeroCallbackArg())
129740d490593e0de8732a697c9f77b90ddd463863bJordan Rose    return;
130740d490593e0de8732a697c9f77b90ddd463863bJordan Rose
131740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  if (const FunctionDecl *FDecl = dyn_cast<FunctionDecl>(CallDecl)) {
132740d490593e0de8732a697c9f77b90ddd463863bJordan Rose    const IdentifierInfo *II = FDecl->getIdentifier();
133740d490593e0de8732a697c9f77b90ddd463863bJordan Rose
134740d490593e0de8732a697c9f77b90ddd463863bJordan Rose    // List the cases, where the region should be invalidated even if the
135740d490593e0de8732a697c9f77b90ddd463863bJordan Rose    // argument is const.
136740d490593e0de8732a697c9f77b90ddd463863bJordan Rose    // FIXME: This is conflating invalidating /contents/ and invalidating
137740d490593e0de8732a697c9f77b90ddd463863bJordan Rose    // /metadata/. Now that we pass the CallEvent to the checkers, they
138740d490593e0de8732a697c9f77b90ddd463863bJordan Rose    // should probably be doing this work themselves.
139740d490593e0de8732a697c9f77b90ddd463863bJordan Rose    if (II) {
140740d490593e0de8732a697c9f77b90ddd463863bJordan Rose      StringRef FName = II->getName();
141740d490593e0de8732a697c9f77b90ddd463863bJordan Rose      //  - 'int pthread_setspecific(ptheread_key k, const void *)' stores a
142740d490593e0de8732a697c9f77b90ddd463863bJordan Rose      // value into thread local storage. The value can later be retrieved with
143740d490593e0de8732a697c9f77b90ddd463863bJordan Rose      // 'void *ptheread_getspecific(pthread_key)'. So even thought the
144740d490593e0de8732a697c9f77b90ddd463863bJordan Rose      // parameter is 'const void *', the region escapes through the call.
145740d490593e0de8732a697c9f77b90ddd463863bJordan Rose      //  - funopen - sets a buffer for future IO calls.
146740d490593e0de8732a697c9f77b90ddd463863bJordan Rose      //  - ObjC functions that end with "NoCopy" can free memory, of the passed
147740d490593e0de8732a697c9f77b90ddd463863bJordan Rose      // in buffer.
148740d490593e0de8732a697c9f77b90ddd463863bJordan Rose      // - Many CF containers allow objects to escape through custom
149740d490593e0de8732a697c9f77b90ddd463863bJordan Rose      // allocators/deallocators upon container construction.
150740d490593e0de8732a697c9f77b90ddd463863bJordan Rose      // - NSXXInsertXX, for example NSMapInsertIfAbsent, since they can
151740d490593e0de8732a697c9f77b90ddd463863bJordan Rose      // be deallocated by NSMapRemove.
152740d490593e0de8732a697c9f77b90ddd463863bJordan Rose      // - Any call that has a callback as one of the arguments.
153740d490593e0de8732a697c9f77b90ddd463863bJordan Rose      if (FName == "pthread_setspecific" ||
154740d490593e0de8732a697c9f77b90ddd463863bJordan Rose          FName == "funopen" ||
155740d490593e0de8732a697c9f77b90ddd463863bJordan Rose          FName.endswith("NoCopy") ||
156740d490593e0de8732a697c9f77b90ddd463863bJordan Rose          (FName.startswith("NS") &&
157740d490593e0de8732a697c9f77b90ddd463863bJordan Rose           (FName.find("Insert") != StringRef::npos)) ||
158740d490593e0de8732a697c9f77b90ddd463863bJordan Rose          CallOrObjCMessage::isCFCGAllowingEscape(FName))
159740d490593e0de8732a697c9f77b90ddd463863bJordan Rose        return;
160740d490593e0de8732a697c9f77b90ddd463863bJordan Rose    }
161740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  }
162740d490593e0de8732a697c9f77b90ddd463863bJordan Rose
163740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  unsigned Idx = 0;
164740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  for (CallEvent::param_type_iterator I = Call.param_type_begin(),
165740d490593e0de8732a697c9f77b90ddd463863bJordan Rose                                       E = Call.param_type_end();
166740d490593e0de8732a697c9f77b90ddd463863bJordan Rose       I != E; ++I, ++Idx) {
167740d490593e0de8732a697c9f77b90ddd463863bJordan Rose    if (isPointerToConst(*I))
168740d490593e0de8732a697c9f77b90ddd463863bJordan Rose      PreserveArgs.insert(Idx);
169740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  }
170740d490593e0de8732a697c9f77b90ddd463863bJordan Rose}
171740d490593e0de8732a697c9f77b90ddd463863bJordan Rose
172740d490593e0de8732a697c9f77b90ddd463863bJordan RoseProgramStateRef CallEvent::invalidateRegions(unsigned BlockCount,
173740d490593e0de8732a697c9f77b90ddd463863bJordan Rose                                              ProgramStateRef Orig) const {
174740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  ProgramStateRef Result = (Orig ? Orig : State);
175740d490593e0de8732a697c9f77b90ddd463863bJordan Rose
176740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  SmallVector<const MemRegion *, 8> RegionsToInvalidate;
177740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  addExtraInvalidatedRegions(RegionsToInvalidate);
178740d490593e0de8732a697c9f77b90ddd463863bJordan Rose
179740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  // Indexes of arguments whose values will be preserved by the call.
180740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  llvm::SmallSet<unsigned, 1> PreserveArgs;
181740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  findPtrToConstParams(PreserveArgs, *this);
182740d490593e0de8732a697c9f77b90ddd463863bJordan Rose
183740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  for (unsigned Idx = 0, Count = getNumArgs(); Idx != Count; ++Idx) {
184740d490593e0de8732a697c9f77b90ddd463863bJordan Rose    if (PreserveArgs.count(Idx))
185740d490593e0de8732a697c9f77b90ddd463863bJordan Rose      continue;
186740d490593e0de8732a697c9f77b90ddd463863bJordan Rose
187740d490593e0de8732a697c9f77b90ddd463863bJordan Rose    SVal V = getArgSVal(Idx);
188740d490593e0de8732a697c9f77b90ddd463863bJordan Rose
189740d490593e0de8732a697c9f77b90ddd463863bJordan Rose    // If we are passing a location wrapped as an integer, unwrap it and
190740d490593e0de8732a697c9f77b90ddd463863bJordan Rose    // invalidate the values referred by the location.
191740d490593e0de8732a697c9f77b90ddd463863bJordan Rose    if (nonloc::LocAsInteger *Wrapped = dyn_cast<nonloc::LocAsInteger>(&V))
192740d490593e0de8732a697c9f77b90ddd463863bJordan Rose      V = Wrapped->getLoc();
193740d490593e0de8732a697c9f77b90ddd463863bJordan Rose    else if (!isa<Loc>(V))
194740d490593e0de8732a697c9f77b90ddd463863bJordan Rose      continue;
195740d490593e0de8732a697c9f77b90ddd463863bJordan Rose
196740d490593e0de8732a697c9f77b90ddd463863bJordan Rose    if (const MemRegion *R = V.getAsRegion()) {
197740d490593e0de8732a697c9f77b90ddd463863bJordan Rose      // Invalidate the value of the variable passed by reference.
198740d490593e0de8732a697c9f77b90ddd463863bJordan Rose
199740d490593e0de8732a697c9f77b90ddd463863bJordan Rose      // Are we dealing with an ElementRegion?  If the element type is
200740d490593e0de8732a697c9f77b90ddd463863bJordan Rose      // a basic integer type (e.g., char, int) and the underlying region
201740d490593e0de8732a697c9f77b90ddd463863bJordan Rose      // is a variable region then strip off the ElementRegion.
202740d490593e0de8732a697c9f77b90ddd463863bJordan Rose      // FIXME: We really need to think about this for the general case
203740d490593e0de8732a697c9f77b90ddd463863bJordan Rose      //   as sometimes we are reasoning about arrays and other times
204740d490593e0de8732a697c9f77b90ddd463863bJordan Rose      //   about (char*), etc., is just a form of passing raw bytes.
205740d490593e0de8732a697c9f77b90ddd463863bJordan Rose      //   e.g., void *p = alloca(); foo((char*)p);
206740d490593e0de8732a697c9f77b90ddd463863bJordan Rose      if (const ElementRegion *ER = dyn_cast<ElementRegion>(R)) {
207740d490593e0de8732a697c9f77b90ddd463863bJordan Rose        // Checking for 'integral type' is probably too promiscuous, but
208740d490593e0de8732a697c9f77b90ddd463863bJordan Rose        // we'll leave it in for now until we have a systematic way of
209740d490593e0de8732a697c9f77b90ddd463863bJordan Rose        // handling all of these cases.  Eventually we need to come up
210740d490593e0de8732a697c9f77b90ddd463863bJordan Rose        // with an interface to StoreManager so that this logic can be
211740d490593e0de8732a697c9f77b90ddd463863bJordan Rose        // appropriately delegated to the respective StoreManagers while
212740d490593e0de8732a697c9f77b90ddd463863bJordan Rose        // still allowing us to do checker-specific logic (e.g.,
213740d490593e0de8732a697c9f77b90ddd463863bJordan Rose        // invalidating reference counts), probably via callbacks.
214740d490593e0de8732a697c9f77b90ddd463863bJordan Rose        if (ER->getElementType()->isIntegralOrEnumerationType()) {
215740d490593e0de8732a697c9f77b90ddd463863bJordan Rose          const MemRegion *superReg = ER->getSuperRegion();
216740d490593e0de8732a697c9f77b90ddd463863bJordan Rose          if (isa<VarRegion>(superReg) || isa<FieldRegion>(superReg) ||
217740d490593e0de8732a697c9f77b90ddd463863bJordan Rose              isa<ObjCIvarRegion>(superReg))
218740d490593e0de8732a697c9f77b90ddd463863bJordan Rose            R = cast<TypedRegion>(superReg);
219740d490593e0de8732a697c9f77b90ddd463863bJordan Rose        }
220740d490593e0de8732a697c9f77b90ddd463863bJordan Rose        // FIXME: What about layers of ElementRegions?
221740d490593e0de8732a697c9f77b90ddd463863bJordan Rose      }
222740d490593e0de8732a697c9f77b90ddd463863bJordan Rose
223740d490593e0de8732a697c9f77b90ddd463863bJordan Rose      // Mark this region for invalidation.  We batch invalidate regions
224740d490593e0de8732a697c9f77b90ddd463863bJordan Rose      // below for efficiency.
225740d490593e0de8732a697c9f77b90ddd463863bJordan Rose      RegionsToInvalidate.push_back(R);
226740d490593e0de8732a697c9f77b90ddd463863bJordan Rose    }
227740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  }
228740d490593e0de8732a697c9f77b90ddd463863bJordan Rose
229740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  // Invalidate designated regions using the batch invalidation API.
230740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  // NOTE: Even if RegionsToInvalidate is empty, we may still invalidate
231740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  //  global variables.
232740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  return Result->invalidateRegions(RegionsToInvalidate, getOriginExpr(),
233740d490593e0de8732a697c9f77b90ddd463863bJordan Rose                                   BlockCount, LCtx, /*Symbols=*/0, this);
234740d490593e0de8732a697c9f77b90ddd463863bJordan Rose}
235740d490593e0de8732a697c9f77b90ddd463863bJordan Rose
236740d490593e0de8732a697c9f77b90ddd463863bJordan RoseCallEvent::param_iterator AnyFunctionCall::param_begin() const {
237740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  const FunctionDecl *D = getDecl();
238740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  if (!D)
239740d490593e0de8732a697c9f77b90ddd463863bJordan Rose    return 0;
240740d490593e0de8732a697c9f77b90ddd463863bJordan Rose
241740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  return D->param_begin();
242740d490593e0de8732a697c9f77b90ddd463863bJordan Rose}
243740d490593e0de8732a697c9f77b90ddd463863bJordan Rose
244740d490593e0de8732a697c9f77b90ddd463863bJordan RoseCallEvent::param_iterator AnyFunctionCall::param_end() const {
245740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  const FunctionDecl *D = getDecl();
246740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  if (!D)
247740d490593e0de8732a697c9f77b90ddd463863bJordan Rose    return 0;
248740d490593e0de8732a697c9f77b90ddd463863bJordan Rose
249740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  return D->param_end();
250740d490593e0de8732a697c9f77b90ddd463863bJordan Rose}
251740d490593e0de8732a697c9f77b90ddd463863bJordan Rose
252740d490593e0de8732a697c9f77b90ddd463863bJordan RoseQualType AnyFunctionCall::getDeclaredResultType() const {
253740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  const FunctionDecl *D = getDecl();
254740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  if (!D)
255740d490593e0de8732a697c9f77b90ddd463863bJordan Rose    return QualType();
256740d490593e0de8732a697c9f77b90ddd463863bJordan Rose
257740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  return D->getResultType();
258740d490593e0de8732a697c9f77b90ddd463863bJordan Rose}
259740d490593e0de8732a697c9f77b90ddd463863bJordan Rose
260740d490593e0de8732a697c9f77b90ddd463863bJordan Roseconst FunctionDecl *SimpleCall::getDecl() const {
261740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  const FunctionDecl *D = CE->getDirectCallee();
262740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  if (D)
263740d490593e0de8732a697c9f77b90ddd463863bJordan Rose    return D;
264740d490593e0de8732a697c9f77b90ddd463863bJordan Rose
265740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  return getSVal(CE->getCallee()).getAsFunctionDecl();
266740d490593e0de8732a697c9f77b90ddd463863bJordan Rose}
267740d490593e0de8732a697c9f77b90ddd463863bJordan Rose
268740d490593e0de8732a697c9f77b90ddd463863bJordan Rosevoid CXXMemberCall::addExtraInvalidatedRegions(RegionList &Regions) const {
269740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  const Expr *Base = getOriginExpr()->getImplicitObjectArgument();
270740d490593e0de8732a697c9f77b90ddd463863bJordan Rose
271740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  // FIXME: Will eventually need to cope with member pointers.  This is
272740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  // a limitation in getImplicitObjectArgument().
273740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  if (!Base)
274740d490593e0de8732a697c9f77b90ddd463863bJordan Rose    return;
275740d490593e0de8732a697c9f77b90ddd463863bJordan Rose
276740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  if (const MemRegion *R = getSVal(Base).getAsRegion())
277740d490593e0de8732a697c9f77b90ddd463863bJordan Rose    Regions.push_back(R);
278740d490593e0de8732a697c9f77b90ddd463863bJordan Rose}
279740d490593e0de8732a697c9f77b90ddd463863bJordan Rose
280740d490593e0de8732a697c9f77b90ddd463863bJordan Roseconst BlockDataRegion *BlockCall::getBlockRegion() const {
281740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  const Expr *Callee = getOriginExpr()->getCallee();
282740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  const MemRegion *DataReg = getSVal(Callee).getAsRegion();
283740d490593e0de8732a697c9f77b90ddd463863bJordan Rose
284740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  return cast<BlockDataRegion>(DataReg);
285740d490593e0de8732a697c9f77b90ddd463863bJordan Rose}
286740d490593e0de8732a697c9f77b90ddd463863bJordan Rose
287740d490593e0de8732a697c9f77b90ddd463863bJordan RoseCallEvent::param_iterator BlockCall::param_begin() const {
288740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  return getBlockRegion()->getDecl()->param_begin();
289740d490593e0de8732a697c9f77b90ddd463863bJordan Rose}
290740d490593e0de8732a697c9f77b90ddd463863bJordan Rose
291740d490593e0de8732a697c9f77b90ddd463863bJordan RoseCallEvent::param_iterator BlockCall::param_end() const {
292740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  return getBlockRegion()->getDecl()->param_end();
293740d490593e0de8732a697c9f77b90ddd463863bJordan Rose}
294740d490593e0de8732a697c9f77b90ddd463863bJordan Rose
295740d490593e0de8732a697c9f77b90ddd463863bJordan Rosevoid BlockCall::addExtraInvalidatedRegions(RegionList &Regions) const {
296740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  Regions.push_back(getBlockRegion());
297740d490593e0de8732a697c9f77b90ddd463863bJordan Rose}
298740d490593e0de8732a697c9f77b90ddd463863bJordan Rose
299740d490593e0de8732a697c9f77b90ddd463863bJordan RoseQualType BlockCall::getDeclaredResultType() const {
300740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  QualType BlockTy = getBlockRegion()->getCodeRegion()->getLocationType();
301740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  return cast<FunctionType>(BlockTy->getPointeeType())->getResultType();
302740d490593e0de8732a697c9f77b90ddd463863bJordan Rose}
303740d490593e0de8732a697c9f77b90ddd463863bJordan Rose
304740d490593e0de8732a697c9f77b90ddd463863bJordan Rosevoid CXXConstructorCall::addExtraInvalidatedRegions(RegionList &Regions) const {
305740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  if (Target)
306740d490593e0de8732a697c9f77b90ddd463863bJordan Rose    Regions.push_back(Target);
307740d490593e0de8732a697c9f77b90ddd463863bJordan Rose}
308740d490593e0de8732a697c9f77b90ddd463863bJordan Rose
309740d490593e0de8732a697c9f77b90ddd463863bJordan RoseCallEvent::param_iterator ObjCMessageInvocation::param_begin() const {
310740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  const ObjCMethodDecl *D = getDecl();
311740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  if (!D)
312740d490593e0de8732a697c9f77b90ddd463863bJordan Rose    return 0;
313740d490593e0de8732a697c9f77b90ddd463863bJordan Rose
314740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  return D->param_begin();
315740d490593e0de8732a697c9f77b90ddd463863bJordan Rose}
316740d490593e0de8732a697c9f77b90ddd463863bJordan Rose
317740d490593e0de8732a697c9f77b90ddd463863bJordan RoseCallEvent::param_iterator ObjCMessageInvocation::param_end() const {
318740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  const ObjCMethodDecl *D = getDecl();
319740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  if (!D)
320740d490593e0de8732a697c9f77b90ddd463863bJordan Rose    return 0;
321740d490593e0de8732a697c9f77b90ddd463863bJordan Rose
322740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  return D->param_end();
323740d490593e0de8732a697c9f77b90ddd463863bJordan Rose}
324740d490593e0de8732a697c9f77b90ddd463863bJordan Rose
325740d490593e0de8732a697c9f77b90ddd463863bJordan Rosevoid
326740d490593e0de8732a697c9f77b90ddd463863bJordan RoseObjCMessageInvocation::addExtraInvalidatedRegions(RegionList &Regions) const {
327740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  if (const MemRegion *R = getReceiverSVal().getAsRegion())
328740d490593e0de8732a697c9f77b90ddd463863bJordan Rose    Regions.push_back(R);
329740d490593e0de8732a697c9f77b90ddd463863bJordan Rose}
330740d490593e0de8732a697c9f77b90ddd463863bJordan Rose
331740d490593e0de8732a697c9f77b90ddd463863bJordan RoseQualType ObjCMessageInvocation::getDeclaredResultType() const {
332740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  const ObjCMethodDecl *D = getDecl();
333740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  if (!D)
334740d490593e0de8732a697c9f77b90ddd463863bJordan Rose    return QualType();
335740d490593e0de8732a697c9f77b90ddd463863bJordan Rose
336740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  return D->getResultType();
337740d490593e0de8732a697c9f77b90ddd463863bJordan Rose}
338740d490593e0de8732a697c9f77b90ddd463863bJordan Rose
339740d490593e0de8732a697c9f77b90ddd463863bJordan RoseSVal ObjCMessageInvocation::getReceiverSVal() const {
340740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  // FIXME: Is this the best way to handle class receivers?
341740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  if (!isInstanceMessage())
342740d490593e0de8732a697c9f77b90ddd463863bJordan Rose    return UnknownVal();
343740d490593e0de8732a697c9f77b90ddd463863bJordan Rose
344740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  const Expr *Base = Msg.getInstanceReceiver();
345740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  if (Base)
346740d490593e0de8732a697c9f77b90ddd463863bJordan Rose    return getSVal(Base);
347740d490593e0de8732a697c9f77b90ddd463863bJordan Rose
348740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  // An instance message with no expression means we are sending to super.
349740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  // In this case the object reference is the same as 'self'.
350740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  const ImplicitParamDecl *SelfDecl = LCtx->getSelfDecl();
351740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  assert(SelfDecl && "No message receiver Expr, but not in an ObjC method");
352740d490593e0de8732a697c9f77b90ddd463863bJordan Rose  return loc::MemRegionVal(State->getRegion(SelfDecl, LCtx));
353740d490593e0de8732a697c9f77b90ddd463863bJordan Rose}
354