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