CallEvent.cpp revision 3f558af01643787d209a133215b0abec81b5fe30
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 235ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rosestatic void addParameterValuesToBindings(const StackFrameContext *CalleeCtx, 236ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose CallEvent::BindingsTy &Bindings, 237ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose SValBuilder &SVB, 238ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose const CallEvent &Call, 239ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose CallEvent::param_iterator I, 240ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose CallEvent::param_iterator E) { 241ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose MemRegionManager &MRMgr = SVB.getRegionManager(); 24285d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose 243ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose unsigned Idx = 0; 244ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose for (; I != E; ++I, ++Idx) { 245ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose const ParmVarDecl *ParamDecl = *I; 246ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose assert(ParamDecl && "Formal parameter has no decl?"); 247ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose 248ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose SVal ArgVal = Call.getArgSVal(Idx); 249ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose if (!ArgVal.isUnknown()) { 250ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose Loc ParamLoc = SVB.makeLoc(MRMgr.getVarRegion(ParamDecl, CalleeCtx)); 251ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose Bindings.push_back(std::make_pair(ParamLoc, ArgVal)); 252ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose } 253ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose } 254ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose 255ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose // FIXME: Variadic arguments are not handled at all right now. 256ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose} 257ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose 258ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose 259ef15831780b705475e7b237ac16418e9b53cb7a6Jordan RoseCallEvent::param_iterator AnyFunctionCall::param_begin() const { 260ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose const FunctionDecl *D = getDecl(); 261740d490593e0de8732a697c9f77b90ddd463863bJordan Rose if (!D) 262740d490593e0de8732a697c9f77b90ddd463863bJordan Rose return 0; 263740d490593e0de8732a697c9f77b90ddd463863bJordan Rose 264ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose return D->param_begin(); 265740d490593e0de8732a697c9f77b90ddd463863bJordan Rose} 266740d490593e0de8732a697c9f77b90ddd463863bJordan Rose 267ef15831780b705475e7b237ac16418e9b53cb7a6Jordan RoseCallEvent::param_iterator AnyFunctionCall::param_end() const { 268ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose const FunctionDecl *D = getDecl(); 269740d490593e0de8732a697c9f77b90ddd463863bJordan Rose if (!D) 270740d490593e0de8732a697c9f77b90ddd463863bJordan Rose return 0; 271740d490593e0de8732a697c9f77b90ddd463863bJordan Rose 272ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose return D->param_end(); 273ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose} 274ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose 275ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rosevoid AnyFunctionCall::getInitialStackFrameContents( 276ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose const StackFrameContext *CalleeCtx, 277ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose BindingsTy &Bindings) const { 278ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose const FunctionDecl *D = cast<FunctionDecl>(CalleeCtx->getDecl()); 279ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose SValBuilder &SVB = getState()->getStateManager().getSValBuilder(); 280ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose addParameterValuesToBindings(CalleeCtx, Bindings, SVB, *this, 281ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose D->param_begin(), D->param_end()); 282740d490593e0de8732a697c9f77b90ddd463863bJordan Rose} 283740d490593e0de8732a697c9f77b90ddd463863bJordan Rose 284740d490593e0de8732a697c9f77b90ddd463863bJordan RoseQualType AnyFunctionCall::getDeclaredResultType() const { 285740d490593e0de8732a697c9f77b90ddd463863bJordan Rose const FunctionDecl *D = getDecl(); 286740d490593e0de8732a697c9f77b90ddd463863bJordan Rose if (!D) 287740d490593e0de8732a697c9f77b90ddd463863bJordan Rose return QualType(); 288740d490593e0de8732a697c9f77b90ddd463863bJordan Rose 289740d490593e0de8732a697c9f77b90ddd463863bJordan Rose return D->getResultType(); 290740d490593e0de8732a697c9f77b90ddd463863bJordan Rose} 291740d490593e0de8732a697c9f77b90ddd463863bJordan Rose 29285d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rosebool AnyFunctionCall::argumentsMayEscape() const { 293b7a23e05d1d8f07f2a6edce5c88c728fe894c2c7Jordan Rose if (hasNonZeroCallbackArg()) 29485d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose return true; 29585d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose 29685d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose const FunctionDecl *D = getDecl(); 29785d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose if (!D) 29885d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose return true; 29985d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose 30085d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose const IdentifierInfo *II = D->getIdentifier(); 30185d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose if (!II) 30285d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose return true; 30385d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose 30485d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose // This set of "escaping" APIs is 30585d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose 30685d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose // - 'int pthread_setspecific(ptheread_key k, const void *)' stores a 30785d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose // value into thread local storage. The value can later be retrieved with 30885d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose // 'void *ptheread_getspecific(pthread_key)'. So even thought the 30985d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose // parameter is 'const void *', the region escapes through the call. 31085d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose if (II->isStr("pthread_setspecific")) 31185d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose return true; 31285d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose 31385d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose // - xpc_connection_set_context stores a value which can be retrieved later 31485d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose // with xpc_connection_get_context. 31585d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose if (II->isStr("xpc_connection_set_context")) 31685d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose return true; 31785d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose 31885d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose // - funopen - sets a buffer for future IO calls. 31985d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose if (II->isStr("funopen")) 32085d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose return true; 32185d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose 32285d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose StringRef FName = II->getName(); 32385d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose 32485d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose // - CoreFoundation functions that end with "NoCopy" can free a passed-in 32585d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose // buffer even if it is const. 32685d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose if (FName.endswith("NoCopy")) 32785d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose return true; 32885d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose 32985d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose // - NSXXInsertXX, for example NSMapInsertIfAbsent, since they can 33085d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose // be deallocated by NSMapRemove. 33185d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose if (FName.startswith("NS") && (FName.find("Insert") != StringRef::npos)) 33285d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose return true; 33385d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose 33485d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose // - Many CF containers allow objects to escape through custom 33585d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose // allocators/deallocators upon container construction. (PR12101) 33685d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose if (FName.startswith("CF") || FName.startswith("CG")) { 33785d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose return StrInStrNoCase(FName, "InsertValue") != StringRef::npos || 33885d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose StrInStrNoCase(FName, "AddValue") != StringRef::npos || 33985d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose StrInStrNoCase(FName, "SetValue") != StringRef::npos || 34085d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose StrInStrNoCase(FName, "WithData") != StringRef::npos || 34185d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose StrInStrNoCase(FName, "AppendValue") != StringRef::npos || 34285d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose StrInStrNoCase(FName, "SetAttribute") != StringRef::npos; 34385d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose } 34485d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose 34585d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose return false; 34685d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose} 34785d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose 34885d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose 349740d490593e0de8732a697c9f77b90ddd463863bJordan Roseconst FunctionDecl *SimpleCall::getDecl() const { 350b7a23e05d1d8f07f2a6edce5c88c728fe894c2c7Jordan Rose const FunctionDecl *D = getOriginExpr()->getDirectCallee(); 351740d490593e0de8732a697c9f77b90ddd463863bJordan Rose if (D) 352740d490593e0de8732a697c9f77b90ddd463863bJordan Rose return D; 353740d490593e0de8732a697c9f77b90ddd463863bJordan Rose 354b7a23e05d1d8f07f2a6edce5c88c728fe894c2c7Jordan Rose return getSVal(getOriginExpr()->getCallee()).getAsFunctionDecl(); 355740d490593e0de8732a697c9f77b90ddd463863bJordan Rose} 356740d490593e0de8732a697c9f77b90ddd463863bJordan Rose 35785d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose 3584b3918e9534e46f9ac067c6e0018f94613292efaJordan Rosevoid CXXInstanceCall::getExtraInvalidatedRegions(RegionList &Regions) const { 359c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose if (const MemRegion *R = getCXXThisVal().getAsRegion()) 360c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose Regions.push_back(R); 361c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose} 362c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose 363c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rosestatic const CXXMethodDecl *devirtualize(const CXXMethodDecl *MD, SVal ThisVal){ 364c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose const MemRegion *R = ThisVal.getAsRegion(); 365c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose if (!R) 366c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose return 0; 367c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose 368c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose const TypedValueRegion *TR = dyn_cast<TypedValueRegion>(R->StripCasts()); 369c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose if (!TR) 370c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose return 0; 371c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose 372c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose const CXXRecordDecl *RD = TR->getValueType()->getAsCXXRecordDecl(); 373c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose if (!RD) 374c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose return 0; 375c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose 376c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose const CXXMethodDecl *Result = MD->getCorrespondingMethodInClass(RD); 377c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose const FunctionDecl *Definition; 378c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose if (!Result->hasBody(Definition)) 379c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose return 0; 380c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose 381c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose return cast<CXXMethodDecl>(Definition); 382c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose} 383c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose 384c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose 385e90d3f847dcce76237078b67db8895eb7a24189eAnna ZaksRuntimeDefinition CXXInstanceCall::getRuntimeDefinition() const { 386fc05decf08feefd2ffe8cc250219aee6eab3119cAnna Zaks const Decl *D = SimpleCall::getRuntimeDefinition().getDecl(); 387c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose if (!D) 388e90d3f847dcce76237078b67db8895eb7a24189eAnna Zaks return RuntimeDefinition(); 389c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose 390c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose const CXXMethodDecl *MD = cast<CXXMethodDecl>(D); 391c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose if (!MD->isVirtual()) 3925960f4aeac9760198c80e05d70d8dadb1db0ff0eAnna Zaks return RuntimeDefinition(MD); 393c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose 394c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose // If the method is virtual, see if we can find the actual implementation 395c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose // based on context-sensitivity. 3966d8ab45a203eb701c2fd1104492cb4bd7557a3e9Jordan Rose // FIXME: Virtual method calls behave differently when an object is being 3976d8ab45a203eb701c2fd1104492cb4bd7557a3e9Jordan Rose // constructed or destructed. It's not as simple as "no devirtualization" 3986d8ab45a203eb701c2fd1104492cb4bd7557a3e9Jordan Rose // because a /partially/ constructed object can be referred to through a 3996d8ab45a203eb701c2fd1104492cb4bd7557a3e9Jordan Rose // base pointer. We'll eventually want to use DynamicTypeInfo here. 400c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose if (const CXXMethodDecl *Devirtualized = devirtualize(MD, getCXXThisVal())) 4015960f4aeac9760198c80e05d70d8dadb1db0ff0eAnna Zaks return RuntimeDefinition(Devirtualized); 402c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose 403e90d3f847dcce76237078b67db8895eb7a24189eAnna Zaks return RuntimeDefinition(); 404c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose} 405c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose 406ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rosevoid CXXInstanceCall::getInitialStackFrameContents( 407ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose const StackFrameContext *CalleeCtx, 408ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose BindingsTy &Bindings) const { 409ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose AnyFunctionCall::getInitialStackFrameContents(CalleeCtx, Bindings); 410ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose 411ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose SVal ThisVal = getCXXThisVal(); 412ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose if (!ThisVal.isUnknown()) { 413ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose SValBuilder &SVB = getState()->getStateManager().getSValBuilder(); 414ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose const CXXMethodDecl *MD = cast<CXXMethodDecl>(CalleeCtx->getDecl()); 415ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose Loc ThisLoc = SVB.getCXXThis(MD, CalleeCtx); 416ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose Bindings.push_back(std::make_pair(ThisLoc, ThisVal)); 417ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose } 418ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose} 419ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose 420ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose 421c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose 4229da59a67a27a4d3fc9d59552f07808a32f85e9d3Jordan Roseconst Expr *CXXMemberCall::getCXXThisExpr() const { 4239da59a67a27a4d3fc9d59552f07808a32f85e9d3Jordan Rose return getOriginExpr()->getImplicitObjectArgument(); 424e54cfc7b9990acffd0a8a4ba381717b4bb9f3011Jordan Rose} 425e54cfc7b9990acffd0a8a4ba381717b4bb9f3011Jordan Rose 42685d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose 4279da59a67a27a4d3fc9d59552f07808a32f85e9d3Jordan Roseconst Expr *CXXMemberOperatorCall::getCXXThisExpr() const { 4289da59a67a27a4d3fc9d59552f07808a32f85e9d3Jordan Rose return getOriginExpr()->getArg(0); 429e54cfc7b9990acffd0a8a4ba381717b4bb9f3011Jordan Rose} 430e54cfc7b9990acffd0a8a4ba381717b4bb9f3011Jordan Rose 431fdaa33818cf9bad8d092136e73bd2e489cb821baJordan Rose 432740d490593e0de8732a697c9f77b90ddd463863bJordan Roseconst BlockDataRegion *BlockCall::getBlockRegion() const { 433740d490593e0de8732a697c9f77b90ddd463863bJordan Rose const Expr *Callee = getOriginExpr()->getCallee(); 434740d490593e0de8732a697c9f77b90ddd463863bJordan Rose const MemRegion *DataReg = getSVal(Callee).getAsRegion(); 435740d490593e0de8732a697c9f77b90ddd463863bJordan Rose 43669f87c956b3ac2b80124fd9604af012e1061473aJordan Rose return dyn_cast_or_null<BlockDataRegion>(DataReg); 437740d490593e0de8732a697c9f77b90ddd463863bJordan Rose} 438740d490593e0de8732a697c9f77b90ddd463863bJordan Rose 439ef15831780b705475e7b237ac16418e9b53cb7a6Jordan RoseCallEvent::param_iterator BlockCall::param_begin() const { 44069f87c956b3ac2b80124fd9604af012e1061473aJordan Rose const BlockDecl *D = getBlockDecl(); 44169f87c956b3ac2b80124fd9604af012e1061473aJordan Rose if (!D) 44269f87c956b3ac2b80124fd9604af012e1061473aJordan Rose return 0; 44369f87c956b3ac2b80124fd9604af012e1061473aJordan Rose return D->param_begin(); 444740d490593e0de8732a697c9f77b90ddd463863bJordan Rose} 445740d490593e0de8732a697c9f77b90ddd463863bJordan Rose 446ef15831780b705475e7b237ac16418e9b53cb7a6Jordan RoseCallEvent::param_iterator BlockCall::param_end() const { 44769f87c956b3ac2b80124fd9604af012e1061473aJordan Rose const BlockDecl *D = getBlockDecl(); 44869f87c956b3ac2b80124fd9604af012e1061473aJordan Rose if (!D) 44969f87c956b3ac2b80124fd9604af012e1061473aJordan Rose return 0; 45069f87c956b3ac2b80124fd9604af012e1061473aJordan Rose return D->param_end(); 451740d490593e0de8732a697c9f77b90ddd463863bJordan Rose} 452740d490593e0de8732a697c9f77b90ddd463863bJordan Rose 4534b3918e9534e46f9ac067c6e0018f94613292efaJordan Rosevoid BlockCall::getExtraInvalidatedRegions(RegionList &Regions) const { 45469f87c956b3ac2b80124fd9604af012e1061473aJordan Rose // FIXME: This also needs to invalidate captured globals. 45569f87c956b3ac2b80124fd9604af012e1061473aJordan Rose if (const MemRegion *R = getBlockRegion()) 45669f87c956b3ac2b80124fd9604af012e1061473aJordan Rose Regions.push_back(R); 457740d490593e0de8732a697c9f77b90ddd463863bJordan Rose} 458740d490593e0de8732a697c9f77b90ddd463863bJordan Rose 459ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rosevoid BlockCall::getInitialStackFrameContents(const StackFrameContext *CalleeCtx, 460ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose BindingsTy &Bindings) const { 461ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose const BlockDecl *D = cast<BlockDecl>(CalleeCtx->getDecl()); 462ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose SValBuilder &SVB = getState()->getStateManager().getSValBuilder(); 463ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose addParameterValuesToBindings(CalleeCtx, Bindings, SVB, *this, 464ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose D->param_begin(), D->param_end()); 465ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose} 466ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose 467ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose 468740d490593e0de8732a697c9f77b90ddd463863bJordan RoseQualType BlockCall::getDeclaredResultType() const { 46969f87c956b3ac2b80124fd9604af012e1061473aJordan Rose const BlockDataRegion *BR = getBlockRegion(); 47069f87c956b3ac2b80124fd9604af012e1061473aJordan Rose if (!BR) 47169f87c956b3ac2b80124fd9604af012e1061473aJordan Rose return QualType(); 47269f87c956b3ac2b80124fd9604af012e1061473aJordan Rose QualType BlockTy = BR->getCodeRegion()->getLocationType(); 473740d490593e0de8732a697c9f77b90ddd463863bJordan Rose return cast<FunctionType>(BlockTy->getPointeeType())->getResultType(); 474740d490593e0de8732a697c9f77b90ddd463863bJordan Rose} 475740d490593e0de8732a697c9f77b90ddd463863bJordan Rose 47685d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose 477e54cfc7b9990acffd0a8a4ba381717b4bb9f3011Jordan RoseSVal CXXConstructorCall::getCXXThisVal() const { 478b7a23e05d1d8f07f2a6edce5c88c728fe894c2c7Jordan Rose if (Data) 479b7a23e05d1d8f07f2a6edce5c88c728fe894c2c7Jordan Rose return loc::MemRegionVal(static_cast<const MemRegion *>(Data)); 480e54cfc7b9990acffd0a8a4ba381717b4bb9f3011Jordan Rose return UnknownVal(); 481e54cfc7b9990acffd0a8a4ba381717b4bb9f3011Jordan Rose} 482e54cfc7b9990acffd0a8a4ba381717b4bb9f3011Jordan Rose 4834b3918e9534e46f9ac067c6e0018f94613292efaJordan Rosevoid CXXConstructorCall::getExtraInvalidatedRegions(RegionList &Regions) const { 484b7a23e05d1d8f07f2a6edce5c88c728fe894c2c7Jordan Rose if (Data) 485b7a23e05d1d8f07f2a6edce5c88c728fe894c2c7Jordan Rose Regions.push_back(static_cast<const MemRegion *>(Data)); 486740d490593e0de8732a697c9f77b90ddd463863bJordan Rose} 487740d490593e0de8732a697c9f77b90ddd463863bJordan Rose 488ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rosevoid CXXConstructorCall::getInitialStackFrameContents( 489ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose const StackFrameContext *CalleeCtx, 490ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose BindingsTy &Bindings) const { 491ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose AnyFunctionCall::getInitialStackFrameContents(CalleeCtx, Bindings); 492ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose 493ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose SVal ThisVal = getCXXThisVal(); 494ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose if (!ThisVal.isUnknown()) { 495ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose SValBuilder &SVB = getState()->getStateManager().getSValBuilder(); 496ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose const CXXMethodDecl *MD = cast<CXXMethodDecl>(CalleeCtx->getDecl()); 497ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose Loc ThisLoc = SVB.getCXXThis(MD, CalleeCtx); 498ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose Bindings.push_back(std::make_pair(ThisLoc, ThisVal)); 499ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose } 500ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose} 501ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose 502ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose 50385d7e01cf639b257d70f8a129709a2d7594d7b22Jordan Rose 504e54cfc7b9990acffd0a8a4ba381717b4bb9f3011Jordan RoseSVal CXXDestructorCall::getCXXThisVal() const { 505b7a23e05d1d8f07f2a6edce5c88c728fe894c2c7Jordan Rose if (Data) 506b7a23e05d1d8f07f2a6edce5c88c728fe894c2c7Jordan Rose return loc::MemRegionVal(static_cast<const MemRegion *>(Data)); 507e54cfc7b9990acffd0a8a4ba381717b4bb9f3011Jordan Rose return UnknownVal(); 508e54cfc7b9990acffd0a8a4ba381717b4bb9f3011Jordan Rose} 509e54cfc7b9990acffd0a8a4ba381717b4bb9f3011Jordan Rose 5104b3918e9534e46f9ac067c6e0018f94613292efaJordan Rosevoid CXXDestructorCall::getExtraInvalidatedRegions(RegionList &Regions) const { 511b7a23e05d1d8f07f2a6edce5c88c728fe894c2c7Jordan Rose if (Data) 512b7a23e05d1d8f07f2a6edce5c88c728fe894c2c7Jordan Rose Regions.push_back(static_cast<const MemRegion *>(Data)); 5138d276d38c258dfc572586daf6c0e8f8fce249c0eJordan Rose} 5148d276d38c258dfc572586daf6c0e8f8fce249c0eJordan Rose 515e90d3f847dcce76237078b67db8895eb7a24189eAnna ZaksRuntimeDefinition CXXDestructorCall::getRuntimeDefinition() const { 516fc05decf08feefd2ffe8cc250219aee6eab3119cAnna Zaks const Decl *D = AnyFunctionCall::getRuntimeDefinition().getDecl(); 517c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose if (!D) 518e90d3f847dcce76237078b67db8895eb7a24189eAnna Zaks return RuntimeDefinition(); 519c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose 520c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose const CXXMethodDecl *MD = cast<CXXMethodDecl>(D); 521c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose if (!MD->isVirtual()) 5225960f4aeac9760198c80e05d70d8dadb1db0ff0eAnna Zaks return RuntimeDefinition(MD); 523c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose 524c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose // If the method is virtual, see if we can find the actual implementation 525c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose // based on context-sensitivity. 5266d8ab45a203eb701c2fd1104492cb4bd7557a3e9Jordan Rose // FIXME: Virtual method calls behave differently when an object is being 5276d8ab45a203eb701c2fd1104492cb4bd7557a3e9Jordan Rose // constructed or destructed. It's not as simple as "no devirtualization" 5286d8ab45a203eb701c2fd1104492cb4bd7557a3e9Jordan Rose // because a /partially/ constructed object can be referred to through a 5296d8ab45a203eb701c2fd1104492cb4bd7557a3e9Jordan Rose // base pointer. We'll eventually want to use DynamicTypeInfo here. 530c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose if (const CXXMethodDecl *Devirtualized = devirtualize(MD, getCXXThisVal())) 5315960f4aeac9760198c80e05d70d8dadb1db0ff0eAnna Zaks return RuntimeDefinition(Devirtualized); 532c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose 533e90d3f847dcce76237078b67db8895eb7a24189eAnna Zaks return RuntimeDefinition(); 534c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose} 535c36b30c92c78b95fd29fb5d9d6214d737b3bcb02Jordan Rose 536ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rosevoid CXXDestructorCall::getInitialStackFrameContents( 537ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose const StackFrameContext *CalleeCtx, 538ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose BindingsTy &Bindings) const { 539ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose AnyFunctionCall::getInitialStackFrameContents(CalleeCtx, Bindings); 5408d276d38c258dfc572586daf6c0e8f8fce249c0eJordan Rose 541ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose SVal ThisVal = getCXXThisVal(); 542ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose if (!ThisVal.isUnknown()) { 543ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose SValBuilder &SVB = getState()->getStateManager().getSValBuilder(); 544ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose const CXXMethodDecl *MD = cast<CXXMethodDecl>(CalleeCtx->getDecl()); 545ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose Loc ThisLoc = SVB.getCXXThis(MD, CalleeCtx); 546ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose Bindings.push_back(std::make_pair(ThisLoc, ThisVal)); 547ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose } 548ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose} 549ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose 550ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose 551ef15831780b705475e7b237ac16418e9b53cb7a6Jordan RoseCallEvent::param_iterator ObjCMethodCall::param_begin() const { 552ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose const ObjCMethodDecl *D = getDecl(); 553740d490593e0de8732a697c9f77b90ddd463863bJordan Rose if (!D) 554740d490593e0de8732a697c9f77b90ddd463863bJordan Rose return 0; 555740d490593e0de8732a697c9f77b90ddd463863bJordan Rose 556ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose return D->param_begin(); 557740d490593e0de8732a697c9f77b90ddd463863bJordan Rose} 558740d490593e0de8732a697c9f77b90ddd463863bJordan Rose 559ef15831780b705475e7b237ac16418e9b53cb7a6Jordan RoseCallEvent::param_iterator ObjCMethodCall::param_end() const { 560ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose const ObjCMethodDecl *D = getDecl(); 561740d490593e0de8732a697c9f77b90ddd463863bJordan Rose if (!D) 562740d490593e0de8732a697c9f77b90ddd463863bJordan Rose return 0; 563740d490593e0de8732a697c9f77b90ddd463863bJordan Rose 564ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose return D->param_end(); 565740d490593e0de8732a697c9f77b90ddd463863bJordan Rose} 566740d490593e0de8732a697c9f77b90ddd463863bJordan Rose 567740d490593e0de8732a697c9f77b90ddd463863bJordan Rosevoid 5684b3918e9534e46f9ac067c6e0018f94613292efaJordan RoseObjCMethodCall::getExtraInvalidatedRegions(RegionList &Regions) const { 569740d490593e0de8732a697c9f77b90ddd463863bJordan Rose if (const MemRegion *R = getReceiverSVal().getAsRegion()) 570740d490593e0de8732a697c9f77b90ddd463863bJordan Rose Regions.push_back(R); 571740d490593e0de8732a697c9f77b90ddd463863bJordan Rose} 572740d490593e0de8732a697c9f77b90ddd463863bJordan Rose 573cde8cdbd6a662c636164465ad309b5f17ff01064Jordan RoseQualType ObjCMethodCall::getDeclaredResultType() const { 574740d490593e0de8732a697c9f77b90ddd463863bJordan Rose const ObjCMethodDecl *D = getDecl(); 575740d490593e0de8732a697c9f77b90ddd463863bJordan Rose if (!D) 576740d490593e0de8732a697c9f77b90ddd463863bJordan Rose return QualType(); 577740d490593e0de8732a697c9f77b90ddd463863bJordan Rose 578740d490593e0de8732a697c9f77b90ddd463863bJordan Rose return D->getResultType(); 579740d490593e0de8732a697c9f77b90ddd463863bJordan Rose} 580740d490593e0de8732a697c9f77b90ddd463863bJordan Rose 581cde8cdbd6a662c636164465ad309b5f17ff01064Jordan RoseSVal ObjCMethodCall::getReceiverSVal() const { 582740d490593e0de8732a697c9f77b90ddd463863bJordan Rose // FIXME: Is this the best way to handle class receivers? 583740d490593e0de8732a697c9f77b90ddd463863bJordan Rose if (!isInstanceMessage()) 584740d490593e0de8732a697c9f77b90ddd463863bJordan Rose return UnknownVal(); 585740d490593e0de8732a697c9f77b90ddd463863bJordan Rose 586c7ecc43c33a21b82c49664910b19fcc1f555aa51Anna Zaks if (const Expr *RecE = getOriginExpr()->getInstanceReceiver()) 587c7ecc43c33a21b82c49664910b19fcc1f555aa51Anna Zaks return getSVal(RecE); 588740d490593e0de8732a697c9f77b90ddd463863bJordan Rose 589740d490593e0de8732a697c9f77b90ddd463863bJordan Rose // An instance message with no expression means we are sending to super. 590740d490593e0de8732a697c9f77b90ddd463863bJordan Rose // In this case the object reference is the same as 'self'. 591b7a23e05d1d8f07f2a6edce5c88c728fe894c2c7Jordan Rose const LocationContext *LCtx = getLocationContext(); 592740d490593e0de8732a697c9f77b90ddd463863bJordan Rose const ImplicitParamDecl *SelfDecl = LCtx->getSelfDecl(); 593740d490593e0de8732a697c9f77b90ddd463863bJordan Rose assert(SelfDecl && "No message receiver Expr, but not in an ObjC method"); 594b7a23e05d1d8f07f2a6edce5c88c728fe894c2c7Jordan Rose return getState()->getSVal(getState()->getRegion(SelfDecl, LCtx)); 595b7a23e05d1d8f07f2a6edce5c88c728fe894c2c7Jordan Rose} 596b7a23e05d1d8f07f2a6edce5c88c728fe894c2c7Jordan Rose 5978919e688dc610d1f632a4d43f7f1489f67255476Jordan RoseSourceRange ObjCMethodCall::getSourceRange() const { 5988919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose switch (getMessageKind()) { 5998919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose case OCM_Message: 6008919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose return getOriginExpr()->getSourceRange(); 6018919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose case OCM_PropertyAccess: 6028919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose case OCM_Subscript: 6038919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose return getContainingPseudoObjectExpr()->getSourceRange(); 6048919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose } 6057c30427afb4c2171ee4d336477f5e4d7c277ccb4Richard Smith llvm_unreachable("unknown message kind"); 6068919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose} 6078919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose 6088919e688dc610d1f632a4d43f7f1489f67255476Jordan Rosetypedef llvm::PointerIntPair<const PseudoObjectExpr *, 2> ObjCMessageDataTy; 6098919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose 6108919e688dc610d1f632a4d43f7f1489f67255476Jordan Roseconst PseudoObjectExpr *ObjCMethodCall::getContainingPseudoObjectExpr() const { 6118919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose assert(Data != 0 && "Lazy lookup not yet performed."); 6128919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose assert(getMessageKind() != OCM_Message && "Explicit message send."); 6138919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose return ObjCMessageDataTy::getFromOpaqueValue(Data).getPointer(); 6148919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose} 6158919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose 6168919e688dc610d1f632a4d43f7f1489f67255476Jordan RoseObjCMessageKind ObjCMethodCall::getMessageKind() const { 6178919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose if (Data == 0) { 6188919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose ParentMap &PM = getLocationContext()->getParentMap(); 6198919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose const Stmt *S = PM.getParent(getOriginExpr()); 6208919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose if (const PseudoObjectExpr *POE = dyn_cast_or_null<PseudoObjectExpr>(S)) { 6218919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose const Expr *Syntactic = POE->getSyntacticForm(); 6228919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose 6238919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose // This handles the funny case of assigning to the result of a getter. 6248919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose // This can happen if the getter returns a non-const reference. 6258919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose if (const BinaryOperator *BO = dyn_cast<BinaryOperator>(Syntactic)) 6268919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose Syntactic = BO->getLHS(); 6278919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose 6288919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose ObjCMessageKind K; 6298919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose switch (Syntactic->getStmtClass()) { 6308919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose case Stmt::ObjCPropertyRefExprClass: 6318919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose K = OCM_PropertyAccess; 6328919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose break; 6338919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose case Stmt::ObjCSubscriptRefExprClass: 6348919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose K = OCM_Subscript; 6358919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose break; 6368919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose default: 6378919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose // FIXME: Can this ever happen? 6388919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose K = OCM_Message; 6398919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose break; 6408919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose } 6418919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose 6428919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose if (K != OCM_Message) { 6438919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose const_cast<ObjCMethodCall *>(this)->Data 6448919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose = ObjCMessageDataTy(POE, K).getOpaqueValue(); 6458919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose assert(getMessageKind() == K); 6468919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose return K; 6478919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose } 6488919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose } 6498919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose 6508919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose const_cast<ObjCMethodCall *>(this)->Data 6518919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose = ObjCMessageDataTy(0, 1).getOpaqueValue(); 6528919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose assert(getMessageKind() == OCM_Message); 6538919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose return OCM_Message; 6548919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose } 6558919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose 6568919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose ObjCMessageDataTy Info = ObjCMessageDataTy::getFromOpaqueValue(Data); 6578919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose if (!Info.getPointer()) 6588919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose return OCM_Message; 6598919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose return static_cast<ObjCMessageKind>(Info.getInt()); 660740d490593e0de8732a697c9f77b90ddd463863bJordan Rose} 6619dc5167e4017ef4c8b327abb6f72225eec2e0f19Anna Zaks 6623f558af01643787d209a133215b0abec81b5fe30Anna Zaks 6633f558af01643787d209a133215b0abec81b5fe30Anna Zaksbool ObjCMethodCall::canBeOverridenInSubclass(ObjCInterfaceDecl *IDecl, 6643f558af01643787d209a133215b0abec81b5fe30Anna Zaks Selector Sel) const { 6653f558af01643787d209a133215b0abec81b5fe30Anna Zaks assert(IDecl); 6663f558af01643787d209a133215b0abec81b5fe30Anna Zaks const SourceManager &SM = 6673f558af01643787d209a133215b0abec81b5fe30Anna Zaks getState()->getStateManager().getContext().getSourceManager(); 6683f558af01643787d209a133215b0abec81b5fe30Anna Zaks 6693f558af01643787d209a133215b0abec81b5fe30Anna Zaks // If the class interface is declared inside the main file, assume it is not 6703f558af01643787d209a133215b0abec81b5fe30Anna Zaks // subcassed. 6713f558af01643787d209a133215b0abec81b5fe30Anna Zaks // TODO: It could actually be subclassed if the subclass is private as well. 6723f558af01643787d209a133215b0abec81b5fe30Anna Zaks // This is probably very rare. 6733f558af01643787d209a133215b0abec81b5fe30Anna Zaks SourceLocation InterfLoc = IDecl->getEndOfDefinitionLoc(); 6743f558af01643787d209a133215b0abec81b5fe30Anna Zaks if (InterfLoc.isValid() && SM.isFromMainFile(InterfLoc)) 6753f558af01643787d209a133215b0abec81b5fe30Anna Zaks return false; 6763f558af01643787d209a133215b0abec81b5fe30Anna Zaks 6773f558af01643787d209a133215b0abec81b5fe30Anna Zaks 6783f558af01643787d209a133215b0abec81b5fe30Anna Zaks // We assume that if the method is public (declared outside of main file) or 6793f558af01643787d209a133215b0abec81b5fe30Anna Zaks // has a parent which publicly declares the method, the method could be 6803f558af01643787d209a133215b0abec81b5fe30Anna Zaks // overridden in a subclass. 6813f558af01643787d209a133215b0abec81b5fe30Anna Zaks 6823f558af01643787d209a133215b0abec81b5fe30Anna Zaks // Find the first declaration in the class hierarchy that declares 6833f558af01643787d209a133215b0abec81b5fe30Anna Zaks // the selector. 6843f558af01643787d209a133215b0abec81b5fe30Anna Zaks ObjCMethodDecl *D = 0; 6853f558af01643787d209a133215b0abec81b5fe30Anna Zaks while (true) { 6863f558af01643787d209a133215b0abec81b5fe30Anna Zaks D = IDecl->lookupMethod(Sel, true); 6873f558af01643787d209a133215b0abec81b5fe30Anna Zaks 6883f558af01643787d209a133215b0abec81b5fe30Anna Zaks // Cannot find a public definition. 6893f558af01643787d209a133215b0abec81b5fe30Anna Zaks if (!D) 6903f558af01643787d209a133215b0abec81b5fe30Anna Zaks return false; 6913f558af01643787d209a133215b0abec81b5fe30Anna Zaks 6923f558af01643787d209a133215b0abec81b5fe30Anna Zaks // If outside the main file, 6933f558af01643787d209a133215b0abec81b5fe30Anna Zaks if (D->getLocation().isValid() && !SM.isFromMainFile(D->getLocation())) 6943f558af01643787d209a133215b0abec81b5fe30Anna Zaks return true; 6953f558af01643787d209a133215b0abec81b5fe30Anna Zaks 6963f558af01643787d209a133215b0abec81b5fe30Anna Zaks if (D->isOverriding()) { 6973f558af01643787d209a133215b0abec81b5fe30Anna Zaks // Search in the superclass on the next iteration. 6983f558af01643787d209a133215b0abec81b5fe30Anna Zaks IDecl = D->getClassInterface(); 6993f558af01643787d209a133215b0abec81b5fe30Anna Zaks if (!IDecl) 7003f558af01643787d209a133215b0abec81b5fe30Anna Zaks return false; 7013f558af01643787d209a133215b0abec81b5fe30Anna Zaks 7023f558af01643787d209a133215b0abec81b5fe30Anna Zaks IDecl = IDecl->getSuperClass(); 7033f558af01643787d209a133215b0abec81b5fe30Anna Zaks if (!IDecl) 7043f558af01643787d209a133215b0abec81b5fe30Anna Zaks return false; 7053f558af01643787d209a133215b0abec81b5fe30Anna Zaks 7063f558af01643787d209a133215b0abec81b5fe30Anna Zaks continue; 7073f558af01643787d209a133215b0abec81b5fe30Anna Zaks } 7083f558af01643787d209a133215b0abec81b5fe30Anna Zaks 7093f558af01643787d209a133215b0abec81b5fe30Anna Zaks return false; 7103f558af01643787d209a133215b0abec81b5fe30Anna Zaks }; 7113f558af01643787d209a133215b0abec81b5fe30Anna Zaks 7123f558af01643787d209a133215b0abec81b5fe30Anna Zaks llvm_unreachable("The while loop should always terminate."); 7133f558af01643787d209a133215b0abec81b5fe30Anna Zaks} 7143f558af01643787d209a133215b0abec81b5fe30Anna Zaks 715e90d3f847dcce76237078b67db8895eb7a24189eAnna ZaksRuntimeDefinition ObjCMethodCall::getRuntimeDefinition() const { 7162d18419a7c8f9a2975d4ed74a202de6467308ad1Anna Zaks const ObjCMessageExpr *E = getOriginExpr(); 7172d18419a7c8f9a2975d4ed74a202de6467308ad1Anna Zaks assert(E); 718f0324d33967f28758f7243c7bb1a469c5a0394b6Anna Zaks Selector Sel = E->getSelector(); 7192d18419a7c8f9a2975d4ed74a202de6467308ad1Anna Zaks 7202d18419a7c8f9a2975d4ed74a202de6467308ad1Anna Zaks if (E->isInstanceMessage()) { 721f0324d33967f28758f7243c7bb1a469c5a0394b6Anna Zaks 722f0324d33967f28758f7243c7bb1a469c5a0394b6Anna Zaks // Find the the receiver type. 723f0324d33967f28758f7243c7bb1a469c5a0394b6Anna Zaks const ObjCObjectPointerType *ReceiverT = 0; 724f0324d33967f28758f7243c7bb1a469c5a0394b6Anna Zaks QualType SupersType = E->getSuperType(); 725e90d3f847dcce76237078b67db8895eb7a24189eAnna Zaks const MemRegion *Receiver = 0; 726e90d3f847dcce76237078b67db8895eb7a24189eAnna Zaks 727f0324d33967f28758f7243c7bb1a469c5a0394b6Anna Zaks if (!SupersType.isNull()) { 728e90d3f847dcce76237078b67db8895eb7a24189eAnna Zaks // Super always means the type of immediate predecessor to the method 729e90d3f847dcce76237078b67db8895eb7a24189eAnna Zaks // where the call occurs. 7308ed21ef726be89ef7151b5ff397631379bd8a537Anna Zaks ReceiverT = cast<ObjCObjectPointerType>(SupersType); 731f0324d33967f28758f7243c7bb1a469c5a0394b6Anna Zaks } else { 732e90d3f847dcce76237078b67db8895eb7a24189eAnna Zaks Receiver = getReceiverSVal().getAsRegion(); 7334fe64ad383c056774087113561063429103ac9a6Jordan Rose if (!Receiver) 734e90d3f847dcce76237078b67db8895eb7a24189eAnna Zaks return RuntimeDefinition(); 7354fe64ad383c056774087113561063429103ac9a6Jordan Rose 736c7ecc43c33a21b82c49664910b19fcc1f555aa51Anna Zaks QualType DynType = getState()->getDynamicTypeInfo(Receiver).getType(); 7378ed21ef726be89ef7151b5ff397631379bd8a537Anna Zaks ReceiverT = dyn_cast<ObjCObjectPointerType>(DynType); 7389dc5167e4017ef4c8b327abb6f72225eec2e0f19Anna Zaks } 7399dc5167e4017ef4c8b327abb6f72225eec2e0f19Anna Zaks 740f0324d33967f28758f7243c7bb1a469c5a0394b6Anna Zaks // Lookup the method implementation. 741f0324d33967f28758f7243c7bb1a469c5a0394b6Anna Zaks if (ReceiverT) 7423f558af01643787d209a133215b0abec81b5fe30Anna Zaks if (ObjCInterfaceDecl *IDecl = ReceiverT->getInterfaceDecl()) { 7433f558af01643787d209a133215b0abec81b5fe30Anna Zaks if (canBeOverridenInSubclass(IDecl, Sel)) 7443f558af01643787d209a133215b0abec81b5fe30Anna Zaks return RuntimeDefinition(IDecl->lookupPrivateMethod(Sel), Receiver); 7453f558af01643787d209a133215b0abec81b5fe30Anna Zaks else 7463f558af01643787d209a133215b0abec81b5fe30Anna Zaks return RuntimeDefinition(IDecl->lookupPrivateMethod(Sel), 0); 7473f558af01643787d209a133215b0abec81b5fe30Anna Zaks } 748f0324d33967f28758f7243c7bb1a469c5a0394b6Anna Zaks 7492d18419a7c8f9a2975d4ed74a202de6467308ad1Anna Zaks } else { 7502d18419a7c8f9a2975d4ed74a202de6467308ad1Anna Zaks // This is a class method. 7512d18419a7c8f9a2975d4ed74a202de6467308ad1Anna Zaks // If we have type info for the receiver class, we are calling via 7522d18419a7c8f9a2975d4ed74a202de6467308ad1Anna Zaks // class name. 7532d18419a7c8f9a2975d4ed74a202de6467308ad1Anna Zaks if (ObjCInterfaceDecl *IDecl = E->getReceiverInterface()) { 7542d18419a7c8f9a2975d4ed74a202de6467308ad1Anna Zaks // Find/Return the method implementation. 7555960f4aeac9760198c80e05d70d8dadb1db0ff0eAnna Zaks return RuntimeDefinition(IDecl->lookupPrivateClassMethod(Sel)); 7562d18419a7c8f9a2975d4ed74a202de6467308ad1Anna Zaks } 7579dc5167e4017ef4c8b327abb6f72225eec2e0f19Anna Zaks } 7582d18419a7c8f9a2975d4ed74a202de6467308ad1Anna Zaks 759e90d3f847dcce76237078b67db8895eb7a24189eAnna Zaks return RuntimeDefinition(); 7609dc5167e4017ef4c8b327abb6f72225eec2e0f19Anna Zaks} 7619dc5167e4017ef4c8b327abb6f72225eec2e0f19Anna Zaks 762ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rosevoid ObjCMethodCall::getInitialStackFrameContents( 763ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose const StackFrameContext *CalleeCtx, 764ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose BindingsTy &Bindings) const { 765ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose const ObjCMethodDecl *D = cast<ObjCMethodDecl>(CalleeCtx->getDecl()); 766ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose SValBuilder &SVB = getState()->getStateManager().getSValBuilder(); 767ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose addParameterValuesToBindings(CalleeCtx, Bindings, SVB, *this, 768ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose D->param_begin(), D->param_end()); 769ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose 770ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose SVal SelfVal = getReceiverSVal(); 771ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose if (!SelfVal.isUnknown()) { 772ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose const VarDecl *SelfD = CalleeCtx->getAnalysisDeclContext()->getSelfDecl(); 773ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose MemRegionManager &MRMgr = SVB.getRegionManager(); 774ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose Loc SelfLoc = SVB.makeLoc(MRMgr.getVarRegion(SelfD, CalleeCtx)); 775ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose Bindings.push_back(std::make_pair(SelfLoc, SelfVal)); 776ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose } 777ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose} 778ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose 779d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan RoseCallEventRef<SimpleCall> 780d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan RoseCallEventManager::getSimpleCall(const CallExpr *CE, ProgramStateRef State, 781d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose const LocationContext *LCtx) { 782d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose if (const CXXMemberCallExpr *MCE = dyn_cast<CXXMemberCallExpr>(CE)) 783d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose return create<CXXMemberCall>(MCE, State, LCtx); 784d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose 785d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose if (const CXXOperatorCallExpr *OpCE = dyn_cast<CXXOperatorCallExpr>(CE)) { 786d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose const FunctionDecl *DirectCallee = OpCE->getDirectCallee(); 787d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(DirectCallee)) 788d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose if (MD->isInstance()) 789d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose return create<CXXMemberOperatorCall>(OpCE, State, LCtx); 790d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose 791d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose } else if (CE->getCallee()->getType()->isBlockPointerType()) { 792d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose return create<BlockCall>(CE, State, LCtx); 793d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose } 794d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose 795d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose // Otherwise, it's a normal function call, static member function call, or 796d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose // something we can't reason about. 797d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose return create<FunctionCall>(CE, State, LCtx); 798d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose} 79957c033621dacd8720ac9ff65a09025f14f70e22fJordan Rose 80057c033621dacd8720ac9ff65a09025f14f70e22fJordan Rose 80157c033621dacd8720ac9ff65a09025f14f70e22fJordan RoseCallEventRef<> 80257c033621dacd8720ac9ff65a09025f14f70e22fJordan RoseCallEventManager::getCaller(const StackFrameContext *CalleeCtx, 80357c033621dacd8720ac9ff65a09025f14f70e22fJordan Rose ProgramStateRef State) { 80457c033621dacd8720ac9ff65a09025f14f70e22fJordan Rose const LocationContext *ParentCtx = CalleeCtx->getParent(); 80557c033621dacd8720ac9ff65a09025f14f70e22fJordan Rose const LocationContext *CallerCtx = ParentCtx->getCurrentStackFrame(); 80657c033621dacd8720ac9ff65a09025f14f70e22fJordan Rose assert(CallerCtx && "This should not be used for top-level stack frames"); 80757c033621dacd8720ac9ff65a09025f14f70e22fJordan Rose 80857c033621dacd8720ac9ff65a09025f14f70e22fJordan Rose const Stmt *CallSite = CalleeCtx->getCallSite(); 80957c033621dacd8720ac9ff65a09025f14f70e22fJordan Rose 81057c033621dacd8720ac9ff65a09025f14f70e22fJordan Rose if (CallSite) { 81157c033621dacd8720ac9ff65a09025f14f70e22fJordan Rose if (const CallExpr *CE = dyn_cast<CallExpr>(CallSite)) 81257c033621dacd8720ac9ff65a09025f14f70e22fJordan Rose return getSimpleCall(CE, State, CallerCtx); 81357c033621dacd8720ac9ff65a09025f14f70e22fJordan Rose 81457c033621dacd8720ac9ff65a09025f14f70e22fJordan Rose switch (CallSite->getStmtClass()) { 81557c033621dacd8720ac9ff65a09025f14f70e22fJordan Rose case Stmt::CXXConstructExprClass: { 81657c033621dacd8720ac9ff65a09025f14f70e22fJordan Rose SValBuilder &SVB = State->getStateManager().getSValBuilder(); 81757c033621dacd8720ac9ff65a09025f14f70e22fJordan Rose const CXXMethodDecl *Ctor = cast<CXXMethodDecl>(CalleeCtx->getDecl()); 81857c033621dacd8720ac9ff65a09025f14f70e22fJordan Rose Loc ThisPtr = SVB.getCXXThis(Ctor, CalleeCtx); 81957c033621dacd8720ac9ff65a09025f14f70e22fJordan Rose SVal ThisVal = State->getSVal(ThisPtr); 82057c033621dacd8720ac9ff65a09025f14f70e22fJordan Rose 82157c033621dacd8720ac9ff65a09025f14f70e22fJordan Rose return getCXXConstructorCall(cast<CXXConstructExpr>(CallSite), 82257c033621dacd8720ac9ff65a09025f14f70e22fJordan Rose ThisVal.getAsRegion(), State, CallerCtx); 82357c033621dacd8720ac9ff65a09025f14f70e22fJordan Rose } 82457c033621dacd8720ac9ff65a09025f14f70e22fJordan Rose case Stmt::CXXNewExprClass: 82557c033621dacd8720ac9ff65a09025f14f70e22fJordan Rose return getCXXAllocatorCall(cast<CXXNewExpr>(CallSite), State, CallerCtx); 82657c033621dacd8720ac9ff65a09025f14f70e22fJordan Rose case Stmt::ObjCMessageExprClass: 82757c033621dacd8720ac9ff65a09025f14f70e22fJordan Rose return getObjCMethodCall(cast<ObjCMessageExpr>(CallSite), 82857c033621dacd8720ac9ff65a09025f14f70e22fJordan Rose State, CallerCtx); 82957c033621dacd8720ac9ff65a09025f14f70e22fJordan Rose default: 83057c033621dacd8720ac9ff65a09025f14f70e22fJordan Rose llvm_unreachable("This is not an inlineable statement."); 83157c033621dacd8720ac9ff65a09025f14f70e22fJordan Rose } 83257c033621dacd8720ac9ff65a09025f14f70e22fJordan Rose } 83357c033621dacd8720ac9ff65a09025f14f70e22fJordan Rose 83457c033621dacd8720ac9ff65a09025f14f70e22fJordan Rose // Fall back to the CFG. The only thing we haven't handled yet is 83557c033621dacd8720ac9ff65a09025f14f70e22fJordan Rose // destructors, though this could change in the future. 83657c033621dacd8720ac9ff65a09025f14f70e22fJordan Rose const CFGBlock *B = CalleeCtx->getCallSiteBlock(); 83757c033621dacd8720ac9ff65a09025f14f70e22fJordan Rose CFGElement E = (*B)[CalleeCtx->getIndex()]; 83857c033621dacd8720ac9ff65a09025f14f70e22fJordan Rose assert(isa<CFGImplicitDtor>(E) && "All other CFG elements should have exprs"); 83957c033621dacd8720ac9ff65a09025f14f70e22fJordan Rose assert(!isa<CFGTemporaryDtor>(E) && "We don't handle temporaries yet"); 84057c033621dacd8720ac9ff65a09025f14f70e22fJordan Rose 84157c033621dacd8720ac9ff65a09025f14f70e22fJordan Rose SValBuilder &SVB = State->getStateManager().getSValBuilder(); 84257c033621dacd8720ac9ff65a09025f14f70e22fJordan Rose const CXXDestructorDecl *Dtor = cast<CXXDestructorDecl>(CalleeCtx->getDecl()); 84357c033621dacd8720ac9ff65a09025f14f70e22fJordan Rose Loc ThisPtr = SVB.getCXXThis(Dtor, CalleeCtx); 84457c033621dacd8720ac9ff65a09025f14f70e22fJordan Rose SVal ThisVal = State->getSVal(ThisPtr); 84557c033621dacd8720ac9ff65a09025f14f70e22fJordan Rose 84657c033621dacd8720ac9ff65a09025f14f70e22fJordan Rose const Stmt *Trigger; 84757c033621dacd8720ac9ff65a09025f14f70e22fJordan Rose if (const CFGAutomaticObjDtor *AutoDtor = dyn_cast<CFGAutomaticObjDtor>(&E)) 84857c033621dacd8720ac9ff65a09025f14f70e22fJordan Rose Trigger = AutoDtor->getTriggerStmt(); 84957c033621dacd8720ac9ff65a09025f14f70e22fJordan Rose else 85057c033621dacd8720ac9ff65a09025f14f70e22fJordan Rose Trigger = Dtor->getBody(); 85157c033621dacd8720ac9ff65a09025f14f70e22fJordan Rose 85257c033621dacd8720ac9ff65a09025f14f70e22fJordan Rose return getCXXDestructorCall(Dtor, Trigger, ThisVal.getAsRegion(), 85357c033621dacd8720ac9ff65a09025f14f70e22fJordan Rose State, CallerCtx); 85457c033621dacd8720ac9ff65a09025f14f70e22fJordan Rose} 85557c033621dacd8720ac9ff65a09025f14f70e22fJordan Rose 856