CallEvent.cpp revision 7c99aa385178c630e29f671299cdd9c104f1c885
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 16f540c54701e3eeb34cb619a3a4eb18f1ac70ef2dJordan Rose#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" 1728038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose#include "clang/Analysis/ProgramPoint.h" 18b7a23e05d1d8f07f2a6edce5c88c728fe894c2c7Jordan Rose#include "clang/AST/ParentMap.h" 19740d490593e0de8732a697c9f77b90ddd463863bJordan Rose#include "llvm/ADT/SmallSet.h" 20de507eaf3cb54d3cb234dc14499c10ab3373d15fJordan Rose#include "llvm/ADT/StringExtras.h" 21740d490593e0de8732a697c9f77b90ddd463863bJordan Rose 22740d490593e0de8732a697c9f77b90ddd463863bJordan Roseusing namespace clang; 23740d490593e0de8732a697c9f77b90ddd463863bJordan Roseusing namespace ento; 24740d490593e0de8732a697c9f77b90ddd463863bJordan Rose 25740d490593e0de8732a697c9f77b90ddd463863bJordan RoseQualType CallEvent::getResultType() const { 26740d490593e0de8732a697c9f77b90ddd463863bJordan Rose QualType ResultTy = getDeclaredResultType(); 27740d490593e0de8732a697c9f77b90ddd463863bJordan Rose 28a6a1abac4701a3d08dc61070acd46b6a19be95eaJordan Rose if (ResultTy.isNull()) 29a6a1abac4701a3d08dc61070acd46b6a19be95eaJordan Rose ResultTy = getOriginExpr()->getType(); 30740d490593e0de8732a697c9f77b90ddd463863bJordan Rose 31740d490593e0de8732a697c9f77b90ddd463863bJordan Rose return ResultTy; 32740d490593e0de8732a697c9f77b90ddd463863bJordan Rose} 33740d490593e0de8732a697c9f77b90ddd463863bJordan Rose 34740d490593e0de8732a697c9f77b90ddd463863bJordan Rosestatic bool isCallbackArg(SVal V, QualType T) { 35740d490593e0de8732a697c9f77b90ddd463863bJordan Rose // If the parameter is 0, it's harmless. 36740d490593e0de8732a697c9f77b90ddd463863bJordan Rose if (V.isZeroConstant()) 37740d490593e0de8732a697c9f77b90ddd463863bJordan Rose return false; 38740d490593e0de8732a697c9f77b90ddd463863bJordan Rose 39740d490593e0de8732a697c9f77b90ddd463863bJordan Rose // If a parameter is a block or a callback, assume it can modify pointer. 40740d490593e0de8732a697c9f77b90ddd463863bJordan Rose if (T->isBlockPointerType() || 41740d490593e0de8732a697c9f77b90ddd463863bJordan Rose T->isFunctionPointerType() || 42740d490593e0de8732a697c9f77b90ddd463863bJordan Rose T->isObjCSelType()) 43740d490593e0de8732a697c9f77b90ddd463863bJordan Rose return true; 44740d490593e0de8732a697c9f77b90ddd463863bJordan Rose 45740d490593e0de8732a697c9f77b90ddd463863bJordan Rose // Check if a callback is passed inside a struct (for both, struct passed by 46740d490593e0de8732a697c9f77b90ddd463863bJordan Rose // reference and by value). Dig just one level into the struct for now. 47740d490593e0de8732a697c9f77b90ddd463863bJordan Rose 48740d490593e0de8732a697c9f77b90ddd463863bJordan Rose if (isa<PointerType>(T) || isa<ReferenceType>(T)) 49740d490593e0de8732a697c9f77b90ddd463863bJordan Rose T = T->getPointeeType(); 50740d490593e0de8732a697c9f77b90ddd463863bJordan Rose 51740d490593e0de8732a697c9f77b90ddd463863bJordan Rose if (const RecordType *RT = T->getAsStructureType()) { 52740d490593e0de8732a697c9f77b90ddd463863bJordan Rose const RecordDecl *RD = RT->getDecl(); 53740d490593e0de8732a697c9f77b90ddd463863bJordan Rose for (RecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end(); 54740d490593e0de8732a697c9f77b90ddd463863bJordan Rose I != E; ++I) { 55740d490593e0de8732a697c9f77b90ddd463863bJordan Rose QualType FieldT = I->getType(); 56740d490593e0de8732a697c9f77b90ddd463863bJordan Rose if (FieldT->isBlockPointerType() || FieldT->isFunctionPointerType()) 57740d490593e0de8732a697c9f77b90ddd463863bJordan Rose return true; 58740d490593e0de8732a697c9f77b90ddd463863bJordan Rose } 59740d490593e0de8732a697c9f77b90ddd463863bJordan Rose } 60740d490593e0de8732a697c9f77b90ddd463863bJordan Rose 61740d490593e0de8732a697c9f77b90ddd463863bJordan Rose return false; 62740d490593e0de8732a697c9f77b90ddd463863bJordan Rose} 63740d490593e0de8732a697c9f77b90ddd463863bJordan Rose 64740d490593e0de8732a697c9f77b90ddd463863bJordan Rosebool CallEvent::hasNonZeroCallbackArg() const { 65740d490593e0de8732a697c9f77b90ddd463863bJordan Rose unsigned NumOfArgs = getNumArgs(); 66740d490593e0de8732a697c9f77b90ddd463863bJordan Rose 67740d490593e0de8732a697c9f77b90ddd463863bJordan Rose // If calling using a function pointer, assume the function does not 68740d490593e0de8732a697c9f77b90ddd463863bJordan Rose // have a callback. TODO: We could check the types of the arguments here. 69740d490593e0de8732a697c9f77b90ddd463863bJordan Rose if (!getDecl()) 70740d490593e0de8732a697c9f77b90ddd463863bJordan Rose return false; 71740d490593e0de8732a697c9f77b90ddd463863bJordan Rose 72740d490593e0de8732a697c9f77b90ddd463863bJordan Rose unsigned Idx = 0; 73740d490593e0de8732a697c9f77b90ddd463863bJordan Rose for (CallEvent::param_type_iterator I = param_type_begin(), 74740d490593e0de8732a697c9f77b90ddd463863bJordan Rose E = param_type_end(); 75740d490593e0de8732a697c9f77b90ddd463863bJordan Rose I != E && Idx < NumOfArgs; ++I, ++Idx) { 76740d490593e0de8732a697c9f77b90ddd463863bJordan Rose if (NumOfArgs <= Idx) 77740d490593e0de8732a697c9f77b90ddd463863bJordan Rose break; 78740d490593e0de8732a697c9f77b90ddd463863bJordan Rose 79740d490593e0de8732a697c9f77b90ddd463863bJordan Rose if (isCallbackArg(getArgSVal(Idx), *I)) 80740d490593e0de8732a697c9f77b90ddd463863bJordan Rose return true; 81740d490593e0de8732a697c9f77b90ddd463863bJordan Rose } 82740d490593e0de8732a697c9f77b90ddd463863bJordan Rose 83740d490593e0de8732a697c9f77b90ddd463863bJordan Rose return false; 84740d490593e0de8732a697c9f77b90ddd463863bJordan Rose} 85740d490593e0de8732a697c9f77b90ddd463863bJordan Rose 86740d490593e0de8732a697c9f77b90ddd463863bJordan Rose/// \brief Returns true if a type is a pointer-to-const or reference-to-const 87740d490593e0de8732a697c9f77b90ddd463863bJordan Rose/// with no further indirection. 88740d490593e0de8732a697c9f77b90ddd463863bJordan Rosestatic bool isPointerToConst(QualType Ty) { 89740d490593e0de8732a697c9f77b90ddd463863bJordan Rose QualType PointeeTy = Ty->getPointeeType(); 90740d490593e0de8732a697c9f77b90ddd463863bJordan Rose if (PointeeTy == QualType()) 91740d490593e0de8732a697c9f77b90ddd463863bJordan Rose return false; 92740d490593e0de8732a697c9f77b90ddd463863bJordan Rose if (!PointeeTy.isConstQualified()) 93740d490593e0de8732a697c9f77b90ddd463863bJordan Rose return false; 94740d490593e0de8732a697c9f77b90ddd463863bJordan Rose if (PointeeTy->isAnyPointerType()) 95740d490593e0de8732a697c9f77b90ddd463863bJordan Rose return false; 96740d490593e0de8732a697c9f77b90ddd463863bJordan Rose return true; 97740d490593e0de8732a697c9f77b90ddd463863bJordan Rose} 98740d490593e0de8732a697c9f77b90ddd463863bJordan Rose 99740d490593e0de8732a697c9f77b90ddd463863bJordan Rose// Try to retrieve the function declaration and find the function parameter 100740d490593e0de8732a697c9f77b90ddd463863bJordan Rose// types which are pointers/references to a non-pointer const. 10185d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose// We will not invalidate the corresponding argument regions. 102740d490593e0de8732a697c9f77b90ddd463863bJordan Rosestatic void findPtrToConstParams(llvm::SmallSet<unsigned, 1> &PreserveArgs, 103740d490593e0de8732a697c9f77b90ddd463863bJordan Rose const CallEvent &Call) { 104740d490593e0de8732a697c9f77b90ddd463863bJordan Rose unsigned Idx = 0; 105740d490593e0de8732a697c9f77b90ddd463863bJordan Rose for (CallEvent::param_type_iterator I = Call.param_type_begin(), 10685d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose E = Call.param_type_end(); 107740d490593e0de8732a697c9f77b90ddd463863bJordan Rose I != E; ++I, ++Idx) { 108740d490593e0de8732a697c9f77b90ddd463863bJordan Rose if (isPointerToConst(*I)) 109740d490593e0de8732a697c9f77b90ddd463863bJordan Rose PreserveArgs.insert(Idx); 110740d490593e0de8732a697c9f77b90ddd463863bJordan Rose } 111740d490593e0de8732a697c9f77b90ddd463863bJordan Rose} 112740d490593e0de8732a697c9f77b90ddd463863bJordan Rose 113740d490593e0de8732a697c9f77b90ddd463863bJordan RoseProgramStateRef CallEvent::invalidateRegions(unsigned BlockCount, 114740d490593e0de8732a697c9f77b90ddd463863bJordan Rose ProgramStateRef Orig) const { 115b7a23e05d1d8f07f2a6edce5c88c728fe894c2c7Jordan Rose ProgramStateRef Result = (Orig ? Orig : getState()); 116740d490593e0de8732a697c9f77b90ddd463863bJordan Rose 117740d490593e0de8732a697c9f77b90ddd463863bJordan Rose SmallVector<const MemRegion *, 8> RegionsToInvalidate; 1184b3918e9534e46f9ac067c6e0018f94613292efaJordan Rose getExtraInvalidatedRegions(RegionsToInvalidate); 119740d490593e0de8732a697c9f77b90ddd463863bJordan Rose 120740d490593e0de8732a697c9f77b90ddd463863bJordan Rose // Indexes of arguments whose values will be preserved by the call. 121740d490593e0de8732a697c9f77b90ddd463863bJordan Rose llvm::SmallSet<unsigned, 1> PreserveArgs; 12285d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose if (!argumentsMayEscape()) 12385d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose findPtrToConstParams(PreserveArgs, *this); 124740d490593e0de8732a697c9f77b90ddd463863bJordan Rose 125740d490593e0de8732a697c9f77b90ddd463863bJordan Rose for (unsigned Idx = 0, Count = getNumArgs(); Idx != Count; ++Idx) { 126740d490593e0de8732a697c9f77b90ddd463863bJordan Rose if (PreserveArgs.count(Idx)) 127740d490593e0de8732a697c9f77b90ddd463863bJordan Rose continue; 128740d490593e0de8732a697c9f77b90ddd463863bJordan Rose 129740d490593e0de8732a697c9f77b90ddd463863bJordan Rose SVal V = getArgSVal(Idx); 130740d490593e0de8732a697c9f77b90ddd463863bJordan Rose 131740d490593e0de8732a697c9f77b90ddd463863bJordan Rose // If we are passing a location wrapped as an integer, unwrap it and 132740d490593e0de8732a697c9f77b90ddd463863bJordan Rose // invalidate the values referred by the location. 133740d490593e0de8732a697c9f77b90ddd463863bJordan Rose if (nonloc::LocAsInteger *Wrapped = dyn_cast<nonloc::LocAsInteger>(&V)) 134740d490593e0de8732a697c9f77b90ddd463863bJordan Rose V = Wrapped->getLoc(); 135740d490593e0de8732a697c9f77b90ddd463863bJordan Rose else if (!isa<Loc>(V)) 136740d490593e0de8732a697c9f77b90ddd463863bJordan Rose continue; 137740d490593e0de8732a697c9f77b90ddd463863bJordan Rose 138740d490593e0de8732a697c9f77b90ddd463863bJordan Rose if (const MemRegion *R = V.getAsRegion()) { 139740d490593e0de8732a697c9f77b90ddd463863bJordan Rose // Invalidate the value of the variable passed by reference. 140740d490593e0de8732a697c9f77b90ddd463863bJordan Rose 141740d490593e0de8732a697c9f77b90ddd463863bJordan Rose // Are we dealing with an ElementRegion? If the element type is 142740d490593e0de8732a697c9f77b90ddd463863bJordan Rose // a basic integer type (e.g., char, int) and the underlying region 143740d490593e0de8732a697c9f77b90ddd463863bJordan Rose // is a variable region then strip off the ElementRegion. 144740d490593e0de8732a697c9f77b90ddd463863bJordan Rose // FIXME: We really need to think about this for the general case 145740d490593e0de8732a697c9f77b90ddd463863bJordan Rose // as sometimes we are reasoning about arrays and other times 146740d490593e0de8732a697c9f77b90ddd463863bJordan Rose // about (char*), etc., is just a form of passing raw bytes. 147740d490593e0de8732a697c9f77b90ddd463863bJordan Rose // e.g., void *p = alloca(); foo((char*)p); 148740d490593e0de8732a697c9f77b90ddd463863bJordan Rose if (const ElementRegion *ER = dyn_cast<ElementRegion>(R)) { 149740d490593e0de8732a697c9f77b90ddd463863bJordan Rose // Checking for 'integral type' is probably too promiscuous, but 150740d490593e0de8732a697c9f77b90ddd463863bJordan Rose // we'll leave it in for now until we have a systematic way of 151740d490593e0de8732a697c9f77b90ddd463863bJordan Rose // handling all of these cases. Eventually we need to come up 152740d490593e0de8732a697c9f77b90ddd463863bJordan Rose // with an interface to StoreManager so that this logic can be 153740d490593e0de8732a697c9f77b90ddd463863bJordan Rose // appropriately delegated to the respective StoreManagers while 154740d490593e0de8732a697c9f77b90ddd463863bJordan Rose // still allowing us to do checker-specific logic (e.g., 155740d490593e0de8732a697c9f77b90ddd463863bJordan Rose // invalidating reference counts), probably via callbacks. 156740d490593e0de8732a697c9f77b90ddd463863bJordan Rose if (ER->getElementType()->isIntegralOrEnumerationType()) { 157740d490593e0de8732a697c9f77b90ddd463863bJordan Rose const MemRegion *superReg = ER->getSuperRegion(); 158740d490593e0de8732a697c9f77b90ddd463863bJordan Rose if (isa<VarRegion>(superReg) || isa<FieldRegion>(superReg) || 159740d490593e0de8732a697c9f77b90ddd463863bJordan Rose isa<ObjCIvarRegion>(superReg)) 160740d490593e0de8732a697c9f77b90ddd463863bJordan Rose R = cast<TypedRegion>(superReg); 161740d490593e0de8732a697c9f77b90ddd463863bJordan Rose } 162740d490593e0de8732a697c9f77b90ddd463863bJordan Rose // FIXME: What about layers of ElementRegions? 163740d490593e0de8732a697c9f77b90ddd463863bJordan Rose } 164740d490593e0de8732a697c9f77b90ddd463863bJordan Rose 165740d490593e0de8732a697c9f77b90ddd463863bJordan Rose // Mark this region for invalidation. We batch invalidate regions 166740d490593e0de8732a697c9f77b90ddd463863bJordan Rose // below for efficiency. 167740d490593e0de8732a697c9f77b90ddd463863bJordan Rose RegionsToInvalidate.push_back(R); 168740d490593e0de8732a697c9f77b90ddd463863bJordan Rose } 169740d490593e0de8732a697c9f77b90ddd463863bJordan Rose } 170740d490593e0de8732a697c9f77b90ddd463863bJordan Rose 171740d490593e0de8732a697c9f77b90ddd463863bJordan Rose // Invalidate designated regions using the batch invalidation API. 172740d490593e0de8732a697c9f77b90ddd463863bJordan Rose // NOTE: Even if RegionsToInvalidate is empty, we may still invalidate 173740d490593e0de8732a697c9f77b90ddd463863bJordan Rose // global variables. 174740d490593e0de8732a697c9f77b90ddd463863bJordan Rose return Result->invalidateRegions(RegionsToInvalidate, getOriginExpr(), 175b7a23e05d1d8f07f2a6edce5c88c728fe894c2c7Jordan Rose BlockCount, getLocationContext(), 176b7a23e05d1d8f07f2a6edce5c88c728fe894c2c7Jordan Rose /*Symbols=*/0, this); 177740d490593e0de8732a697c9f77b90ddd463863bJordan Rose} 178740d490593e0de8732a697c9f77b90ddd463863bJordan Rose 17928038f33aa2db4833881fea757a1f0daf85ac02bJordan RoseProgramPoint CallEvent::getProgramPoint(bool IsPreVisit, 18028038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose const ProgramPointTag *Tag) const { 18128038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose if (const Expr *E = getOriginExpr()) { 18228038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose if (IsPreVisit) 183b7a23e05d1d8f07f2a6edce5c88c728fe894c2c7Jordan Rose return PreStmt(E, getLocationContext(), Tag); 184b7a23e05d1d8f07f2a6edce5c88c728fe894c2c7Jordan Rose return PostStmt(E, getLocationContext(), Tag); 18528038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose } 18628038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose 18728038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose const Decl *D = getDecl(); 18828038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose assert(D && "Cannot get a program point without a statement or decl"); 18928038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose 19028038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose SourceLocation Loc = getSourceRange().getBegin(); 19128038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose if (IsPreVisit) 192b7a23e05d1d8f07f2a6edce5c88c728fe894c2c7Jordan Rose return PreImplicitCall(D, Loc, getLocationContext(), Tag); 193b7a23e05d1d8f07f2a6edce5c88c728fe894c2c7Jordan Rose return PostImplicitCall(D, Loc, getLocationContext(), Tag); 19428038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose} 19528038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose 1967c99aa385178c630e29f671299cdd9c104f1c885Jordan RoseSVal CallEvent::getArgSVal(unsigned Index) const { 1977c99aa385178c630e29f671299cdd9c104f1c885Jordan Rose const Expr *ArgE = getArgExpr(Index); 1987c99aa385178c630e29f671299cdd9c104f1c885Jordan Rose if (!ArgE) 1997c99aa385178c630e29f671299cdd9c104f1c885Jordan Rose return UnknownVal(); 2007c99aa385178c630e29f671299cdd9c104f1c885Jordan Rose return getSVal(ArgE); 2017c99aa385178c630e29f671299cdd9c104f1c885Jordan Rose} 2027c99aa385178c630e29f671299cdd9c104f1c885Jordan Rose 2037c99aa385178c630e29f671299cdd9c104f1c885Jordan RoseSourceRange CallEvent::getArgSourceRange(unsigned Index) const { 2047c99aa385178c630e29f671299cdd9c104f1c885Jordan Rose const Expr *ArgE = getArgExpr(Index); 2057c99aa385178c630e29f671299cdd9c104f1c885Jordan Rose if (!ArgE) 2067c99aa385178c630e29f671299cdd9c104f1c885Jordan Rose return SourceRange(); 2077c99aa385178c630e29f671299cdd9c104f1c885Jordan Rose return ArgE->getSourceRange(); 2087c99aa385178c630e29f671299cdd9c104f1c885Jordan Rose} 2097c99aa385178c630e29f671299cdd9c104f1c885Jordan Rose 2107c99aa385178c630e29f671299cdd9c104f1c885Jordan Rosevoid CallEvent::dump(raw_ostream &Out) const { 2117c99aa385178c630e29f671299cdd9c104f1c885Jordan Rose ASTContext &Ctx = getState()->getStateManager().getContext(); 2127c99aa385178c630e29f671299cdd9c104f1c885Jordan Rose if (const Expr *E = getOriginExpr()) { 2137c99aa385178c630e29f671299cdd9c104f1c885Jordan Rose E->printPretty(Out, Ctx, 0, Ctx.getPrintingPolicy()); 2147c99aa385178c630e29f671299cdd9c104f1c885Jordan Rose Out << "\n"; 2157c99aa385178c630e29f671299cdd9c104f1c885Jordan Rose return; 2167c99aa385178c630e29f671299cdd9c104f1c885Jordan Rose } 2177c99aa385178c630e29f671299cdd9c104f1c885Jordan Rose 2187c99aa385178c630e29f671299cdd9c104f1c885Jordan Rose if (const Decl *D = getDecl()) { 2197c99aa385178c630e29f671299cdd9c104f1c885Jordan Rose Out << "Call to "; 2207c99aa385178c630e29f671299cdd9c104f1c885Jordan Rose D->print(Out, Ctx.getPrintingPolicy()); 2217c99aa385178c630e29f671299cdd9c104f1c885Jordan Rose return; 2227c99aa385178c630e29f671299cdd9c104f1c885Jordan Rose } 2237c99aa385178c630e29f671299cdd9c104f1c885Jordan Rose 2247c99aa385178c630e29f671299cdd9c104f1c885Jordan Rose // FIXME: a string representation of the kind would be nice. 2257c99aa385178c630e29f671299cdd9c104f1c885Jordan Rose Out << "Unknown call (type " << getKind() << ")"; 2267c99aa385178c630e29f671299cdd9c104f1c885Jordan Rose} 2277c99aa385178c630e29f671299cdd9c104f1c885Jordan Rose 22828038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose 22985d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rosebool CallEvent::mayBeInlined(const Stmt *S) { 2307c99aa385178c630e29f671299cdd9c104f1c885Jordan Rose // FIXME: Kill this. 2317c99aa385178c630e29f671299cdd9c104f1c885Jordan Rose return isa<CallExpr>(S) || isa<ObjCMessageExpr>(S) 2327c99aa385178c630e29f671299cdd9c104f1c885Jordan Rose || isa<CXXConstructExpr>(S); 23385d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose} 23485d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose 23585d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose 236e54cfc7b9990acffd0a8a4ba381717b4bb9f3011Jordan RoseCallEvent::param_iterator 237e54cfc7b9990acffd0a8a4ba381717b4bb9f3011Jordan RoseAnyFunctionCall::param_begin(bool UseDefinitionParams) const { 2389dc5167e4017ef4c8b327abb6f72225eec2e0f19Anna Zaks const Decl *D = UseDefinitionParams ? getRuntimeDefinition() 239c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose : getDecl(); 240740d490593e0de8732a697c9f77b90ddd463863bJordan Rose if (!D) 241740d490593e0de8732a697c9f77b90ddd463863bJordan Rose return 0; 242740d490593e0de8732a697c9f77b90ddd463863bJordan Rose 243e54cfc7b9990acffd0a8a4ba381717b4bb9f3011Jordan Rose return cast<FunctionDecl>(D)->param_begin(); 244740d490593e0de8732a697c9f77b90ddd463863bJordan Rose} 245740d490593e0de8732a697c9f77b90ddd463863bJordan Rose 246e54cfc7b9990acffd0a8a4ba381717b4bb9f3011Jordan RoseCallEvent::param_iterator 247e54cfc7b9990acffd0a8a4ba381717b4bb9f3011Jordan RoseAnyFunctionCall::param_end(bool UseDefinitionParams) const { 2489dc5167e4017ef4c8b327abb6f72225eec2e0f19Anna Zaks const Decl *D = UseDefinitionParams ? getRuntimeDefinition() 249c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose : getDecl(); 250740d490593e0de8732a697c9f77b90ddd463863bJordan Rose if (!D) 251740d490593e0de8732a697c9f77b90ddd463863bJordan Rose return 0; 252740d490593e0de8732a697c9f77b90ddd463863bJordan Rose 253e54cfc7b9990acffd0a8a4ba381717b4bb9f3011Jordan Rose return cast<FunctionDecl>(D)->param_end(); 254740d490593e0de8732a697c9f77b90ddd463863bJordan Rose} 255740d490593e0de8732a697c9f77b90ddd463863bJordan Rose 256740d490593e0de8732a697c9f77b90ddd463863bJordan RoseQualType AnyFunctionCall::getDeclaredResultType() const { 257740d490593e0de8732a697c9f77b90ddd463863bJordan Rose const FunctionDecl *D = getDecl(); 258740d490593e0de8732a697c9f77b90ddd463863bJordan Rose if (!D) 259740d490593e0de8732a697c9f77b90ddd463863bJordan Rose return QualType(); 260740d490593e0de8732a697c9f77b90ddd463863bJordan Rose 261740d490593e0de8732a697c9f77b90ddd463863bJordan Rose return D->getResultType(); 262740d490593e0de8732a697c9f77b90ddd463863bJordan Rose} 263740d490593e0de8732a697c9f77b90ddd463863bJordan Rose 26485d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rosebool AnyFunctionCall::argumentsMayEscape() const { 265b7a23e05d1d8f07f2a6edce5c88c728fe894c2c7Jordan Rose if (hasNonZeroCallbackArg()) 26685d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose return true; 26785d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose 26885d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose const FunctionDecl *D = getDecl(); 26985d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose if (!D) 27085d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose return true; 27185d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose 27285d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose const IdentifierInfo *II = D->getIdentifier(); 27385d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose if (!II) 27485d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose return true; 27585d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose 27685d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose // This set of "escaping" APIs is 27785d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose 27885d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose // - 'int pthread_setspecific(ptheread_key k, const void *)' stores a 27985d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose // value into thread local storage. The value can later be retrieved with 28085d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose // 'void *ptheread_getspecific(pthread_key)'. So even thought the 28185d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose // parameter is 'const void *', the region escapes through the call. 28285d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose if (II->isStr("pthread_setspecific")) 28385d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose return true; 28485d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose 28585d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose // - xpc_connection_set_context stores a value which can be retrieved later 28685d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose // with xpc_connection_get_context. 28785d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose if (II->isStr("xpc_connection_set_context")) 28885d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose return true; 28985d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose 29085d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose // - funopen - sets a buffer for future IO calls. 29185d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose if (II->isStr("funopen")) 29285d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose return true; 29385d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose 29485d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose StringRef FName = II->getName(); 29585d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose 29685d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose // - CoreFoundation functions that end with "NoCopy" can free a passed-in 29785d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose // buffer even if it is const. 29885d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose if (FName.endswith("NoCopy")) 29985d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose return true; 30085d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose 30185d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose // - NSXXInsertXX, for example NSMapInsertIfAbsent, since they can 30285d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose // be deallocated by NSMapRemove. 30385d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose if (FName.startswith("NS") && (FName.find("Insert") != StringRef::npos)) 30485d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose return true; 30585d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose 30685d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose // - Many CF containers allow objects to escape through custom 30785d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose // allocators/deallocators upon container construction. (PR12101) 30885d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose if (FName.startswith("CF") || FName.startswith("CG")) { 30985d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose return StrInStrNoCase(FName, "InsertValue") != StringRef::npos || 31085d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose StrInStrNoCase(FName, "AddValue") != StringRef::npos || 31185d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose StrInStrNoCase(FName, "SetValue") != StringRef::npos || 31285d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose StrInStrNoCase(FName, "WithData") != StringRef::npos || 31385d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose StrInStrNoCase(FName, "AppendValue") != StringRef::npos || 31485d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose StrInStrNoCase(FName, "SetAttribute") != StringRef::npos; 31585d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose } 31685d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose 31785d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose return false; 31885d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose} 31985d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose 32085d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose 321740d490593e0de8732a697c9f77b90ddd463863bJordan Roseconst FunctionDecl *SimpleCall::getDecl() const { 322b7a23e05d1d8f07f2a6edce5c88c728fe894c2c7Jordan Rose const FunctionDecl *D = getOriginExpr()->getDirectCallee(); 323740d490593e0de8732a697c9f77b90ddd463863bJordan Rose if (D) 324740d490593e0de8732a697c9f77b90ddd463863bJordan Rose return D; 325740d490593e0de8732a697c9f77b90ddd463863bJordan Rose 326b7a23e05d1d8f07f2a6edce5c88c728fe894c2c7Jordan Rose return getSVal(getOriginExpr()->getCallee()).getAsFunctionDecl(); 327740d490593e0de8732a697c9f77b90ddd463863bJordan Rose} 328740d490593e0de8732a697c9f77b90ddd463863bJordan Rose 32985d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose 3304b3918e9534e46f9ac067c6e0018f94613292efaJordan Rosevoid CXXInstanceCall::getExtraInvalidatedRegions(RegionList &Regions) const { 331c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose if (const MemRegion *R = getCXXThisVal().getAsRegion()) 332c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose Regions.push_back(R); 333c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose} 334c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose 335c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rosestatic const CXXMethodDecl *devirtualize(const CXXMethodDecl *MD, SVal ThisVal){ 336c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose const MemRegion *R = ThisVal.getAsRegion(); 337c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose if (!R) 338c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose return 0; 339c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose 340c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose const TypedValueRegion *TR = dyn_cast<TypedValueRegion>(R->StripCasts()); 341c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose if (!TR) 342c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose return 0; 343c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose 344c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose const CXXRecordDecl *RD = TR->getValueType()->getAsCXXRecordDecl(); 345c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose if (!RD) 346c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose return 0; 347c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose 348c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose const CXXMethodDecl *Result = MD->getCorrespondingMethodInClass(RD); 349c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose const FunctionDecl *Definition; 350c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose if (!Result->hasBody(Definition)) 351c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose return 0; 352c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose 353c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose return cast<CXXMethodDecl>(Definition); 354c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose} 355c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose 356c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose 3579dc5167e4017ef4c8b327abb6f72225eec2e0f19Anna Zaksconst Decl *CXXInstanceCall::getRuntimeDefinition() const { 3589dc5167e4017ef4c8b327abb6f72225eec2e0f19Anna Zaks const Decl *D = SimpleCall::getRuntimeDefinition(); 359c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose if (!D) 360c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose return 0; 361c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose 362c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose const CXXMethodDecl *MD = cast<CXXMethodDecl>(D); 363c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose if (!MD->isVirtual()) 364c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose return MD; 365c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose 366c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose // If the method is virtual, see if we can find the actual implementation 367c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose // based on context-sensitivity. 368c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose if (const CXXMethodDecl *Devirtualized = devirtualize(MD, getCXXThisVal())) 369c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose return Devirtualized; 370c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose 3719dc5167e4017ef4c8b327abb6f72225eec2e0f19Anna Zaks return 0; 372c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose} 373c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose 374c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose 375e54cfc7b9990acffd0a8a4ba381717b4bb9f3011Jordan RoseSVal CXXMemberCall::getCXXThisVal() const { 376740d490593e0de8732a697c9f77b90ddd463863bJordan Rose const Expr *Base = getOriginExpr()->getImplicitObjectArgument(); 377740d490593e0de8732a697c9f77b90ddd463863bJordan Rose 378740d490593e0de8732a697c9f77b90ddd463863bJordan Rose // FIXME: Will eventually need to cope with member pointers. This is 379740d490593e0de8732a697c9f77b90ddd463863bJordan Rose // a limitation in getImplicitObjectArgument(). 380740d490593e0de8732a697c9f77b90ddd463863bJordan Rose if (!Base) 381e54cfc7b9990acffd0a8a4ba381717b4bb9f3011Jordan Rose return UnknownVal(); 382e54cfc7b9990acffd0a8a4ba381717b4bb9f3011Jordan Rose 383e54cfc7b9990acffd0a8a4ba381717b4bb9f3011Jordan Rose return getSVal(Base); 384e54cfc7b9990acffd0a8a4ba381717b4bb9f3011Jordan Rose} 385e54cfc7b9990acffd0a8a4ba381717b4bb9f3011Jordan Rose 38685d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose 387e54cfc7b9990acffd0a8a4ba381717b4bb9f3011Jordan RoseSVal CXXMemberOperatorCall::getCXXThisVal() const { 388e54cfc7b9990acffd0a8a4ba381717b4bb9f3011Jordan Rose const Expr *Base = getOriginExpr()->getArg(0); 389e54cfc7b9990acffd0a8a4ba381717b4bb9f3011Jordan Rose return getSVal(Base); 390e54cfc7b9990acffd0a8a4ba381717b4bb9f3011Jordan Rose} 391e54cfc7b9990acffd0a8a4ba381717b4bb9f3011Jordan Rose 392fdaa33818cf9bad8d092136e73bd2e489cb821baJordan Rose 393740d490593e0de8732a697c9f77b90ddd463863bJordan Roseconst BlockDataRegion *BlockCall::getBlockRegion() const { 394740d490593e0de8732a697c9f77b90ddd463863bJordan Rose const Expr *Callee = getOriginExpr()->getCallee(); 395740d490593e0de8732a697c9f77b90ddd463863bJordan Rose const MemRegion *DataReg = getSVal(Callee).getAsRegion(); 396740d490593e0de8732a697c9f77b90ddd463863bJordan Rose 39769f87c956b3ac2b80124fd9604af012e1061473aJordan Rose return dyn_cast_or_null<BlockDataRegion>(DataReg); 398740d490593e0de8732a697c9f77b90ddd463863bJordan Rose} 399740d490593e0de8732a697c9f77b90ddd463863bJordan Rose 400e54cfc7b9990acffd0a8a4ba381717b4bb9f3011Jordan RoseCallEvent::param_iterator 401e54cfc7b9990acffd0a8a4ba381717b4bb9f3011Jordan RoseBlockCall::param_begin(bool UseDefinitionParams) const { 402e54cfc7b9990acffd0a8a4ba381717b4bb9f3011Jordan Rose // Blocks don't have distinct declarations and definitions. 403e54cfc7b9990acffd0a8a4ba381717b4bb9f3011Jordan Rose (void)UseDefinitionParams; 404e54cfc7b9990acffd0a8a4ba381717b4bb9f3011Jordan Rose 40569f87c956b3ac2b80124fd9604af012e1061473aJordan Rose const BlockDecl *D = getBlockDecl(); 40669f87c956b3ac2b80124fd9604af012e1061473aJordan Rose if (!D) 40769f87c956b3ac2b80124fd9604af012e1061473aJordan Rose return 0; 40869f87c956b3ac2b80124fd9604af012e1061473aJordan Rose return D->param_begin(); 409740d490593e0de8732a697c9f77b90ddd463863bJordan Rose} 410740d490593e0de8732a697c9f77b90ddd463863bJordan Rose 411e54cfc7b9990acffd0a8a4ba381717b4bb9f3011Jordan RoseCallEvent::param_iterator 412e54cfc7b9990acffd0a8a4ba381717b4bb9f3011Jordan RoseBlockCall::param_end(bool UseDefinitionParams) const { 413e54cfc7b9990acffd0a8a4ba381717b4bb9f3011Jordan Rose // Blocks don't have distinct declarations and definitions. 414e54cfc7b9990acffd0a8a4ba381717b4bb9f3011Jordan Rose (void)UseDefinitionParams; 415e54cfc7b9990acffd0a8a4ba381717b4bb9f3011Jordan Rose 41669f87c956b3ac2b80124fd9604af012e1061473aJordan Rose const BlockDecl *D = getBlockDecl(); 41769f87c956b3ac2b80124fd9604af012e1061473aJordan Rose if (!D) 41869f87c956b3ac2b80124fd9604af012e1061473aJordan Rose return 0; 41969f87c956b3ac2b80124fd9604af012e1061473aJordan Rose return D->param_end(); 420740d490593e0de8732a697c9f77b90ddd463863bJordan Rose} 421740d490593e0de8732a697c9f77b90ddd463863bJordan Rose 4224b3918e9534e46f9ac067c6e0018f94613292efaJordan Rosevoid BlockCall::getExtraInvalidatedRegions(RegionList &Regions) const { 42369f87c956b3ac2b80124fd9604af012e1061473aJordan Rose // FIXME: This also needs to invalidate captured globals. 42469f87c956b3ac2b80124fd9604af012e1061473aJordan Rose if (const MemRegion *R = getBlockRegion()) 42569f87c956b3ac2b80124fd9604af012e1061473aJordan Rose Regions.push_back(R); 426740d490593e0de8732a697c9f77b90ddd463863bJordan Rose} 427740d490593e0de8732a697c9f77b90ddd463863bJordan Rose 428740d490593e0de8732a697c9f77b90ddd463863bJordan RoseQualType BlockCall::getDeclaredResultType() const { 42969f87c956b3ac2b80124fd9604af012e1061473aJordan Rose const BlockDataRegion *BR = getBlockRegion(); 43069f87c956b3ac2b80124fd9604af012e1061473aJordan Rose if (!BR) 43169f87c956b3ac2b80124fd9604af012e1061473aJordan Rose return QualType(); 43269f87c956b3ac2b80124fd9604af012e1061473aJordan Rose QualType BlockTy = BR->getCodeRegion()->getLocationType(); 433740d490593e0de8732a697c9f77b90ddd463863bJordan Rose return cast<FunctionType>(BlockTy->getPointeeType())->getResultType(); 434740d490593e0de8732a697c9f77b90ddd463863bJordan Rose} 435740d490593e0de8732a697c9f77b90ddd463863bJordan Rose 43685d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose 437e54cfc7b9990acffd0a8a4ba381717b4bb9f3011Jordan RoseSVal CXXConstructorCall::getCXXThisVal() const { 438b7a23e05d1d8f07f2a6edce5c88c728fe894c2c7Jordan Rose if (Data) 439b7a23e05d1d8f07f2a6edce5c88c728fe894c2c7Jordan Rose return loc::MemRegionVal(static_cast<const MemRegion *>(Data)); 440e54cfc7b9990acffd0a8a4ba381717b4bb9f3011Jordan Rose return UnknownVal(); 441e54cfc7b9990acffd0a8a4ba381717b4bb9f3011Jordan Rose} 442e54cfc7b9990acffd0a8a4ba381717b4bb9f3011Jordan Rose 4434b3918e9534e46f9ac067c6e0018f94613292efaJordan Rosevoid CXXConstructorCall::getExtraInvalidatedRegions(RegionList &Regions) const { 444b7a23e05d1d8f07f2a6edce5c88c728fe894c2c7Jordan Rose if (Data) 445b7a23e05d1d8f07f2a6edce5c88c728fe894c2c7Jordan Rose Regions.push_back(static_cast<const MemRegion *>(Data)); 446740d490593e0de8732a697c9f77b90ddd463863bJordan Rose} 447740d490593e0de8732a697c9f77b90ddd463863bJordan Rose 44885d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose 449e54cfc7b9990acffd0a8a4ba381717b4bb9f3011Jordan RoseSVal CXXDestructorCall::getCXXThisVal() const { 450b7a23e05d1d8f07f2a6edce5c88c728fe894c2c7Jordan Rose if (Data) 451b7a23e05d1d8f07f2a6edce5c88c728fe894c2c7Jordan Rose return loc::MemRegionVal(static_cast<const MemRegion *>(Data)); 452e54cfc7b9990acffd0a8a4ba381717b4bb9f3011Jordan Rose return UnknownVal(); 453e54cfc7b9990acffd0a8a4ba381717b4bb9f3011Jordan Rose} 454e54cfc7b9990acffd0a8a4ba381717b4bb9f3011Jordan Rose 4554b3918e9534e46f9ac067c6e0018f94613292efaJordan Rosevoid CXXDestructorCall::getExtraInvalidatedRegions(RegionList &Regions) const { 456b7a23e05d1d8f07f2a6edce5c88c728fe894c2c7Jordan Rose if (Data) 457b7a23e05d1d8f07f2a6edce5c88c728fe894c2c7Jordan Rose Regions.push_back(static_cast<const MemRegion *>(Data)); 4588d276d38c258dfc572586daf6c0e8f8fce249c0eJordan Rose} 4598d276d38c258dfc572586daf6c0e8f8fce249c0eJordan Rose 4609dc5167e4017ef4c8b327abb6f72225eec2e0f19Anna Zaksconst Decl *CXXDestructorCall::getRuntimeDefinition() const { 4619dc5167e4017ef4c8b327abb6f72225eec2e0f19Anna Zaks const Decl *D = AnyFunctionCall::getRuntimeDefinition(); 462c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose if (!D) 463c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose return 0; 464c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose 465c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose const CXXMethodDecl *MD = cast<CXXMethodDecl>(D); 466c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose if (!MD->isVirtual()) 467c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose return MD; 468c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose 469c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose // If the method is virtual, see if we can find the actual implementation 470c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose // based on context-sensitivity. 471c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose if (const CXXMethodDecl *Devirtualized = devirtualize(MD, getCXXThisVal())) 472c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose return Devirtualized; 473c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose 4749dc5167e4017ef4c8b327abb6f72225eec2e0f19Anna Zaks return 0; 475c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose} 476c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose 4778d276d38c258dfc572586daf6c0e8f8fce249c0eJordan Rose 478e54cfc7b9990acffd0a8a4ba381717b4bb9f3011Jordan RoseCallEvent::param_iterator 479e54cfc7b9990acffd0a8a4ba381717b4bb9f3011Jordan RoseObjCMethodCall::param_begin(bool UseDefinitionParams) const { 4809dc5167e4017ef4c8b327abb6f72225eec2e0f19Anna Zaks const Decl *D = UseDefinitionParams ? getRuntimeDefinition() 481c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose : getDecl(); 482740d490593e0de8732a697c9f77b90ddd463863bJordan Rose if (!D) 483740d490593e0de8732a697c9f77b90ddd463863bJordan Rose return 0; 484740d490593e0de8732a697c9f77b90ddd463863bJordan Rose 485e54cfc7b9990acffd0a8a4ba381717b4bb9f3011Jordan Rose return cast<ObjCMethodDecl>(D)->param_begin(); 486740d490593e0de8732a697c9f77b90ddd463863bJordan Rose} 487740d490593e0de8732a697c9f77b90ddd463863bJordan Rose 488e54cfc7b9990acffd0a8a4ba381717b4bb9f3011Jordan RoseCallEvent::param_iterator 489e54cfc7b9990acffd0a8a4ba381717b4bb9f3011Jordan RoseObjCMethodCall::param_end(bool UseDefinitionParams) const { 4909dc5167e4017ef4c8b327abb6f72225eec2e0f19Anna Zaks const Decl *D = UseDefinitionParams ? getRuntimeDefinition() 491c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose : getDecl(); 492740d490593e0de8732a697c9f77b90ddd463863bJordan Rose if (!D) 493740d490593e0de8732a697c9f77b90ddd463863bJordan Rose return 0; 494740d490593e0de8732a697c9f77b90ddd463863bJordan Rose 495e54cfc7b9990acffd0a8a4ba381717b4bb9f3011Jordan Rose return cast<ObjCMethodDecl>(D)->param_end(); 496740d490593e0de8732a697c9f77b90ddd463863bJordan Rose} 497740d490593e0de8732a697c9f77b90ddd463863bJordan Rose 498740d490593e0de8732a697c9f77b90ddd463863bJordan Rosevoid 4994b3918e9534e46f9ac067c6e0018f94613292efaJordan RoseObjCMethodCall::getExtraInvalidatedRegions(RegionList &Regions) const { 500740d490593e0de8732a697c9f77b90ddd463863bJordan Rose if (const MemRegion *R = getReceiverSVal().getAsRegion()) 501740d490593e0de8732a697c9f77b90ddd463863bJordan Rose Regions.push_back(R); 502740d490593e0de8732a697c9f77b90ddd463863bJordan Rose} 503740d490593e0de8732a697c9f77b90ddd463863bJordan Rose 504cde8cdbd6a662c636164465ad309b5f17ff01064Jordan RoseQualType ObjCMethodCall::getDeclaredResultType() const { 505740d490593e0de8732a697c9f77b90ddd463863bJordan Rose const ObjCMethodDecl *D = getDecl(); 506740d490593e0de8732a697c9f77b90ddd463863bJordan Rose if (!D) 507740d490593e0de8732a697c9f77b90ddd463863bJordan Rose return QualType(); 508740d490593e0de8732a697c9f77b90ddd463863bJordan Rose 509740d490593e0de8732a697c9f77b90ddd463863bJordan Rose return D->getResultType(); 510740d490593e0de8732a697c9f77b90ddd463863bJordan Rose} 511740d490593e0de8732a697c9f77b90ddd463863bJordan Rose 512cde8cdbd6a662c636164465ad309b5f17ff01064Jordan RoseSVal ObjCMethodCall::getReceiverSVal() const { 513740d490593e0de8732a697c9f77b90ddd463863bJordan Rose // FIXME: Is this the best way to handle class receivers? 514740d490593e0de8732a697c9f77b90ddd463863bJordan Rose if (!isInstanceMessage()) 515740d490593e0de8732a697c9f77b90ddd463863bJordan Rose return UnknownVal(); 516740d490593e0de8732a697c9f77b90ddd463863bJordan Rose 5178919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose if (const Expr *Base = getOriginExpr()->getInstanceReceiver()) 518740d490593e0de8732a697c9f77b90ddd463863bJordan Rose return getSVal(Base); 519740d490593e0de8732a697c9f77b90ddd463863bJordan Rose 520740d490593e0de8732a697c9f77b90ddd463863bJordan Rose // An instance message with no expression means we are sending to super. 521740d490593e0de8732a697c9f77b90ddd463863bJordan Rose // In this case the object reference is the same as 'self'. 522b7a23e05d1d8f07f2a6edce5c88c728fe894c2c7Jordan Rose const LocationContext *LCtx = getLocationContext(); 523740d490593e0de8732a697c9f77b90ddd463863bJordan Rose const ImplicitParamDecl *SelfDecl = LCtx->getSelfDecl(); 524740d490593e0de8732a697c9f77b90ddd463863bJordan Rose assert(SelfDecl && "No message receiver Expr, but not in an ObjC method"); 525b7a23e05d1d8f07f2a6edce5c88c728fe894c2c7Jordan Rose return getState()->getSVal(getState()->getRegion(SelfDecl, LCtx)); 526b7a23e05d1d8f07f2a6edce5c88c728fe894c2c7Jordan Rose} 527b7a23e05d1d8f07f2a6edce5c88c728fe894c2c7Jordan Rose 5288919e688dc610d1f632a4d43f7f1489f67255476Jordan RoseSourceRange ObjCMethodCall::getSourceRange() const { 5298919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose switch (getMessageKind()) { 5308919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose case OCM_Message: 5318919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose return getOriginExpr()->getSourceRange(); 5328919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose case OCM_PropertyAccess: 5338919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose case OCM_Subscript: 5348919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose return getContainingPseudoObjectExpr()->getSourceRange(); 5358919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose } 5367c30427afb4c2171ee4d336477f5e4d7c277ccb4Richard Smith llvm_unreachable("unknown message kind"); 5378919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose} 5388919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose 5398919e688dc610d1f632a4d43f7f1489f67255476Jordan Rosetypedef llvm::PointerIntPair<const PseudoObjectExpr *, 2> ObjCMessageDataTy; 5408919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose 5418919e688dc610d1f632a4d43f7f1489f67255476Jordan Roseconst PseudoObjectExpr *ObjCMethodCall::getContainingPseudoObjectExpr() const { 5428919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose assert(Data != 0 && "Lazy lookup not yet performed."); 5438919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose assert(getMessageKind() != OCM_Message && "Explicit message send."); 5448919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose return ObjCMessageDataTy::getFromOpaqueValue(Data).getPointer(); 5458919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose} 5468919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose 5478919e688dc610d1f632a4d43f7f1489f67255476Jordan RoseObjCMessageKind ObjCMethodCall::getMessageKind() const { 5488919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose if (Data == 0) { 5498919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose ParentMap &PM = getLocationContext()->getParentMap(); 5508919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose const Stmt *S = PM.getParent(getOriginExpr()); 5518919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose if (const PseudoObjectExpr *POE = dyn_cast_or_null<PseudoObjectExpr>(S)) { 5528919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose const Expr *Syntactic = POE->getSyntacticForm(); 5538919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose 5548919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose // This handles the funny case of assigning to the result of a getter. 5558919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose // This can happen if the getter returns a non-const reference. 5568919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose if (const BinaryOperator *BO = dyn_cast<BinaryOperator>(Syntactic)) 5578919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose Syntactic = BO->getLHS(); 5588919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose 5598919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose ObjCMessageKind K; 5608919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose switch (Syntactic->getStmtClass()) { 5618919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose case Stmt::ObjCPropertyRefExprClass: 5628919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose K = OCM_PropertyAccess; 5638919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose break; 5648919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose case Stmt::ObjCSubscriptRefExprClass: 5658919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose K = OCM_Subscript; 5668919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose break; 5678919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose default: 5688919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose // FIXME: Can this ever happen? 5698919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose K = OCM_Message; 5708919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose break; 5718919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose } 5728919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose 5738919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose if (K != OCM_Message) { 5748919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose const_cast<ObjCMethodCall *>(this)->Data 5758919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose = ObjCMessageDataTy(POE, K).getOpaqueValue(); 5768919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose assert(getMessageKind() == K); 5778919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose return K; 5788919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose } 5798919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose } 5808919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose 5818919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose const_cast<ObjCMethodCall *>(this)->Data 5828919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose = ObjCMessageDataTy(0, 1).getOpaqueValue(); 5838919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose assert(getMessageKind() == OCM_Message); 5848919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose return OCM_Message; 5858919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose } 5868919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose 5878919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose ObjCMessageDataTy Info = ObjCMessageDataTy::getFromOpaqueValue(Data); 5888919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose if (!Info.getPointer()) 5898919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose return OCM_Message; 5908919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose return static_cast<ObjCMessageKind>(Info.getInt()); 591740d490593e0de8732a697c9f77b90ddd463863bJordan Rose} 5929dc5167e4017ef4c8b327abb6f72225eec2e0f19Anna Zaks 5939dc5167e4017ef4c8b327abb6f72225eec2e0f19Anna Zaks// TODO: This implementation is copied from SemaExprObjC.cpp, needs to be 5949dc5167e4017ef4c8b327abb6f72225eec2e0f19Anna Zaks// factored into the ObjCInterfaceDecl. 5959dc5167e4017ef4c8b327abb6f72225eec2e0f19Anna ZaksObjCMethodDecl *ObjCMethodCall::LookupClassMethodDefinition(Selector Sel, 5969dc5167e4017ef4c8b327abb6f72225eec2e0f19Anna Zaks ObjCInterfaceDecl *ClassDecl) const { 5979dc5167e4017ef4c8b327abb6f72225eec2e0f19Anna Zaks ObjCMethodDecl *Method = 0; 5989dc5167e4017ef4c8b327abb6f72225eec2e0f19Anna Zaks // Lookup in class and all superclasses. 5999dc5167e4017ef4c8b327abb6f72225eec2e0f19Anna Zaks while (ClassDecl && !Method) { 6009dc5167e4017ef4c8b327abb6f72225eec2e0f19Anna Zaks if (ObjCImplementationDecl *ImpDecl = ClassDecl->getImplementation()) 6019dc5167e4017ef4c8b327abb6f72225eec2e0f19Anna Zaks Method = ImpDecl->getClassMethod(Sel); 6029dc5167e4017ef4c8b327abb6f72225eec2e0f19Anna Zaks 6039dc5167e4017ef4c8b327abb6f72225eec2e0f19Anna Zaks // Look through local category implementations associated with the class. 6049dc5167e4017ef4c8b327abb6f72225eec2e0f19Anna Zaks if (!Method) 6059dc5167e4017ef4c8b327abb6f72225eec2e0f19Anna Zaks Method = ClassDecl->getCategoryClassMethod(Sel); 6069dc5167e4017ef4c8b327abb6f72225eec2e0f19Anna Zaks 6079dc5167e4017ef4c8b327abb6f72225eec2e0f19Anna Zaks // Before we give up, check if the selector is an instance method. 6089dc5167e4017ef4c8b327abb6f72225eec2e0f19Anna Zaks // But only in the root. This matches gcc's behavior and what the 6099dc5167e4017ef4c8b327abb6f72225eec2e0f19Anna Zaks // runtime expects. 6109dc5167e4017ef4c8b327abb6f72225eec2e0f19Anna Zaks if (!Method && !ClassDecl->getSuperClass()) { 6119dc5167e4017ef4c8b327abb6f72225eec2e0f19Anna Zaks Method = ClassDecl->lookupInstanceMethod(Sel); 6129dc5167e4017ef4c8b327abb6f72225eec2e0f19Anna Zaks // Look through local category implementations associated 6139dc5167e4017ef4c8b327abb6f72225eec2e0f19Anna Zaks // with the root class. 6149dc5167e4017ef4c8b327abb6f72225eec2e0f19Anna Zaks //if (!Method) 6159dc5167e4017ef4c8b327abb6f72225eec2e0f19Anna Zaks // Method = LookupPrivateInstanceMethod(Sel, ClassDecl); 6169dc5167e4017ef4c8b327abb6f72225eec2e0f19Anna Zaks } 6179dc5167e4017ef4c8b327abb6f72225eec2e0f19Anna Zaks 6189dc5167e4017ef4c8b327abb6f72225eec2e0f19Anna Zaks ClassDecl = ClassDecl->getSuperClass(); 6199dc5167e4017ef4c8b327abb6f72225eec2e0f19Anna Zaks } 6209dc5167e4017ef4c8b327abb6f72225eec2e0f19Anna Zaks return Method; 6219dc5167e4017ef4c8b327abb6f72225eec2e0f19Anna Zaks} 6229dc5167e4017ef4c8b327abb6f72225eec2e0f19Anna Zaks 623