RetainCountChecker.cpp revision f05aac8472d8ed081a361a218fd14d59ddc91b85
15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//==-- RetainCountChecker.cpp - Checks for leaks and other issues -*- C++ -*--// 25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// 35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// The LLVM Compiler Infrastructure 45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// 55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// This file is distributed under the University of Illinois Open Source 65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// License. See LICENSE.TXT for details. 75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// 85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//===----------------------------------------------------------------------===// 95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// 105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// This file defines the methods for RetainCountChecker, which implements 115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// a reference count checker for Core Foundation and Cocoa on (Mac OS X). 125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// 135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//===----------------------------------------------------------------------===// 145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "ClangSACheckers.h" 165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "clang/AST/DeclObjC.h" 175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "clang/AST/DeclCXX.h" 185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "clang/Basic/LangOptions.h" 195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "clang/Basic/SourceManager.h" 205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "clang/Analysis/DomainSpecific/CocoaConventions.h" 215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "clang/StaticAnalyzer/Core/Checker.h" 2253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "clang/StaticAnalyzer/Core/CheckerManager.h" 235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" 2453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h" 25d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" 261e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngineBuilders.h" 27d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h" 285d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)#include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h" 295d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)#include "clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h" 3053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "llvm/ADT/DenseMap.h" 31591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#include "llvm/ADT/FoldingSet.h" 32591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#include "llvm/ADT/ImmutableList.h" 33591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#include "llvm/ADT/ImmutableMap.h" 345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "llvm/ADT/STLExtras.h" 355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "llvm/ADT/StringExtras.h" 365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include <cstdarg> 37c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) 385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)using namespace clang; 3909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)using namespace ento; 4009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)using llvm::StrInStrNoCase; 41197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 4209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)namespace { 4309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)/// Wrapper around different kinds of node builder, so that helper functions 4409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)/// can have a common interface. 45d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)class GenericNodeBuilderRefCount { 4609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) CheckerContext *C; 4709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) const ProgramPointTag *tag; 4809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) EndOfFunctionNodeBuilder *ENB; 4909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)public: 5009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) GenericNodeBuilderRefCount(CheckerContext &c, 515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const ProgramPointTag *t) 525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) : C(&c), tag(t), ENB(0) {} 537242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 54d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) GenericNodeBuilderRefCount(EndOfFunctionNodeBuilder &enb) 555d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) : C(0), tag(0), ENB(&enb) {} 565d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) 575d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) ExplodedNode *MakeNode(const ProgramState *state, ExplodedNode *Pred, 585d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) bool MarkAsSink = false) { 595d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) if (C) { 605d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) return C->generateNode(state, Pred, tag, false, MarkAsSink); 617242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci } 625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) assert(ENB); 64a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch ExplodedNode *N = ENB->generateNode(state, Pred); 655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (MarkAsSink) 665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) N->markAsSink(); 675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return N; 695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}; 715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} // end anonymous namespace 72a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch 735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//===----------------------------------------------------------------------===// 745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// Primitives used for constructing summaries for function/method calls. 755d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)//===----------------------------------------------------------------------===// 7602772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 77d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)/// ArgEffect is used to summarize a function/method call's effect on a 7809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)/// particular argument. 795d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)enum ArgEffect { DoNothing, Autorelease, Dealloc, DecRef, DecRefMsg, 805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DecRefBridgedTransfered, 815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) IncRefMsg, IncRef, MakeCollectable, MayEscape, 825d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) NewAutoreleasePool, SelfOwn, StopTracking }; 835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 8409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)namespace llvm { 8509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template <> struct FoldingSetTrait<ArgEffect> { 8609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)static inline void Profile(const ArgEffect X, FoldingSetNodeID& ID) { 87d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) ID.AddInteger((unsigned) X); 885d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)} 895d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)}; 907242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci} // end llvm namespace 915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/// ArgEffects summarizes the effects of a function/method call on all of 935d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)/// its arguments. 945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)typedef llvm::ImmutableMap<unsigned,ArgEffect> ArgEffects; 95d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) 9609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)namespace { 975d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) 9809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)/// RetEffect is used to summarize a function/method call's behavior with 995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/// respect to its return value. 1005d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)class RetEffect { 10109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)public: 102d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) enum Kind { NoRet, OwnedSymbol, OwnedAllocatedSymbol, 10309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) NotOwnedSymbol, GCNotOwnedSymbol, ARCNotOwnedSymbol, 1045d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) OwnedWhenTrackedReceiver }; 10509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) enum ObjKind { CF, ObjC, AnyObj }; 1075d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) 10809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)private: 109d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) Kind K; 11009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) ObjKind O; 1115d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) 11209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) RetEffect(Kind k, ObjKind o = AnyObj) : K(k), O(o) {} 1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1145d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)public: 11509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) Kind getKind() const { return K; } 116d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) 11709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) ObjKind getObjKind() const { return O; } 1185d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) 1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool isOwned() const { 1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return K == OwnedSymbol || K == OwnedAllocatedSymbol || 12107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch K == OwnedWhenTrackedReceiver; 12207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch } 1235d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) 12407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch bool operator==(const RetEffect &Other) const { 12507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch return K == Other.K && O == Other.O; 12607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch } 12707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 12807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch static RetEffect MakeOwnedWhenTrackedReceiver() { 12907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch return RetEffect(OwnedWhenTrackedReceiver, ObjC); 1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 13207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch static RetEffect MakeOwned(ObjKind o, bool isAllocated = false) { 1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return RetEffect(isAllocated ? OwnedAllocatedSymbol : OwnedSymbol, o); 1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) static RetEffect MakeNotOwned(ObjKind o) { 1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return RetEffect(NotOwnedSymbol, o); 1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) static RetEffect MakeGCNotOwned() { 1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return RetEffect(GCNotOwnedSymbol, ObjC); 1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) static RetEffect MakeARCNotOwned() { 1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return RetEffect(ARCNotOwnedSymbol, ObjC); 1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) static RetEffect MakeNoRet() { 1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return RetEffect(NoRet); 1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1475d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)}; 1485d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) 1495d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)//===----------------------------------------------------------------------===// 150f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)// Reference-counting logic (typestate + counts). 1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//===----------------------------------------------------------------------===// 1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class RefVal { 1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)public: 1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) enum Kind { 1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Owned = 0, // Owning reference. 157f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) NotOwned, // Reference is not owned by still valid (not freed). 158f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) Released, // Object has been released. 1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ReturnedOwned, // Returned object passes ownership to caller. 1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ReturnedNotOwned, // Return object does not pass ownership to caller. 1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ERROR_START, 1625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ErrorDeallocNotOwned, // -dealloc called on non-owned object. 163f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) ErrorDeallocGC, // Calling -dealloc with GC enabled. 1645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ErrorUseAfterRelease, // Object used after released. 1655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ErrorReleaseNotOwned, // Release of an object that was not owned. 1665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ERROR_LEAK_START, 16709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) ErrorLeak, // A memory leak due to excessive reference counts. 1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ErrorLeakReturned, // A memory leak due to the returning method not having 1695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // the correct naming conventions. 1705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ErrorGCLeakReturned, 1715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ErrorOverAutorelease, 1725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ErrorReturnedNotOwned 1735d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) }; 1745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1755d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)private: 1765d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) Kind kind; 177d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) RetEffect::ObjKind okind; 1785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned Cnt; 1795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned ACnt; 1805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) QualType T; 1815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1825d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) RefVal(Kind k, RetEffect::ObjKind o, unsigned cnt, unsigned acnt, QualType t) 1835d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) : kind(k), okind(o), Cnt(cnt), ACnt(acnt), T(t) {} 1845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)public: 1865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Kind getKind() const { return kind; } 1875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RetEffect::ObjKind getObjKind() const { return okind; } 1895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned getCount() const { return Cnt; } 1915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned getAutoreleaseCount() const { return ACnt; } 1925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned getCombinedCounts() const { return Cnt + ACnt; } 1935d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) void clearCounts() { Cnt = 0; ACnt = 0; } 1945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void setCount(unsigned i) { Cnt = i; } 1955d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) void setAutoreleaseCount(unsigned i) { ACnt = i; } 1965d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) 1975d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) QualType getType() const { return T; } 198d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) 1995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool isOwned() const { 2005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return getKind() == Owned; 2015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2025d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) 2035d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) bool isNotOwned() const { 2045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return getKind() == NotOwned; 2055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool isReturnedOwned() const { 2085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return getKind() == ReturnedOwned; 2095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool isReturnedNotOwned() const { 2125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return getKind() == ReturnedNotOwned; 2135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2145d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) 2155d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) static RefVal makeOwned(RetEffect::ObjKind o, QualType t, 2165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned Count = 1) { 2175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return RefVal(Owned, o, Count, 0, t); 2185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) static RefVal makeNotOwned(RetEffect::ObjKind o, QualType t, 2215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned Count = 0) { 2225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return RefVal(NotOwned, o, Count, 0, t); 2235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 22409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 225d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) // Comparison, profiling, and pretty-printing. 2265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool operator==(const RefVal& X) const { 2285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return kind == X.kind && Cnt == X.Cnt && T == X.T && ACnt == X.ACnt; 22909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) } 23009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 23109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) RefVal operator-(size_t i) const { 23209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return RefVal(getKind(), getObjKind(), getCount() - i, 23309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) getAutoreleaseCount(), getType()); 2345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RefVal operator+(size_t i) const { 2375d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) return RefVal(getKind(), getObjKind(), getCount() + i, 2385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) getAutoreleaseCount(), getType()); 2395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RefVal operator^(Kind k) const { 2425d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) return RefVal(k, getObjKind(), getCount(), getAutoreleaseCount(), 2435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) getType()); 2445d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) } 24507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 2465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RefVal autorelease() const { 2475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return RefVal(getKind(), getObjKind(), getCount(), getAutoreleaseCount()+1, 2485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) getType()); 2495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2505d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) 2515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void Profile(llvm::FoldingSetNodeID& ID) const { 2525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ID.AddInteger((unsigned) kind); 2535d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) ID.AddInteger(Cnt); 25402772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch ID.AddInteger(ACnt); 2555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ID.Add(T); 2565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 25702772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 2585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void print(raw_ostream &Out) const; 2597242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci}; 2605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RefVal::print(raw_ostream &Out) const { 2625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!T.isNull()) 2635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Out << "Tracked " << T.getAsString() << '/'; 2645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) switch (getKind()) { 2665d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) default: llvm_unreachable("Invalid RefVal kind"); 26707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch case Owned: { 2685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Out << "Owned"; 2695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned cnt = getCount(); 2705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (cnt) Out << " (+ " << cnt << ")"; 2715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 2725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case NotOwned: { 2755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Out << "NotOwned"; 2765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned cnt = getCount(); 2775d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) if (cnt) Out << " (+ " << cnt << ")"; 27807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch break; 2795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case ReturnedOwned: { 2825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Out << "ReturnedOwned"; 283d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) unsigned cnt = getCount(); 2845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (cnt) Out << " (+ " << cnt << ")"; 2855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 2865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2885d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) case ReturnedNotOwned: { 28907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch Out << "ReturnedNotOwned"; 2905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned cnt = getCount(); 2915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (cnt) Out << " (+ " << cnt << ")"; 2925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 2935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case Released: 2965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Out << "Released"; 2975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 2985d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) 2995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case ErrorDeallocGC: 3005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Out << "-dealloc (GC)"; 3015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 3025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case ErrorDeallocNotOwned: 3045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Out << "-dealloc (not-owned)"; 3055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 3065d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) 3075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case ErrorLeak: 3085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Out << "Leaked"; 3095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 3105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case ErrorLeakReturned: 3125d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) Out << "Leaked (Bad naming)"; 3135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 3145d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) 3155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case ErrorGCLeakReturned: 316f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) Out << "Leaked (GC-ed at return)"; 3175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 3185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case ErrorUseAfterRelease: 3205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Out << "Use-After-Release [ERROR]"; 3215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 3225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3235d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) case ErrorReleaseNotOwned: 3245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Out << "Release of Not-Owned [ERROR]"; 325f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) break; 3265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case RefVal::ErrorOverAutorelease: 3285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Out << "Over autoreleased"; 3295d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) break; 330f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) 331f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) case RefVal::ErrorReturnedNotOwned: 3325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Out << "Non-owned object returned instead of owned"; 3335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 334f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) } 3355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (ACnt) { 3375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Out << " [ARC +" << ACnt << ']'; 338f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) } 3395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} //end anonymous namespace 3415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//===----------------------------------------------------------------------===// 3435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// RefBindings - State used to track object reference counts. 3445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//===----------------------------------------------------------------------===// 3455d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) 3465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)typedef llvm::ImmutableMap<SymbolRef, RefVal> RefBindings; 3475d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) 3485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace clang { 3495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace ento { 3505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)template<> 3515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)struct ProgramStateTrait<RefBindings> 3525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) : public ProgramStatePartialTrait<RefBindings> { 3535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) static void *GDMIndex() { 3545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) static int RefBIndex = 0; 3555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return &RefBIndex; 3565d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) } 3575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}; 3585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3605d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) 361f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)//===----------------------------------------------------------------------===// 3625d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)// Function/Method behavior summaries. 3635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//===----------------------------------------------------------------------===// 36402772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 3655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace { 3665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class RetainSummary { 3675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) /// Args - an ordered vector of (index, ArgEffect) pairs, where index 3685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) /// specifies the argument (starting from 0). This can be sparsely 3695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) /// populated; arguments with no entry in Args use 'DefaultArgEffect'. 3705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ArgEffects Args; 3715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) /// DefaultArgEffect - The default ArgEffect to apply to arguments that 3735d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) /// do not have an entry in Args. 3745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ArgEffect DefaultArgEffect; 3755d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) 3765d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) /// Receiver - If this summary applies to an Objective-C message expression, 3775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) /// this is the effect applied to the state of the receiver. 3785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ArgEffect Receiver; 3795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) /// Ret - The effect on the return value. Used to indicate if the 3815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) /// function/method call returns a new tracked symbol. 3827242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci RetEffect Ret; 3837242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 3847242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccipublic: 3857242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci RetainSummary(ArgEffects A, RetEffect R, ArgEffect defaultEff, 3867242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci ArgEffect ReceiverEff) 387c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) : Args(A), DefaultArgEffect(defaultEff), Receiver(ReceiverEff), Ret(R) {} 3885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) /// getArg - Return the argument effect on the argument specified by 3905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) /// idx (starting from 0). 3915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ArgEffect getArg(unsigned idx) const { 3925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (const ArgEffect *AE = Args.lookup(idx)) 3935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return *AE; 3945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return DefaultArgEffect; 3965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 397c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) 3985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void addArg(ArgEffects::Factory &af, unsigned idx, ArgEffect e) { 3995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Args = af.add(Args, idx, e); 4005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) /// setDefaultArgEffect - Set the default argument effect. 4035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void setDefaultArgEffect(ArgEffect E) { 4045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DefaultArgEffect = E; 405c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) } 4065d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) 4075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) /// getRetEffect - Returns the effect on the return value of the call. 408f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles) RetEffect getRetEffect() const { return Ret; } 4095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) /// setRetEffect - Set the effect of the return value of the call. 4115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void setRetEffect(RetEffect E) { Ret = E; } 4125d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) 4135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4145d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) /// Sets the effect on the receiver of the message. 4155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void setReceiverEffect(ArgEffect e) { Receiver = e; } 416c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) 4175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) /// getReceiverEffect - Returns the effect on the receiver of the call. 4185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) /// This is only meaningful if the summary applies to an ObjCMessageExpr*. 4195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ArgEffect getReceiverEffect() const { return Receiver; } 420c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) 4215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) /// Test if two retain summaries are identical. Note that merely equivalent 4225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) /// summaries are not necessarily identical (for example, if an explicit 4235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) /// argument effect matches the default effect). 4245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool operator==(const RetainSummary &Other) const { 4255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return Args == Other.Args && DefaultArgEffect == Other.DefaultArgEffect && 4265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Receiver == Other.Receiver && Ret == Other.Ret; 427f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) } 4285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}; 4295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} // end anonymous namespace 4305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 431//===----------------------------------------------------------------------===// 432// Data structures for constructing summaries. 433//===----------------------------------------------------------------------===// 434 435namespace { 436class ObjCSummaryKey { 437 IdentifierInfo* II; 438 Selector S; 439public: 440 ObjCSummaryKey(IdentifierInfo* ii, Selector s) 441 : II(ii), S(s) {} 442 443 ObjCSummaryKey(const ObjCInterfaceDecl *d, Selector s) 444 : II(d ? d->getIdentifier() : 0), S(s) {} 445 446 ObjCSummaryKey(const ObjCInterfaceDecl *d, IdentifierInfo *ii, Selector s) 447 : II(d ? d->getIdentifier() : ii), S(s) {} 448 449 ObjCSummaryKey(Selector s) 450 : II(0), S(s) {} 451 452 IdentifierInfo* getIdentifier() const { return II; } 453 Selector getSelector() const { return S; } 454}; 455} 456 457namespace llvm { 458template <> struct DenseMapInfo<ObjCSummaryKey> { 459 static inline ObjCSummaryKey getEmptyKey() { 460 return ObjCSummaryKey(DenseMapInfo<IdentifierInfo*>::getEmptyKey(), 461 DenseMapInfo<Selector>::getEmptyKey()); 462 } 463 464 static inline ObjCSummaryKey getTombstoneKey() { 465 return ObjCSummaryKey(DenseMapInfo<IdentifierInfo*>::getTombstoneKey(), 466 DenseMapInfo<Selector>::getTombstoneKey()); 467 } 468 469 static unsigned getHashValue(const ObjCSummaryKey &V) { 470 return (DenseMapInfo<IdentifierInfo*>::getHashValue(V.getIdentifier()) 471 & 0x88888888) 472 | (DenseMapInfo<Selector>::getHashValue(V.getSelector()) 473 & 0x55555555); 474 } 475 476 static bool isEqual(const ObjCSummaryKey& LHS, const ObjCSummaryKey& RHS) { 477 return DenseMapInfo<IdentifierInfo*>::isEqual(LHS.getIdentifier(), 478 RHS.getIdentifier()) && 479 DenseMapInfo<Selector>::isEqual(LHS.getSelector(), 480 RHS.getSelector()); 481 } 482 483}; 484template <> 485struct isPodLike<ObjCSummaryKey> { static const bool value = true; }; 486} // end llvm namespace 487 488namespace { 489class ObjCSummaryCache { 490 typedef llvm::DenseMap<ObjCSummaryKey, const RetainSummary *> MapTy; 491 MapTy M; 492public: 493 ObjCSummaryCache() {} 494 495 const RetainSummary * find(const ObjCInterfaceDecl *D, IdentifierInfo *ClsName, 496 Selector S) { 497 // Lookup the method using the decl for the class @interface. If we 498 // have no decl, lookup using the class name. 499 return D ? find(D, S) : find(ClsName, S); 500 } 501 502 const RetainSummary * find(const ObjCInterfaceDecl *D, Selector S) { 503 // Do a lookup with the (D,S) pair. If we find a match return 504 // the iterator. 505 ObjCSummaryKey K(D, S); 506 MapTy::iterator I = M.find(K); 507 508 if (I != M.end() || !D) 509 return I->second; 510 511 // Walk the super chain. If we find a hit with a parent, we'll end 512 // up returning that summary. We actually allow that key (null,S), as 513 // we cache summaries for the null ObjCInterfaceDecl* to allow us to 514 // generate initial summaries without having to worry about NSObject 515 // being declared. 516 // FIXME: We may change this at some point. 517 for (ObjCInterfaceDecl *C=D->getSuperClass() ;; C=C->getSuperClass()) { 518 if ((I = M.find(ObjCSummaryKey(C, S))) != M.end()) 519 break; 520 521 if (!C) 522 return NULL; 523 } 524 525 // Cache the summary with original key to make the next lookup faster 526 // and return the iterator. 527 const RetainSummary *Summ = I->second; 528 M[K] = Summ; 529 return Summ; 530 } 531 532 const RetainSummary * find(IdentifierInfo* II, Selector S) { 533 // FIXME: Class method lookup. Right now we dont' have a good way 534 // of going between IdentifierInfo* and the class hierarchy. 535 MapTy::iterator I = M.find(ObjCSummaryKey(II, S)); 536 537 if (I == M.end()) 538 I = M.find(ObjCSummaryKey(S)); 539 540 return I == M.end() ? NULL : I->second; 541 } 542 543 const RetainSummary *& operator[](ObjCSummaryKey K) { 544 return M[K]; 545 } 546 547 const RetainSummary *& operator[](Selector S) { 548 return M[ ObjCSummaryKey(S) ]; 549 } 550}; 551} // end anonymous namespace 552 553//===----------------------------------------------------------------------===// 554// Data structures for managing collections of summaries. 555//===----------------------------------------------------------------------===// 556 557namespace { 558class RetainSummaryManager { 559 560 //==-----------------------------------------------------------------==// 561 // Typedefs. 562 //==-----------------------------------------------------------------==// 563 564 typedef llvm::DenseMap<const FunctionDecl*, const RetainSummary *> 565 FuncSummariesTy; 566 567 typedef ObjCSummaryCache ObjCMethodSummariesTy; 568 569 //==-----------------------------------------------------------------==// 570 // Data. 571 //==-----------------------------------------------------------------==// 572 573 /// Ctx - The ASTContext object for the analyzed ASTs. 574 ASTContext &Ctx; 575 576 /// GCEnabled - Records whether or not the analyzed code runs in GC mode. 577 const bool GCEnabled; 578 579 /// Records whether or not the analyzed code runs in ARC mode. 580 const bool ARCEnabled; 581 582 /// FuncSummaries - A map from FunctionDecls to summaries. 583 FuncSummariesTy FuncSummaries; 584 585 /// ObjCClassMethodSummaries - A map from selectors (for instance methods) 586 /// to summaries. 587 ObjCMethodSummariesTy ObjCClassMethodSummaries; 588 589 /// ObjCMethodSummaries - A map from selectors to summaries. 590 ObjCMethodSummariesTy ObjCMethodSummaries; 591 592 /// BPAlloc - A BumpPtrAllocator used for allocating summaries, ArgEffects, 593 /// and all other data used by the checker. 594 llvm::BumpPtrAllocator BPAlloc; 595 596 /// AF - A factory for ArgEffects objects. 597 ArgEffects::Factory AF; 598 599 /// ScratchArgs - A holding buffer for construct ArgEffects. 600 ArgEffects ScratchArgs; 601 602 /// ObjCAllocRetE - Default return effect for methods returning Objective-C 603 /// objects. 604 RetEffect ObjCAllocRetE; 605 606 /// ObjCInitRetE - Default return effect for init methods returning 607 /// Objective-C objects. 608 RetEffect ObjCInitRetE; 609 610 RetainSummary DefaultSummary; 611 const RetainSummary *StopSummary; 612 613 //==-----------------------------------------------------------------==// 614 // Methods. 615 //==-----------------------------------------------------------------==// 616 617 /// getArgEffects - Returns a persistent ArgEffects object based on the 618 /// data in ScratchArgs. 619 ArgEffects getArgEffects(); 620 621 enum UnaryFuncKind { cfretain, cfrelease, cfmakecollectable }; 622 623public: 624 RetEffect getObjAllocRetEffect() const { return ObjCAllocRetE; } 625 626 const RetainSummary *getDefaultSummary() { 627 return &DefaultSummary; 628 } 629 630 const RetainSummary * getUnarySummary(const FunctionType* FT, 631 UnaryFuncKind func); 632 633 const RetainSummary * getCFSummaryCreateRule(const FunctionDecl *FD); 634 const RetainSummary * getCFSummaryGetRule(const FunctionDecl *FD); 635 const RetainSummary * getCFCreateGetRuleSummary(const FunctionDecl *FD); 636 637 const RetainSummary * getPersistentSummary(ArgEffects AE, RetEffect RetEff, 638 ArgEffect ReceiverEff = DoNothing, 639 ArgEffect DefaultEff = MayEscape); 640 641 const RetainSummary * getPersistentSummary(RetEffect RE, 642 ArgEffect ReceiverEff = DoNothing, 643 ArgEffect DefaultEff = MayEscape) { 644 return getPersistentSummary(getArgEffects(), RE, ReceiverEff, DefaultEff); 645 } 646 647 const RetainSummary *getPersistentStopSummary() { 648 if (StopSummary) 649 return StopSummary; 650 651 StopSummary = getPersistentSummary(RetEffect::MakeNoRet(), 652 StopTracking, StopTracking); 653 654 return StopSummary; 655 } 656 657 const RetainSummary *getInitMethodSummary(QualType RetTy); 658 659 void InitializeClassMethodSummaries(); 660 void InitializeMethodSummaries(); 661private: 662 void addNSObjectClsMethSummary(Selector S, const RetainSummary *Summ) { 663 ObjCClassMethodSummaries[S] = Summ; 664 } 665 666 void addNSObjectMethSummary(Selector S, const RetainSummary *Summ) { 667 ObjCMethodSummaries[S] = Summ; 668 } 669 670 void addClassMethSummary(const char* Cls, const char* nullaryName, 671 const RetainSummary *Summ) { 672 IdentifierInfo* ClsII = &Ctx.Idents.get(Cls); 673 Selector S = GetNullarySelector(nullaryName, Ctx); 674 ObjCClassMethodSummaries[ObjCSummaryKey(ClsII, S)] = Summ; 675 } 676 677 void addInstMethSummary(const char* Cls, const char* nullaryName, 678 const RetainSummary *Summ) { 679 IdentifierInfo* ClsII = &Ctx.Idents.get(Cls); 680 Selector S = GetNullarySelector(nullaryName, Ctx); 681 ObjCMethodSummaries[ObjCSummaryKey(ClsII, S)] = Summ; 682 } 683 684 Selector generateSelector(va_list argp) { 685 SmallVector<IdentifierInfo*, 10> II; 686 687 while (const char* s = va_arg(argp, const char*)) 688 II.push_back(&Ctx.Idents.get(s)); 689 690 return Ctx.Selectors.getSelector(II.size(), &II[0]); 691 } 692 693 void addMethodSummary(IdentifierInfo *ClsII, ObjCMethodSummariesTy& Summaries, 694 const RetainSummary * Summ, va_list argp) { 695 Selector S = generateSelector(argp); 696 Summaries[ObjCSummaryKey(ClsII, S)] = Summ; 697 } 698 699 void addInstMethSummary(const char* Cls, const RetainSummary * Summ, ...) { 700 va_list argp; 701 va_start(argp, Summ); 702 addMethodSummary(&Ctx.Idents.get(Cls), ObjCMethodSummaries, Summ, argp); 703 va_end(argp); 704 } 705 706 void addClsMethSummary(const char* Cls, const RetainSummary * Summ, ...) { 707 va_list argp; 708 va_start(argp, Summ); 709 addMethodSummary(&Ctx.Idents.get(Cls),ObjCClassMethodSummaries, Summ, argp); 710 va_end(argp); 711 } 712 713 void addClsMethSummary(IdentifierInfo *II, const RetainSummary * Summ, ...) { 714 va_list argp; 715 va_start(argp, Summ); 716 addMethodSummary(II, ObjCClassMethodSummaries, Summ, argp); 717 va_end(argp); 718 } 719 720public: 721 722 RetainSummaryManager(ASTContext &ctx, bool gcenabled, bool usesARC) 723 : Ctx(ctx), 724 GCEnabled(gcenabled), 725 ARCEnabled(usesARC), 726 AF(BPAlloc), ScratchArgs(AF.getEmptyMap()), 727 ObjCAllocRetE(gcenabled 728 ? RetEffect::MakeGCNotOwned() 729 : (usesARC ? RetEffect::MakeARCNotOwned() 730 : RetEffect::MakeOwned(RetEffect::ObjC, true))), 731 ObjCInitRetE(gcenabled 732 ? RetEffect::MakeGCNotOwned() 733 : (usesARC ? RetEffect::MakeARCNotOwned() 734 : RetEffect::MakeOwnedWhenTrackedReceiver())), 735 DefaultSummary(AF.getEmptyMap() /* per-argument effects (none) */, 736 RetEffect::MakeNoRet() /* return effect */, 737 MayEscape, /* default argument effect */ 738 DoNothing /* receiver effect */), 739 StopSummary(0) { 740 741 InitializeClassMethodSummaries(); 742 InitializeMethodSummaries(); 743 } 744 745 const RetainSummary * getSummary(const FunctionDecl *FD); 746 747 const RetainSummary *getInstanceMethodSummary(const ObjCMessage &msg, 748 const ProgramState *state, 749 const LocationContext *LC); 750 751 const RetainSummary * getInstanceMethodSummary(const ObjCMessage &msg, 752 const ObjCInterfaceDecl *ID) { 753 return getInstanceMethodSummary(msg.getSelector(), 0, 754 ID, msg.getMethodDecl(), msg.getType(Ctx)); 755 } 756 757 const RetainSummary * getInstanceMethodSummary(Selector S, 758 IdentifierInfo *ClsName, 759 const ObjCInterfaceDecl *ID, 760 const ObjCMethodDecl *MD, 761 QualType RetTy); 762 763 const RetainSummary *getClassMethodSummary(Selector S, 764 IdentifierInfo *ClsName, 765 const ObjCInterfaceDecl *ID, 766 const ObjCMethodDecl *MD, 767 QualType RetTy); 768 769 const RetainSummary *getClassMethodSummary(const ObjCMessage &msg) { 770 const ObjCInterfaceDecl *Class = 0; 771 if (!msg.isInstanceMessage()) 772 Class = msg.getReceiverInterface(); 773 774 return getClassMethodSummary(msg.getSelector(), 775 Class? Class->getIdentifier() : 0, 776 Class, 777 msg.getMethodDecl(), msg.getType(Ctx)); 778 } 779 780 /// getMethodSummary - This version of getMethodSummary is used to query 781 /// the summary for the current method being analyzed. 782 const RetainSummary *getMethodSummary(const ObjCMethodDecl *MD) { 783 // FIXME: Eventually this should be unneeded. 784 const ObjCInterfaceDecl *ID = MD->getClassInterface(); 785 Selector S = MD->getSelector(); 786 IdentifierInfo *ClsName = ID->getIdentifier(); 787 QualType ResultTy = MD->getResultType(); 788 789 if (MD->isInstanceMethod()) 790 return getInstanceMethodSummary(S, ClsName, ID, MD, ResultTy); 791 else 792 return getClassMethodSummary(S, ClsName, ID, MD, ResultTy); 793 } 794 795 const RetainSummary * getCommonMethodSummary(const ObjCMethodDecl *MD, 796 Selector S, QualType RetTy); 797 798 void updateSummaryFromAnnotations(const RetainSummary *&Summ, 799 const ObjCMethodDecl *MD); 800 801 void updateSummaryFromAnnotations(const RetainSummary *&Summ, 802 const FunctionDecl *FD); 803 804 bool isGCEnabled() const { return GCEnabled; } 805 806 bool isARCEnabled() const { return ARCEnabled; } 807 808 bool isARCorGCEnabled() const { return GCEnabled || ARCEnabled; } 809 810 const RetainSummary *copySummary(const RetainSummary *OldSumm) { 811 RetainSummary *Summ = (RetainSummary *) BPAlloc.Allocate<RetainSummary>(); 812 new (Summ) RetainSummary(*OldSumm); 813 return Summ; 814 } 815}; 816 817// Used to avoid allocating long-term (BPAlloc'd) memory for default retain 818// summaries. If a function or method looks like it has a default summary, but 819// it has annotations, the annotations are added to the stack-based template 820// and then copied into managed memory. 821class RetainSummaryTemplate { 822 RetainSummaryManager &Manager; 823 const RetainSummary *&RealSummary; 824 const RetainSummary *BaseSummary; 825 RetainSummary ScratchSummary; 826 bool Accessed; 827public: 828 RetainSummaryTemplate(const RetainSummary *&real, const RetainSummary &base, 829 RetainSummaryManager &manager) 830 : Manager(manager), 831 RealSummary(real), 832 BaseSummary(&base), 833 ScratchSummary(base), 834 Accessed(false) {} 835 836 ~RetainSummaryTemplate() { 837 if (Accessed) 838 RealSummary = Manager.copySummary(&ScratchSummary); 839 else if (!RealSummary) 840 RealSummary = BaseSummary; 841 } 842 843 RetainSummary &operator*() { 844 Accessed = true; 845 return ScratchSummary; 846 } 847 848 RetainSummary *operator->() { 849 Accessed = true; 850 return &ScratchSummary; 851 } 852}; 853 854} // end anonymous namespace 855 856//===----------------------------------------------------------------------===// 857// Implementation of checker data structures. 858//===----------------------------------------------------------------------===// 859 860ArgEffects RetainSummaryManager::getArgEffects() { 861 ArgEffects AE = ScratchArgs; 862 ScratchArgs = AF.getEmptyMap(); 863 return AE; 864} 865 866const RetainSummary * 867RetainSummaryManager::getPersistentSummary(ArgEffects AE, RetEffect RetEff, 868 ArgEffect ReceiverEff, 869 ArgEffect DefaultEff) { 870 // Create the summary and return it. 871 RetainSummary *Summ = (RetainSummary *) BPAlloc.Allocate<RetainSummary>(); 872 new (Summ) RetainSummary(AE, RetEff, DefaultEff, ReceiverEff); 873 return Summ; 874} 875 876//===----------------------------------------------------------------------===// 877// Summary creation for functions (largely uses of Core Foundation). 878//===----------------------------------------------------------------------===// 879 880static bool isRetain(const FunctionDecl *FD, StringRef FName) { 881 return FName.endswith("Retain"); 882} 883 884static bool isRelease(const FunctionDecl *FD, StringRef FName) { 885 return FName.endswith("Release"); 886} 887 888static bool isMakeCollectable(const FunctionDecl *FD, StringRef FName) { 889 // FIXME: Remove FunctionDecl parameter. 890 // FIXME: Is it really okay if MakeCollectable isn't a suffix? 891 return FName.find("MakeCollectable") != StringRef::npos; 892} 893 894const RetainSummary * RetainSummaryManager::getSummary(const FunctionDecl *FD) { 895 // Look up a summary in our cache of FunctionDecls -> Summaries. 896 FuncSummariesTy::iterator I = FuncSummaries.find(FD); 897 if (I != FuncSummaries.end()) 898 return I->second; 899 900 // No summary? Generate one. 901 const RetainSummary *S = 0; 902 903 do { 904 // We generate "stop" summaries for implicitly defined functions. 905 if (FD->isImplicit()) { 906 S = getPersistentStopSummary(); 907 break; 908 } 909 // For C++ methods, generate an implicit "stop" summary as well. We 910 // can relax this once we have a clear policy for C++ methods and 911 // ownership attributes. 912 if (isa<CXXMethodDecl>(FD)) { 913 S = getPersistentStopSummary(); 914 break; 915 } 916 917 // [PR 3337] Use 'getAs<FunctionType>' to strip away any typedefs on the 918 // function's type. 919 const FunctionType* FT = FD->getType()->getAs<FunctionType>(); 920 const IdentifierInfo *II = FD->getIdentifier(); 921 if (!II) 922 break; 923 924 StringRef FName = II->getName(); 925 926 // Strip away preceding '_'. Doing this here will effect all the checks 927 // down below. 928 FName = FName.substr(FName.find_first_not_of('_')); 929 930 // Inspect the result type. 931 QualType RetTy = FT->getResultType(); 932 933 // FIXME: This should all be refactored into a chain of "summary lookup" 934 // filters. 935 assert(ScratchArgs.isEmpty()); 936 937 if (FName == "pthread_create") { 938 // Part of: <rdar://problem/7299394>. This will be addressed 939 // better with IPA. 940 S = getPersistentStopSummary(); 941 } else if (FName == "NSMakeCollectable") { 942 // Handle: id NSMakeCollectable(CFTypeRef) 943 S = (RetTy->isObjCIdType()) 944 ? getUnarySummary(FT, cfmakecollectable) 945 : getPersistentStopSummary(); 946 } else if (FName == "IOBSDNameMatching" || 947 FName == "IOServiceMatching" || 948 FName == "IOServiceNameMatching" || 949 FName == "IORegistryEntryIDMatching" || 950 FName == "IOOpenFirmwarePathMatching") { 951 // Part of <rdar://problem/6961230>. (IOKit) 952 // This should be addressed using a API table. 953 S = getPersistentSummary(RetEffect::MakeOwned(RetEffect::CF, true), 954 DoNothing, DoNothing); 955 } else if (FName == "IOServiceGetMatchingService" || 956 FName == "IOServiceGetMatchingServices") { 957 // FIXES: <rdar://problem/6326900> 958 // This should be addressed using a API table. This strcmp is also 959 // a little gross, but there is no need to super optimize here. 960 ScratchArgs = AF.add(ScratchArgs, 1, DecRef); 961 S = getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, DoNothing); 962 } else if (FName == "IOServiceAddNotification" || 963 FName == "IOServiceAddMatchingNotification") { 964 // Part of <rdar://problem/6961230>. (IOKit) 965 // This should be addressed using a API table. 966 ScratchArgs = AF.add(ScratchArgs, 2, DecRef); 967 S = getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, DoNothing); 968 } else if (FName == "CVPixelBufferCreateWithBytes") { 969 // FIXES: <rdar://problem/7283567> 970 // Eventually this can be improved by recognizing that the pixel 971 // buffer passed to CVPixelBufferCreateWithBytes is released via 972 // a callback and doing full IPA to make sure this is done correctly. 973 // FIXME: This function has an out parameter that returns an 974 // allocated object. 975 ScratchArgs = AF.add(ScratchArgs, 7, StopTracking); 976 S = getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, DoNothing); 977 } else if (FName == "CGBitmapContextCreateWithData") { 978 // FIXES: <rdar://problem/7358899> 979 // Eventually this can be improved by recognizing that 'releaseInfo' 980 // passed to CGBitmapContextCreateWithData is released via 981 // a callback and doing full IPA to make sure this is done correctly. 982 ScratchArgs = AF.add(ScratchArgs, 8, StopTracking); 983 S = getPersistentSummary(RetEffect::MakeOwned(RetEffect::CF, true), 984 DoNothing, DoNothing); 985 } else if (FName == "CVPixelBufferCreateWithPlanarBytes") { 986 // FIXES: <rdar://problem/7283567> 987 // Eventually this can be improved by recognizing that the pixel 988 // buffer passed to CVPixelBufferCreateWithPlanarBytes is released 989 // via a callback and doing full IPA to make sure this is done 990 // correctly. 991 ScratchArgs = AF.add(ScratchArgs, 12, StopTracking); 992 S = getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, DoNothing); 993 } 994 995 // Did we get a summary? 996 if (S) 997 break; 998 999 // Enable this code once the semantics of NSDeallocateObject are resolved 1000 // for GC. <rdar://problem/6619988> 1001#if 0 1002 // Handle: NSDeallocateObject(id anObject); 1003 // This method does allow 'nil' (although we don't check it now). 1004 if (strcmp(FName, "NSDeallocateObject") == 0) { 1005 return RetTy == Ctx.VoidTy 1006 ? getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, Dealloc) 1007 : getPersistentStopSummary(); 1008 } 1009#endif 1010 1011 if (RetTy->isPointerType()) { 1012 // For CoreFoundation ('CF') types. 1013 if (cocoa::isRefType(RetTy, "CF", FName)) { 1014 if (isRetain(FD, FName)) 1015 S = getUnarySummary(FT, cfretain); 1016 else if (isMakeCollectable(FD, FName)) 1017 S = getUnarySummary(FT, cfmakecollectable); 1018 else 1019 S = getCFCreateGetRuleSummary(FD); 1020 1021 break; 1022 } 1023 1024 // For CoreGraphics ('CG') types. 1025 if (cocoa::isRefType(RetTy, "CG", FName)) { 1026 if (isRetain(FD, FName)) 1027 S = getUnarySummary(FT, cfretain); 1028 else 1029 S = getCFCreateGetRuleSummary(FD); 1030 1031 break; 1032 } 1033 1034 // For the Disk Arbitration API (DiskArbitration/DADisk.h) 1035 if (cocoa::isRefType(RetTy, "DADisk") || 1036 cocoa::isRefType(RetTy, "DADissenter") || 1037 cocoa::isRefType(RetTy, "DASessionRef")) { 1038 S = getCFCreateGetRuleSummary(FD); 1039 break; 1040 } 1041 1042 break; 1043 } 1044 1045 // Check for release functions, the only kind of functions that we care 1046 // about that don't return a pointer type. 1047 if (FName[0] == 'C' && (FName[1] == 'F' || FName[1] == 'G')) { 1048 // Test for 'CGCF'. 1049 FName = FName.substr(FName.startswith("CGCF") ? 4 : 2); 1050 1051 if (isRelease(FD, FName)) 1052 S = getUnarySummary(FT, cfrelease); 1053 else { 1054 assert (ScratchArgs.isEmpty()); 1055 // Remaining CoreFoundation and CoreGraphics functions. 1056 // We use to assume that they all strictly followed the ownership idiom 1057 // and that ownership cannot be transferred. While this is technically 1058 // correct, many methods allow a tracked object to escape. For example: 1059 // 1060 // CFMutableDictionaryRef x = CFDictionaryCreateMutable(...); 1061 // CFDictionaryAddValue(y, key, x); 1062 // CFRelease(x); 1063 // ... it is okay to use 'x' since 'y' has a reference to it 1064 // 1065 // We handle this and similar cases with the follow heuristic. If the 1066 // function name contains "InsertValue", "SetValue", "AddValue", 1067 // "AppendValue", or "SetAttribute", then we assume that arguments may 1068 // "escape." This means that something else holds on to the object, 1069 // allowing it be used even after its local retain count drops to 0. 1070 ArgEffect E = (StrInStrNoCase(FName, "InsertValue") != StringRef::npos|| 1071 StrInStrNoCase(FName, "AddValue") != StringRef::npos || 1072 StrInStrNoCase(FName, "SetValue") != StringRef::npos || 1073 StrInStrNoCase(FName, "AppendValue") != StringRef::npos|| 1074 StrInStrNoCase(FName, "SetAttribute") != StringRef::npos) 1075 ? MayEscape : DoNothing; 1076 1077 S = getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, E); 1078 } 1079 } 1080 } 1081 while (0); 1082 1083 // Annotations override defaults. 1084 updateSummaryFromAnnotations(S, FD); 1085 1086 FuncSummaries[FD] = S; 1087 return S; 1088} 1089 1090const RetainSummary * 1091RetainSummaryManager::getCFCreateGetRuleSummary(const FunctionDecl *FD) { 1092 if (coreFoundation::followsCreateRule(FD)) 1093 return getCFSummaryCreateRule(FD); 1094 1095 return getCFSummaryGetRule(FD); 1096} 1097 1098const RetainSummary * 1099RetainSummaryManager::getUnarySummary(const FunctionType* FT, 1100 UnaryFuncKind func) { 1101 1102 // Sanity check that this is *really* a unary function. This can 1103 // happen if people do weird things. 1104 const FunctionProtoType* FTP = dyn_cast<FunctionProtoType>(FT); 1105 if (!FTP || FTP->getNumArgs() != 1) 1106 return getPersistentStopSummary(); 1107 1108 assert (ScratchArgs.isEmpty()); 1109 1110 ArgEffect Effect; 1111 switch (func) { 1112 case cfretain: Effect = IncRef; break; 1113 case cfrelease: Effect = DecRef; break; 1114 case cfmakecollectable: Effect = MakeCollectable; break; 1115 default: llvm_unreachable("Not a supported unary function."); 1116 } 1117 1118 ScratchArgs = AF.add(ScratchArgs, 0, Effect); 1119 return getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, DoNothing); 1120} 1121 1122const RetainSummary * 1123RetainSummaryManager::getCFSummaryCreateRule(const FunctionDecl *FD) { 1124 assert (ScratchArgs.isEmpty()); 1125 1126 return getPersistentSummary(RetEffect::MakeOwned(RetEffect::CF, true)); 1127} 1128 1129const RetainSummary * 1130RetainSummaryManager::getCFSummaryGetRule(const FunctionDecl *FD) { 1131 assert (ScratchArgs.isEmpty()); 1132 return getPersistentSummary(RetEffect::MakeNotOwned(RetEffect::CF), 1133 DoNothing, DoNothing); 1134} 1135 1136//===----------------------------------------------------------------------===// 1137// Summary creation for Selectors. 1138//===----------------------------------------------------------------------===// 1139 1140const RetainSummary * 1141RetainSummaryManager::getInitMethodSummary(QualType RetTy) { 1142 assert(ScratchArgs.isEmpty()); 1143 // 'init' methods conceptually return a newly allocated object and claim 1144 // the receiver. 1145 if (cocoa::isCocoaObjectRef(RetTy) || 1146 coreFoundation::isCFObjectRef(RetTy)) 1147 return getPersistentSummary(ObjCInitRetE, DecRefMsg); 1148 1149 return getDefaultSummary(); 1150} 1151 1152void 1153RetainSummaryManager::updateSummaryFromAnnotations(const RetainSummary *&Summ, 1154 const FunctionDecl *FD) { 1155 if (!FD) 1156 return; 1157 1158 RetainSummaryTemplate Template(Summ, DefaultSummary, *this); 1159 1160 // Effects on the parameters. 1161 unsigned parm_idx = 0; 1162 for (FunctionDecl::param_const_iterator pi = FD->param_begin(), 1163 pe = FD->param_end(); pi != pe; ++pi, ++parm_idx) { 1164 const ParmVarDecl *pd = *pi; 1165 if (pd->getAttr<NSConsumedAttr>()) { 1166 if (!GCEnabled) { 1167 Template->addArg(AF, parm_idx, DecRef); 1168 } 1169 } else if (pd->getAttr<CFConsumedAttr>()) { 1170 Template->addArg(AF, parm_idx, DecRef); 1171 } 1172 } 1173 1174 QualType RetTy = FD->getResultType(); 1175 1176 // Determine if there is a special return effect for this method. 1177 if (cocoa::isCocoaObjectRef(RetTy)) { 1178 if (FD->getAttr<NSReturnsRetainedAttr>()) { 1179 Template->setRetEffect(ObjCAllocRetE); 1180 } 1181 else if (FD->getAttr<CFReturnsRetainedAttr>()) { 1182 Template->setRetEffect(RetEffect::MakeOwned(RetEffect::CF, true)); 1183 } 1184 else if (FD->getAttr<NSReturnsNotRetainedAttr>()) { 1185 Template->setRetEffect(RetEffect::MakeNotOwned(RetEffect::ObjC)); 1186 } 1187 else if (FD->getAttr<CFReturnsNotRetainedAttr>()) { 1188 Template->setRetEffect(RetEffect::MakeNotOwned(RetEffect::CF)); 1189 } 1190 } else if (RetTy->getAs<PointerType>()) { 1191 if (FD->getAttr<CFReturnsRetainedAttr>()) { 1192 Template->setRetEffect(RetEffect::MakeOwned(RetEffect::CF, true)); 1193 } 1194 else if (FD->getAttr<CFReturnsNotRetainedAttr>()) { 1195 Template->setRetEffect(RetEffect::MakeNotOwned(RetEffect::CF)); 1196 } 1197 } 1198} 1199 1200void 1201RetainSummaryManager::updateSummaryFromAnnotations(const RetainSummary *&Summ, 1202 const ObjCMethodDecl *MD) { 1203 if (!MD) 1204 return; 1205 1206 RetainSummaryTemplate Template(Summ, DefaultSummary, *this); 1207 1208 bool isTrackedLoc = false; 1209 1210 // Effects on the receiver. 1211 if (MD->getAttr<NSConsumesSelfAttr>()) { 1212 if (!GCEnabled) 1213 Template->setReceiverEffect(DecRefMsg); 1214 } 1215 1216 // Effects on the parameters. 1217 unsigned parm_idx = 0; 1218 for (ObjCMethodDecl::param_const_iterator 1219 pi=MD->param_begin(), pe=MD->param_end(); 1220 pi != pe; ++pi, ++parm_idx) { 1221 const ParmVarDecl *pd = *pi; 1222 if (pd->getAttr<NSConsumedAttr>()) { 1223 if (!GCEnabled) 1224 Template->addArg(AF, parm_idx, DecRef); 1225 } 1226 else if(pd->getAttr<CFConsumedAttr>()) { 1227 Template->addArg(AF, parm_idx, DecRef); 1228 } 1229 } 1230 1231 // Determine if there is a special return effect for this method. 1232 if (cocoa::isCocoaObjectRef(MD->getResultType())) { 1233 if (MD->getAttr<NSReturnsRetainedAttr>()) { 1234 Template->setRetEffect(ObjCAllocRetE); 1235 return; 1236 } 1237 if (MD->getAttr<NSReturnsNotRetainedAttr>()) { 1238 Template->setRetEffect(RetEffect::MakeNotOwned(RetEffect::ObjC)); 1239 return; 1240 } 1241 1242 isTrackedLoc = true; 1243 } else { 1244 isTrackedLoc = MD->getResultType()->getAs<PointerType>() != NULL; 1245 } 1246 1247 if (isTrackedLoc) { 1248 if (MD->getAttr<CFReturnsRetainedAttr>()) 1249 Template->setRetEffect(RetEffect::MakeOwned(RetEffect::CF, true)); 1250 else if (MD->getAttr<CFReturnsNotRetainedAttr>()) 1251 Template->setRetEffect(RetEffect::MakeNotOwned(RetEffect::CF)); 1252 } 1253} 1254 1255const RetainSummary * 1256RetainSummaryManager::getCommonMethodSummary(const ObjCMethodDecl *MD, 1257 Selector S, QualType RetTy) { 1258 1259 if (MD) { 1260 // Scan the method decl for 'void*' arguments. These should be treated 1261 // as 'StopTracking' because they are often used with delegates. 1262 // Delegates are a frequent form of false positives with the retain 1263 // count checker. 1264 unsigned i = 0; 1265 for (ObjCMethodDecl::param_const_iterator I = MD->param_begin(), 1266 E = MD->param_end(); I != E; ++I, ++i) 1267 if (const ParmVarDecl *PD = *I) { 1268 QualType Ty = Ctx.getCanonicalType(PD->getType()); 1269 if (Ty.getLocalUnqualifiedType() == Ctx.VoidPtrTy) 1270 ScratchArgs = AF.add(ScratchArgs, i, StopTracking); 1271 } 1272 } 1273 1274 // Any special effect for the receiver? 1275 ArgEffect ReceiverEff = DoNothing; 1276 1277 // If one of the arguments in the selector has the keyword 'delegate' we 1278 // should stop tracking the reference count for the receiver. This is 1279 // because the reference count is quite possibly handled by a delegate 1280 // method. 1281 if (S.isKeywordSelector()) { 1282 const std::string &str = S.getAsString(); 1283 assert(!str.empty()); 1284 if (StrInStrNoCase(str, "delegate:") != StringRef::npos) 1285 ReceiverEff = StopTracking; 1286 } 1287 1288 // Look for methods that return an owned object. 1289 if (cocoa::isCocoaObjectRef(RetTy)) { 1290 // EXPERIMENTAL: assume the Cocoa conventions for all objects returned 1291 // by instance methods. 1292 RetEffect E = cocoa::followsFundamentalRule(S, MD) 1293 ? ObjCAllocRetE : RetEffect::MakeNotOwned(RetEffect::ObjC); 1294 1295 return getPersistentSummary(E, ReceiverEff, MayEscape); 1296 } 1297 1298 // Look for methods that return an owned core foundation object. 1299 if (coreFoundation::isCFObjectRef(RetTy)) { 1300 RetEffect E = cocoa::followsFundamentalRule(S, MD) 1301 ? RetEffect::MakeOwned(RetEffect::CF, true) 1302 : RetEffect::MakeNotOwned(RetEffect::CF); 1303 1304 return getPersistentSummary(E, ReceiverEff, MayEscape); 1305 } 1306 1307 if (ScratchArgs.isEmpty() && ReceiverEff == DoNothing) 1308 return getDefaultSummary(); 1309 1310 return getPersistentSummary(RetEffect::MakeNoRet(), ReceiverEff, MayEscape); 1311} 1312 1313const RetainSummary * 1314RetainSummaryManager::getInstanceMethodSummary(const ObjCMessage &msg, 1315 const ProgramState *state, 1316 const LocationContext *LC) { 1317 1318 // We need the type-information of the tracked receiver object 1319 // Retrieve it from the state. 1320 const Expr *Receiver = msg.getInstanceReceiver(); 1321 const ObjCInterfaceDecl *ID = 0; 1322 1323 // FIXME: Is this really working as expected? There are cases where 1324 // we just use the 'ID' from the message expression. 1325 SVal receiverV; 1326 1327 if (Receiver) { 1328 receiverV = state->getSValAsScalarOrLoc(Receiver); 1329 1330 // FIXME: Eventually replace the use of state->get<RefBindings> with 1331 // a generic API for reasoning about the Objective-C types of symbolic 1332 // objects. 1333 if (SymbolRef Sym = receiverV.getAsLocSymbol()) 1334 if (const RefVal *T = state->get<RefBindings>(Sym)) 1335 if (const ObjCObjectPointerType* PT = 1336 T->getType()->getAs<ObjCObjectPointerType>()) 1337 ID = PT->getInterfaceDecl(); 1338 1339 // FIXME: this is a hack. This may or may not be the actual method 1340 // that is called. 1341 if (!ID) { 1342 if (const ObjCObjectPointerType *PT = 1343 Receiver->getType()->getAs<ObjCObjectPointerType>()) 1344 ID = PT->getInterfaceDecl(); 1345 } 1346 } else { 1347 // FIXME: Hack for 'super'. 1348 ID = msg.getReceiverInterface(); 1349 } 1350 1351 // FIXME: The receiver could be a reference to a class, meaning that 1352 // we should use the class method. 1353 return getInstanceMethodSummary(msg, ID); 1354} 1355 1356const RetainSummary * 1357RetainSummaryManager::getInstanceMethodSummary(Selector S, 1358 IdentifierInfo *ClsName, 1359 const ObjCInterfaceDecl *ID, 1360 const ObjCMethodDecl *MD, 1361 QualType RetTy) { 1362 1363 // Look up a summary in our summary cache. 1364 const RetainSummary *Summ = ObjCMethodSummaries.find(ID, ClsName, S); 1365 1366 if (!Summ) { 1367 assert(ScratchArgs.isEmpty()); 1368 1369 // "initXXX": pass-through for receiver. 1370 if (cocoa::deriveNamingConvention(S, MD) == cocoa::InitRule) 1371 Summ = getInitMethodSummary(RetTy); 1372 else 1373 Summ = getCommonMethodSummary(MD, S, RetTy); 1374 1375 // Annotations override defaults. 1376 updateSummaryFromAnnotations(Summ, MD); 1377 1378 // Memoize the summary. 1379 ObjCMethodSummaries[ObjCSummaryKey(ID, ClsName, S)] = Summ; 1380 } 1381 1382 return Summ; 1383} 1384 1385const RetainSummary * 1386RetainSummaryManager::getClassMethodSummary(Selector S, IdentifierInfo *ClsName, 1387 const ObjCInterfaceDecl *ID, 1388 const ObjCMethodDecl *MD, 1389 QualType RetTy) { 1390 1391 assert(ClsName && "Class name must be specified."); 1392 const RetainSummary *Summ = ObjCClassMethodSummaries.find(ID, ClsName, S); 1393 1394 if (!Summ) { 1395 Summ = getCommonMethodSummary(MD, S, RetTy); 1396 1397 // Annotations override defaults. 1398 updateSummaryFromAnnotations(Summ, MD); 1399 1400 // Memoize the summary. 1401 ObjCClassMethodSummaries[ObjCSummaryKey(ID, ClsName, S)] = Summ; 1402 } 1403 1404 return Summ; 1405} 1406 1407void RetainSummaryManager::InitializeClassMethodSummaries() { 1408 assert(ScratchArgs.isEmpty()); 1409 // Create the [NSAssertionHandler currentHander] summary. 1410 addClassMethSummary("NSAssertionHandler", "currentHandler", 1411 getPersistentSummary(RetEffect::MakeNotOwned(RetEffect::ObjC))); 1412 1413 // Create the [NSAutoreleasePool addObject:] summary. 1414 ScratchArgs = AF.add(ScratchArgs, 0, Autorelease); 1415 addClassMethSummary("NSAutoreleasePool", "addObject", 1416 getPersistentSummary(RetEffect::MakeNoRet(), 1417 DoNothing, Autorelease)); 1418 1419 // Create the summaries for [NSObject performSelector...]. We treat 1420 // these as 'stop tracking' for the arguments because they are often 1421 // used for delegates that can release the object. When we have better 1422 // inter-procedural analysis we can potentially do something better. This 1423 // workaround is to remove false positives. 1424 const RetainSummary *Summ = 1425 getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, StopTracking); 1426 IdentifierInfo *NSObjectII = &Ctx.Idents.get("NSObject"); 1427 addClsMethSummary(NSObjectII, Summ, "performSelector", "withObject", 1428 "afterDelay", NULL); 1429 addClsMethSummary(NSObjectII, Summ, "performSelector", "withObject", 1430 "afterDelay", "inModes", NULL); 1431 addClsMethSummary(NSObjectII, Summ, "performSelectorOnMainThread", 1432 "withObject", "waitUntilDone", NULL); 1433 addClsMethSummary(NSObjectII, Summ, "performSelectorOnMainThread", 1434 "withObject", "waitUntilDone", "modes", NULL); 1435 addClsMethSummary(NSObjectII, Summ, "performSelector", "onThread", 1436 "withObject", "waitUntilDone", NULL); 1437 addClsMethSummary(NSObjectII, Summ, "performSelector", "onThread", 1438 "withObject", "waitUntilDone", "modes", NULL); 1439 addClsMethSummary(NSObjectII, Summ, "performSelectorInBackground", 1440 "withObject", NULL); 1441} 1442 1443void RetainSummaryManager::InitializeMethodSummaries() { 1444 1445 assert (ScratchArgs.isEmpty()); 1446 1447 // Create the "init" selector. It just acts as a pass-through for the 1448 // receiver. 1449 const RetainSummary *InitSumm = getPersistentSummary(ObjCInitRetE, DecRefMsg); 1450 addNSObjectMethSummary(GetNullarySelector("init", Ctx), InitSumm); 1451 1452 // awakeAfterUsingCoder: behaves basically like an 'init' method. It 1453 // claims the receiver and returns a retained object. 1454 addNSObjectMethSummary(GetUnarySelector("awakeAfterUsingCoder", Ctx), 1455 InitSumm); 1456 1457 // The next methods are allocators. 1458 const RetainSummary *AllocSumm = getPersistentSummary(ObjCAllocRetE); 1459 const RetainSummary *CFAllocSumm = 1460 getPersistentSummary(RetEffect::MakeOwned(RetEffect::CF, true)); 1461 1462 // Create the "retain" selector. 1463 RetEffect NoRet = RetEffect::MakeNoRet(); 1464 const RetainSummary *Summ = getPersistentSummary(NoRet, IncRefMsg); 1465 addNSObjectMethSummary(GetNullarySelector("retain", Ctx), Summ); 1466 1467 // Create the "release" selector. 1468 Summ = getPersistentSummary(NoRet, DecRefMsg); 1469 addNSObjectMethSummary(GetNullarySelector("release", Ctx), Summ); 1470 1471 // Create the "drain" selector. 1472 Summ = getPersistentSummary(NoRet, isGCEnabled() ? DoNothing : DecRef); 1473 addNSObjectMethSummary(GetNullarySelector("drain", Ctx), Summ); 1474 1475 // Create the -dealloc summary. 1476 Summ = getPersistentSummary(NoRet, Dealloc); 1477 addNSObjectMethSummary(GetNullarySelector("dealloc", Ctx), Summ); 1478 1479 // Create the "autorelease" selector. 1480 Summ = getPersistentSummary(NoRet, Autorelease); 1481 addNSObjectMethSummary(GetNullarySelector("autorelease", Ctx), Summ); 1482 1483 // Specially handle NSAutoreleasePool. 1484 addInstMethSummary("NSAutoreleasePool", "init", 1485 getPersistentSummary(NoRet, NewAutoreleasePool)); 1486 1487 // For NSWindow, allocated objects are (initially) self-owned. 1488 // FIXME: For now we opt for false negatives with NSWindow, as these objects 1489 // self-own themselves. However, they only do this once they are displayed. 1490 // Thus, we need to track an NSWindow's display status. 1491 // This is tracked in <rdar://problem/6062711>. 1492 // See also http://llvm.org/bugs/show_bug.cgi?id=3714. 1493 const RetainSummary *NoTrackYet = getPersistentSummary(RetEffect::MakeNoRet(), 1494 StopTracking, 1495 StopTracking); 1496 1497 addClassMethSummary("NSWindow", "alloc", NoTrackYet); 1498 1499#if 0 1500 addInstMethSummary("NSWindow", NoTrackYet, "initWithContentRect", 1501 "styleMask", "backing", "defer", NULL); 1502 1503 addInstMethSummary("NSWindow", NoTrackYet, "initWithContentRect", 1504 "styleMask", "backing", "defer", "screen", NULL); 1505#endif 1506 1507 // For NSPanel (which subclasses NSWindow), allocated objects are not 1508 // self-owned. 1509 // FIXME: For now we don't track NSPanels. object for the same reason 1510 // as for NSWindow objects. 1511 addClassMethSummary("NSPanel", "alloc", NoTrackYet); 1512 1513#if 0 1514 addInstMethSummary("NSPanel", NoTrackYet, "initWithContentRect", 1515 "styleMask", "backing", "defer", NULL); 1516 1517 addInstMethSummary("NSPanel", NoTrackYet, "initWithContentRect", 1518 "styleMask", "backing", "defer", "screen", NULL); 1519#endif 1520 1521 // Don't track allocated autorelease pools yet, as it is okay to prematurely 1522 // exit a method. 1523 addClassMethSummary("NSAutoreleasePool", "alloc", NoTrackYet); 1524 1525 // Create summaries QCRenderer/QCView -createSnapShotImageOfType: 1526 addInstMethSummary("QCRenderer", AllocSumm, 1527 "createSnapshotImageOfType", NULL); 1528 addInstMethSummary("QCView", AllocSumm, 1529 "createSnapshotImageOfType", NULL); 1530 1531 // Create summaries for CIContext, 'createCGImage' and 1532 // 'createCGLayerWithSize'. These objects are CF objects, and are not 1533 // automatically garbage collected. 1534 addInstMethSummary("CIContext", CFAllocSumm, 1535 "createCGImage", "fromRect", NULL); 1536 addInstMethSummary("CIContext", CFAllocSumm, 1537 "createCGImage", "fromRect", "format", "colorSpace", NULL); 1538 addInstMethSummary("CIContext", CFAllocSumm, "createCGLayerWithSize", 1539 "info", NULL); 1540} 1541 1542//===----------------------------------------------------------------------===// 1543// AutoreleaseBindings - State used to track objects in autorelease pools. 1544//===----------------------------------------------------------------------===// 1545 1546typedef llvm::ImmutableMap<SymbolRef, unsigned> ARCounts; 1547typedef llvm::ImmutableMap<SymbolRef, ARCounts> ARPoolContents; 1548typedef llvm::ImmutableList<SymbolRef> ARStack; 1549 1550static int AutoRCIndex = 0; 1551static int AutoRBIndex = 0; 1552 1553namespace { class AutoreleasePoolContents {}; } 1554namespace { class AutoreleaseStack {}; } 1555 1556namespace clang { 1557namespace ento { 1558template<> struct ProgramStateTrait<AutoreleaseStack> 1559 : public ProgramStatePartialTrait<ARStack> { 1560 static inline void *GDMIndex() { return &AutoRBIndex; } 1561}; 1562 1563template<> struct ProgramStateTrait<AutoreleasePoolContents> 1564 : public ProgramStatePartialTrait<ARPoolContents> { 1565 static inline void *GDMIndex() { return &AutoRCIndex; } 1566}; 1567} // end GR namespace 1568} // end clang namespace 1569 1570static SymbolRef GetCurrentAutoreleasePool(const ProgramState *state) { 1571 ARStack stack = state->get<AutoreleaseStack>(); 1572 return stack.isEmpty() ? SymbolRef() : stack.getHead(); 1573} 1574 1575static const ProgramState * 1576SendAutorelease(const ProgramState *state, 1577 ARCounts::Factory &F, 1578 SymbolRef sym) { 1579 SymbolRef pool = GetCurrentAutoreleasePool(state); 1580 const ARCounts *cnts = state->get<AutoreleasePoolContents>(pool); 1581 ARCounts newCnts(0); 1582 1583 if (cnts) { 1584 const unsigned *cnt = (*cnts).lookup(sym); 1585 newCnts = F.add(*cnts, sym, cnt ? *cnt + 1 : 1); 1586 } 1587 else 1588 newCnts = F.add(F.getEmptyMap(), sym, 1); 1589 1590 return state->set<AutoreleasePoolContents>(pool, newCnts); 1591} 1592 1593//===----------------------------------------------------------------------===// 1594// Error reporting. 1595//===----------------------------------------------------------------------===// 1596namespace { 1597 typedef llvm::DenseMap<const ExplodedNode *, const RetainSummary *> 1598 SummaryLogTy; 1599 1600 //===-------------===// 1601 // Bug Descriptions. // 1602 //===-------------===// 1603 1604 class CFRefBug : public BugType { 1605 protected: 1606 CFRefBug(StringRef name) 1607 : BugType(name, "Memory (Core Foundation/Objective-C)") {} 1608 public: 1609 1610 // FIXME: Eventually remove. 1611 virtual const char *getDescription() const = 0; 1612 1613 virtual bool isLeak() const { return false; } 1614 }; 1615 1616 class UseAfterRelease : public CFRefBug { 1617 public: 1618 UseAfterRelease() : CFRefBug("Use-after-release") {} 1619 1620 const char *getDescription() const { 1621 return "Reference-counted object is used after it is released"; 1622 } 1623 }; 1624 1625 class BadRelease : public CFRefBug { 1626 public: 1627 BadRelease() : CFRefBug("Bad release") {} 1628 1629 const char *getDescription() const { 1630 return "Incorrect decrement of the reference count of an object that is " 1631 "not owned at this point by the caller"; 1632 } 1633 }; 1634 1635 class DeallocGC : public CFRefBug { 1636 public: 1637 DeallocGC() 1638 : CFRefBug("-dealloc called while using garbage collection") {} 1639 1640 const char *getDescription() const { 1641 return "-dealloc called while using garbage collection"; 1642 } 1643 }; 1644 1645 class DeallocNotOwned : public CFRefBug { 1646 public: 1647 DeallocNotOwned() 1648 : CFRefBug("-dealloc sent to non-exclusively owned object") {} 1649 1650 const char *getDescription() const { 1651 return "-dealloc sent to object that may be referenced elsewhere"; 1652 } 1653 }; 1654 1655 class OverAutorelease : public CFRefBug { 1656 public: 1657 OverAutorelease() 1658 : CFRefBug("Object sent -autorelease too many times") {} 1659 1660 const char *getDescription() const { 1661 return "Object sent -autorelease too many times"; 1662 } 1663 }; 1664 1665 class ReturnedNotOwnedForOwned : public CFRefBug { 1666 public: 1667 ReturnedNotOwnedForOwned() 1668 : CFRefBug("Method should return an owned object") {} 1669 1670 const char *getDescription() const { 1671 return "Object with a +0 retain count returned to caller where a +1 " 1672 "(owning) retain count is expected"; 1673 } 1674 }; 1675 1676 class Leak : public CFRefBug { 1677 const bool isReturn; 1678 protected: 1679 Leak(StringRef name, bool isRet) 1680 : CFRefBug(name), isReturn(isRet) { 1681 // Leaks should not be reported if they are post-dominated by a sink. 1682 setSuppressOnSink(true); 1683 } 1684 public: 1685 1686 const char *getDescription() const { return ""; } 1687 1688 bool isLeak() const { return true; } 1689 }; 1690 1691 class LeakAtReturn : public Leak { 1692 public: 1693 LeakAtReturn(StringRef name) 1694 : Leak(name, true) {} 1695 }; 1696 1697 class LeakWithinFunction : public Leak { 1698 public: 1699 LeakWithinFunction(StringRef name) 1700 : Leak(name, false) {} 1701 }; 1702 1703 //===---------===// 1704 // Bug Reports. // 1705 //===---------===// 1706 1707 class CFRefReportVisitor : public BugReporterVisitor { 1708 protected: 1709 SymbolRef Sym; 1710 const SummaryLogTy &SummaryLog; 1711 bool GCEnabled; 1712 1713 public: 1714 CFRefReportVisitor(SymbolRef sym, bool gcEnabled, const SummaryLogTy &log) 1715 : Sym(sym), SummaryLog(log), GCEnabled(gcEnabled) {} 1716 1717 virtual void Profile(llvm::FoldingSetNodeID &ID) const { 1718 static int x = 0; 1719 ID.AddPointer(&x); 1720 ID.AddPointer(Sym); 1721 } 1722 1723 virtual PathDiagnosticPiece *VisitNode(const ExplodedNode *N, 1724 const ExplodedNode *PrevN, 1725 BugReporterContext &BRC, 1726 BugReport &BR); 1727 1728 virtual PathDiagnosticPiece *getEndPath(BugReporterContext &BRC, 1729 const ExplodedNode *N, 1730 BugReport &BR); 1731 }; 1732 1733 class CFRefLeakReportVisitor : public CFRefReportVisitor { 1734 public: 1735 CFRefLeakReportVisitor(SymbolRef sym, bool GCEnabled, 1736 const SummaryLogTy &log) 1737 : CFRefReportVisitor(sym, GCEnabled, log) {} 1738 1739 PathDiagnosticPiece *getEndPath(BugReporterContext &BRC, 1740 const ExplodedNode *N, 1741 BugReport &BR); 1742 }; 1743 1744 class CFRefReport : public BugReport { 1745 void addGCModeDescription(const LangOptions &LOpts, bool GCEnabled); 1746 1747 public: 1748 CFRefReport(CFRefBug &D, const LangOptions &LOpts, bool GCEnabled, 1749 const SummaryLogTy &Log, ExplodedNode *n, SymbolRef sym, 1750 bool registerVisitor = true) 1751 : BugReport(D, D.getDescription(), n) { 1752 if (registerVisitor) 1753 addVisitor(new CFRefReportVisitor(sym, GCEnabled, Log)); 1754 addGCModeDescription(LOpts, GCEnabled); 1755 } 1756 1757 CFRefReport(CFRefBug &D, const LangOptions &LOpts, bool GCEnabled, 1758 const SummaryLogTy &Log, ExplodedNode *n, SymbolRef sym, 1759 StringRef endText) 1760 : BugReport(D, D.getDescription(), endText, n) { 1761 addVisitor(new CFRefReportVisitor(sym, GCEnabled, Log)); 1762 addGCModeDescription(LOpts, GCEnabled); 1763 } 1764 1765 virtual std::pair<ranges_iterator, ranges_iterator> getRanges() { 1766 const CFRefBug& BugTy = static_cast<CFRefBug&>(getBugType()); 1767 if (!BugTy.isLeak()) 1768 return BugReport::getRanges(); 1769 else 1770 return std::make_pair(ranges_iterator(), ranges_iterator()); 1771 } 1772 }; 1773 1774 class CFRefLeakReport : public CFRefReport { 1775 const MemRegion* AllocBinding; 1776 1777 public: 1778 CFRefLeakReport(CFRefBug &D, const LangOptions &LOpts, bool GCEnabled, 1779 const SummaryLogTy &Log, ExplodedNode *n, SymbolRef sym, 1780 ExprEngine &Eng); 1781 1782 PathDiagnosticLocation getLocation(const SourceManager &SM) const { 1783 assert(Location.isValid()); 1784 return Location; 1785 } 1786 }; 1787} // end anonymous namespace 1788 1789void CFRefReport::addGCModeDescription(const LangOptions &LOpts, 1790 bool GCEnabled) { 1791 const char *GCModeDescription = 0; 1792 1793 switch (LOpts.getGC()) { 1794 case LangOptions::GCOnly: 1795 assert(GCEnabled); 1796 GCModeDescription = "Code is compiled to only use garbage collection"; 1797 break; 1798 1799 case LangOptions::NonGC: 1800 assert(!GCEnabled); 1801 GCModeDescription = "Code is compiled to use reference counts"; 1802 break; 1803 1804 case LangOptions::HybridGC: 1805 if (GCEnabled) { 1806 GCModeDescription = "Code is compiled to use either garbage collection " 1807 "(GC) or reference counts (non-GC). The bug occurs " 1808 "with GC enabled"; 1809 break; 1810 } else { 1811 GCModeDescription = "Code is compiled to use either garbage collection " 1812 "(GC) or reference counts (non-GC). The bug occurs " 1813 "in non-GC mode"; 1814 break; 1815 } 1816 } 1817 1818 assert(GCModeDescription && "invalid/unknown GC mode"); 1819 addExtraText(GCModeDescription); 1820} 1821 1822// FIXME: This should be a method on SmallVector. 1823static inline bool contains(const SmallVectorImpl<ArgEffect>& V, 1824 ArgEffect X) { 1825 for (SmallVectorImpl<ArgEffect>::const_iterator I=V.begin(), E=V.end(); 1826 I!=E; ++I) 1827 if (*I == X) return true; 1828 1829 return false; 1830} 1831 1832PathDiagnosticPiece *CFRefReportVisitor::VisitNode(const ExplodedNode *N, 1833 const ExplodedNode *PrevN, 1834 BugReporterContext &BRC, 1835 BugReport &BR) { 1836 1837 if (!isa<StmtPoint>(N->getLocation())) 1838 return NULL; 1839 1840 // Check if the type state has changed. 1841 const ProgramState *PrevSt = PrevN->getState(); 1842 const ProgramState *CurrSt = N->getState(); 1843 1844 const RefVal* CurrT = CurrSt->get<RefBindings>(Sym); 1845 if (!CurrT) return NULL; 1846 1847 const RefVal &CurrV = *CurrT; 1848 const RefVal *PrevT = PrevSt->get<RefBindings>(Sym); 1849 1850 // Create a string buffer to constain all the useful things we want 1851 // to tell the user. 1852 std::string sbuf; 1853 llvm::raw_string_ostream os(sbuf); 1854 1855 // This is the allocation site since the previous node had no bindings 1856 // for this symbol. 1857 if (!PrevT) { 1858 const Stmt *S = cast<StmtPoint>(N->getLocation()).getStmt(); 1859 1860 if (const CallExpr *CE = dyn_cast<CallExpr>(S)) { 1861 // Get the name of the callee (if it is available). 1862 SVal X = CurrSt->getSValAsScalarOrLoc(CE->getCallee()); 1863 if (const FunctionDecl *FD = X.getAsFunctionDecl()) 1864 os << "Call to function '" << *FD << '\''; 1865 else 1866 os << "function call"; 1867 } 1868 else if (isa<ObjCMessageExpr>(S)) { 1869 os << "Method"; 1870 } else { 1871 os << "Property"; 1872 } 1873 1874 if (CurrV.getObjKind() == RetEffect::CF) { 1875 os << " returns a Core Foundation object with a "; 1876 } 1877 else { 1878 assert (CurrV.getObjKind() == RetEffect::ObjC); 1879 os << " returns an Objective-C object with a "; 1880 } 1881 1882 if (CurrV.isOwned()) { 1883 os << "+1 retain count"; 1884 1885 if (GCEnabled) { 1886 assert(CurrV.getObjKind() == RetEffect::CF); 1887 os << ". " 1888 "Core Foundation objects are not automatically garbage collected."; 1889 } 1890 } 1891 else { 1892 assert (CurrV.isNotOwned()); 1893 os << "+0 retain count"; 1894 } 1895 1896 PathDiagnosticLocation Pos(S, BRC.getSourceManager(), 1897 N->getLocationContext()); 1898 return new PathDiagnosticEventPiece(Pos, os.str()); 1899 } 1900 1901 // Gather up the effects that were performed on the object at this 1902 // program point 1903 SmallVector<ArgEffect, 2> AEffects; 1904 1905 const ExplodedNode *OrigNode = BRC.getNodeResolver().getOriginalNode(N); 1906 if (const RetainSummary *Summ = SummaryLog.lookup(OrigNode)) { 1907 // We only have summaries attached to nodes after evaluating CallExpr and 1908 // ObjCMessageExprs. 1909 const Stmt *S = cast<StmtPoint>(N->getLocation()).getStmt(); 1910 1911 if (const CallExpr *CE = dyn_cast<CallExpr>(S)) { 1912 // Iterate through the parameter expressions and see if the symbol 1913 // was ever passed as an argument. 1914 unsigned i = 0; 1915 1916 for (CallExpr::const_arg_iterator AI=CE->arg_begin(), AE=CE->arg_end(); 1917 AI!=AE; ++AI, ++i) { 1918 1919 // Retrieve the value of the argument. Is it the symbol 1920 // we are interested in? 1921 if (CurrSt->getSValAsScalarOrLoc(*AI).getAsLocSymbol() != Sym) 1922 continue; 1923 1924 // We have an argument. Get the effect! 1925 AEffects.push_back(Summ->getArg(i)); 1926 } 1927 } 1928 else if (const ObjCMessageExpr *ME = dyn_cast<ObjCMessageExpr>(S)) { 1929 if (const Expr *receiver = ME->getInstanceReceiver()) 1930 if (CurrSt->getSValAsScalarOrLoc(receiver).getAsLocSymbol() == Sym) { 1931 // The symbol we are tracking is the receiver. 1932 AEffects.push_back(Summ->getReceiverEffect()); 1933 } 1934 } 1935 } 1936 1937 do { 1938 // Get the previous type state. 1939 RefVal PrevV = *PrevT; 1940 1941 // Specially handle -dealloc. 1942 if (!GCEnabled && contains(AEffects, Dealloc)) { 1943 // Determine if the object's reference count was pushed to zero. 1944 assert(!(PrevV == CurrV) && "The typestate *must* have changed."); 1945 // We may not have transitioned to 'release' if we hit an error. 1946 // This case is handled elsewhere. 1947 if (CurrV.getKind() == RefVal::Released) { 1948 assert(CurrV.getCombinedCounts() == 0); 1949 os << "Object released by directly sending the '-dealloc' message"; 1950 break; 1951 } 1952 } 1953 1954 // Specially handle CFMakeCollectable and friends. 1955 if (contains(AEffects, MakeCollectable)) { 1956 // Get the name of the function. 1957 const Stmt *S = cast<StmtPoint>(N->getLocation()).getStmt(); 1958 SVal X = CurrSt->getSValAsScalarOrLoc(cast<CallExpr>(S)->getCallee()); 1959 const FunctionDecl *FD = X.getAsFunctionDecl(); 1960 1961 if (GCEnabled) { 1962 // Determine if the object's reference count was pushed to zero. 1963 assert(!(PrevV == CurrV) && "The typestate *must* have changed."); 1964 1965 os << "In GC mode a call to '" << *FD 1966 << "' decrements an object's retain count and registers the " 1967 "object with the garbage collector. "; 1968 1969 if (CurrV.getKind() == RefVal::Released) { 1970 assert(CurrV.getCount() == 0); 1971 os << "Since it now has a 0 retain count the object can be " 1972 "automatically collected by the garbage collector."; 1973 } 1974 else 1975 os << "An object must have a 0 retain count to be garbage collected. " 1976 "After this call its retain count is +" << CurrV.getCount() 1977 << '.'; 1978 } 1979 else 1980 os << "When GC is not enabled a call to '" << *FD 1981 << "' has no effect on its argument."; 1982 1983 // Nothing more to say. 1984 break; 1985 } 1986 1987 // Determine if the typestate has changed. 1988 if (!(PrevV == CurrV)) 1989 switch (CurrV.getKind()) { 1990 case RefVal::Owned: 1991 case RefVal::NotOwned: 1992 1993 if (PrevV.getCount() == CurrV.getCount()) { 1994 // Did an autorelease message get sent? 1995 if (PrevV.getAutoreleaseCount() == CurrV.getAutoreleaseCount()) 1996 return 0; 1997 1998 assert(PrevV.getAutoreleaseCount() < CurrV.getAutoreleaseCount()); 1999 os << "Object sent -autorelease message"; 2000 break; 2001 } 2002 2003 if (PrevV.getCount() > CurrV.getCount()) 2004 os << "Reference count decremented."; 2005 else 2006 os << "Reference count incremented."; 2007 2008 if (unsigned Count = CurrV.getCount()) 2009 os << " The object now has a +" << Count << " retain count."; 2010 2011 if (PrevV.getKind() == RefVal::Released) { 2012 assert(GCEnabled && CurrV.getCount() > 0); 2013 os << " The object is not eligible for garbage collection until the " 2014 "retain count reaches 0 again."; 2015 } 2016 2017 break; 2018 2019 case RefVal::Released: 2020 os << "Object released."; 2021 break; 2022 2023 case RefVal::ReturnedOwned: 2024 os << "Object returned to caller as an owning reference (single retain " 2025 "count transferred to caller)"; 2026 break; 2027 2028 case RefVal::ReturnedNotOwned: 2029 os << "Object returned to caller with a +0 retain count"; 2030 break; 2031 2032 default: 2033 return NULL; 2034 } 2035 2036 // Emit any remaining diagnostics for the argument effects (if any). 2037 for (SmallVectorImpl<ArgEffect>::iterator I=AEffects.begin(), 2038 E=AEffects.end(); I != E; ++I) { 2039 2040 // A bunch of things have alternate behavior under GC. 2041 if (GCEnabled) 2042 switch (*I) { 2043 default: break; 2044 case Autorelease: 2045 os << "In GC mode an 'autorelease' has no effect."; 2046 continue; 2047 case IncRefMsg: 2048 os << "In GC mode the 'retain' message has no effect."; 2049 continue; 2050 case DecRefMsg: 2051 os << "In GC mode the 'release' message has no effect."; 2052 continue; 2053 } 2054 } 2055 } while (0); 2056 2057 if (os.str().empty()) 2058 return 0; // We have nothing to say! 2059 2060 const Stmt *S = cast<StmtPoint>(N->getLocation()).getStmt(); 2061 PathDiagnosticLocation Pos(S, BRC.getSourceManager(), 2062 N->getLocationContext()); 2063 PathDiagnosticPiece *P = new PathDiagnosticEventPiece(Pos, os.str()); 2064 2065 // Add the range by scanning the children of the statement for any bindings 2066 // to Sym. 2067 for (Stmt::const_child_iterator I = S->child_begin(), E = S->child_end(); 2068 I!=E; ++I) 2069 if (const Expr *Exp = dyn_cast_or_null<Expr>(*I)) 2070 if (CurrSt->getSValAsScalarOrLoc(Exp).getAsLocSymbol() == Sym) { 2071 P->addRange(Exp->getSourceRange()); 2072 break; 2073 } 2074 2075 return P; 2076} 2077 2078namespace { 2079 class FindUniqueBinding : 2080 public StoreManager::BindingsHandler { 2081 SymbolRef Sym; 2082 const MemRegion* Binding; 2083 bool First; 2084 2085 public: 2086 FindUniqueBinding(SymbolRef sym) : Sym(sym), Binding(0), First(true) {} 2087 2088 bool HandleBinding(StoreManager& SMgr, Store store, const MemRegion* R, 2089 SVal val) { 2090 2091 SymbolRef SymV = val.getAsSymbol(); 2092 if (!SymV || SymV != Sym) 2093 return true; 2094 2095 if (Binding) { 2096 First = false; 2097 return false; 2098 } 2099 else 2100 Binding = R; 2101 2102 return true; 2103 } 2104 2105 operator bool() { return First && Binding; } 2106 const MemRegion* getRegion() { return Binding; } 2107 }; 2108} 2109 2110static std::pair<const ExplodedNode*,const MemRegion*> 2111GetAllocationSite(ProgramStateManager& StateMgr, const ExplodedNode *N, 2112 SymbolRef Sym) { 2113 2114 // Find both first node that referred to the tracked symbol and the 2115 // memory location that value was store to. 2116 const ExplodedNode *Last = N; 2117 const MemRegion* FirstBinding = 0; 2118 2119 while (N) { 2120 const ProgramState *St = N->getState(); 2121 RefBindings B = St->get<RefBindings>(); 2122 2123 if (!B.lookup(Sym)) 2124 break; 2125 2126 FindUniqueBinding FB(Sym); 2127 StateMgr.iterBindings(St, FB); 2128 if (FB) FirstBinding = FB.getRegion(); 2129 2130 Last = N; 2131 N = N->pred_empty() ? NULL : *(N->pred_begin()); 2132 } 2133 2134 return std::make_pair(Last, FirstBinding); 2135} 2136 2137PathDiagnosticPiece* 2138CFRefReportVisitor::getEndPath(BugReporterContext &BRC, 2139 const ExplodedNode *EndN, 2140 BugReport &BR) { 2141 // Tell the BugReporterContext to report cases when the tracked symbol is 2142 // assigned to different variables, etc. 2143 BRC.addNotableSymbol(Sym); 2144 return BugReporterVisitor::getDefaultEndPath(BRC, EndN, BR); 2145} 2146 2147PathDiagnosticPiece* 2148CFRefLeakReportVisitor::getEndPath(BugReporterContext &BRC, 2149 const ExplodedNode *EndN, 2150 BugReport &BR) { 2151 2152 // Tell the BugReporterContext to report cases when the tracked symbol is 2153 // assigned to different variables, etc. 2154 BRC.addNotableSymbol(Sym); 2155 2156 // We are reporting a leak. Walk up the graph to get to the first node where 2157 // the symbol appeared, and also get the first VarDecl that tracked object 2158 // is stored to. 2159 const ExplodedNode *AllocNode = 0; 2160 const MemRegion* FirstBinding = 0; 2161 2162 llvm::tie(AllocNode, FirstBinding) = 2163 GetAllocationSite(BRC.getStateManager(), EndN, Sym); 2164 2165 SourceManager& SM = BRC.getSourceManager(); 2166 2167 // Compute an actual location for the leak. Sometimes a leak doesn't 2168 // occur at an actual statement (e.g., transition between blocks; end 2169 // of function) so we need to walk the graph and compute a real location. 2170 const ExplodedNode *LeakN = EndN; 2171 PathDiagnosticLocation L = PathDiagnosticLocation::createEndOfPath(LeakN, SM); 2172 2173 std::string sbuf; 2174 llvm::raw_string_ostream os(sbuf); 2175 2176 os << "Object leaked: "; 2177 2178 if (FirstBinding) { 2179 os << "object allocated and stored into '" 2180 << FirstBinding->getString() << '\''; 2181 } 2182 else 2183 os << "allocated object"; 2184 2185 // Get the retain count. 2186 const RefVal* RV = EndN->getState()->get<RefBindings>(Sym); 2187 2188 if (RV->getKind() == RefVal::ErrorLeakReturned) { 2189 // FIXME: Per comments in rdar://6320065, "create" only applies to CF 2190 // objects. Only "copy", "alloc", "retain" and "new" transfer ownership 2191 // to the caller for NS objects. 2192 const Decl *D = &EndN->getCodeDecl(); 2193 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) { 2194 os << " is returned from a method whose name ('" 2195 << MD->getSelector().getAsString() 2196 << "') does not start with 'copy', 'mutableCopy', 'alloc' or 'new'." 2197 " This violates the naming convention rules" 2198 " given in the Memory Management Guide for Cocoa"; 2199 } 2200 else { 2201 const FunctionDecl *FD = cast<FunctionDecl>(D); 2202 os << " is return from a function whose name ('" 2203 << FD->getNameAsString() 2204 << "') does not contain 'Copy' or 'Create'. This violates the naming" 2205 " convention rules given the Memory Management Guide for Core" 2206 " Foundation"; 2207 } 2208 } 2209 else if (RV->getKind() == RefVal::ErrorGCLeakReturned) { 2210 ObjCMethodDecl &MD = cast<ObjCMethodDecl>(EndN->getCodeDecl()); 2211 os << " and returned from method '" << MD.getSelector().getAsString() 2212 << "' is potentially leaked when using garbage collection. Callers " 2213 "of this method do not expect a returned object with a +1 retain " 2214 "count since they expect the object to be managed by the garbage " 2215 "collector"; 2216 } 2217 else 2218 os << " is not referenced later in this execution path and has a retain " 2219 "count of +" << RV->getCount(); 2220 2221 return new PathDiagnosticEventPiece(L, os.str()); 2222} 2223 2224CFRefLeakReport::CFRefLeakReport(CFRefBug &D, const LangOptions &LOpts, 2225 bool GCEnabled, const SummaryLogTy &Log, 2226 ExplodedNode *n, SymbolRef sym, 2227 ExprEngine &Eng) 2228: CFRefReport(D, LOpts, GCEnabled, Log, n, sym, false) { 2229 2230 // Most bug reports are cached at the location where they occurred. 2231 // With leaks, we want to unique them by the location where they were 2232 // allocated, and only report a single path. To do this, we need to find 2233 // the allocation site of a piece of tracked memory, which we do via a 2234 // call to GetAllocationSite. This will walk the ExplodedGraph backwards. 2235 // Note that this is *not* the trimmed graph; we are guaranteed, however, 2236 // that all ancestor nodes that represent the allocation site have the 2237 // same SourceLocation. 2238 const ExplodedNode *AllocNode = 0; 2239 2240 const SourceManager& SMgr = Eng.getContext().getSourceManager(); 2241 2242 llvm::tie(AllocNode, AllocBinding) = // Set AllocBinding. 2243 GetAllocationSite(Eng.getStateManager(), getErrorNode(), sym); 2244 2245 // Get the SourceLocation for the allocation site. 2246 ProgramPoint P = AllocNode->getLocation(); 2247 const Stmt *AllocStmt = cast<PostStmt>(P).getStmt(); 2248 Location = PathDiagnosticLocation::createBegin(AllocStmt, SMgr, 2249 n->getLocationContext()); 2250 // Fill in the description of the bug. 2251 Description.clear(); 2252 llvm::raw_string_ostream os(Description); 2253 unsigned AllocLine = SMgr.getExpansionLineNumber(AllocStmt->getLocStart()); 2254 os << "Potential leak "; 2255 if (GCEnabled) 2256 os << "(when using garbage collection) "; 2257 os << "of an object allocated on line " << AllocLine; 2258 2259 // FIXME: AllocBinding doesn't get populated for RegionStore yet. 2260 if (AllocBinding) 2261 os << " and stored into '" << AllocBinding->getString() << '\''; 2262 2263 addVisitor(new CFRefLeakReportVisitor(sym, GCEnabled, Log)); 2264} 2265 2266//===----------------------------------------------------------------------===// 2267// Main checker logic. 2268//===----------------------------------------------------------------------===// 2269 2270namespace { 2271class RetainCountChecker 2272 : public Checker< check::Bind, 2273 check::DeadSymbols, 2274 check::EndAnalysis, 2275 check::EndPath, 2276 check::PostStmt<BlockExpr>, 2277 check::PostStmt<CastExpr>, 2278 check::PostStmt<CallExpr>, 2279 check::PostStmt<CXXConstructExpr>, 2280 check::PostObjCMessage, 2281 check::PreStmt<ReturnStmt>, 2282 check::RegionChanges, 2283 eval::Assume, 2284 eval::Call > { 2285 mutable llvm::OwningPtr<CFRefBug> useAfterRelease, releaseNotOwned; 2286 mutable llvm::OwningPtr<CFRefBug> deallocGC, deallocNotOwned; 2287 mutable llvm::OwningPtr<CFRefBug> overAutorelease, returnNotOwnedForOwned; 2288 mutable llvm::OwningPtr<CFRefBug> leakWithinFunction, leakAtReturn; 2289 mutable llvm::OwningPtr<CFRefBug> leakWithinFunctionGC, leakAtReturnGC; 2290 2291 typedef llvm::DenseMap<SymbolRef, const SimpleProgramPointTag *> SymbolTagMap; 2292 2293 // This map is only used to ensure proper deletion of any allocated tags. 2294 mutable SymbolTagMap DeadSymbolTags; 2295 2296 mutable llvm::OwningPtr<RetainSummaryManager> Summaries; 2297 mutable llvm::OwningPtr<RetainSummaryManager> SummariesGC; 2298 2299 mutable ARCounts::Factory ARCountFactory; 2300 2301 mutable SummaryLogTy SummaryLog; 2302 mutable bool ShouldResetSummaryLog; 2303 2304public: 2305 RetainCountChecker() : ShouldResetSummaryLog(false) {} 2306 2307 virtual ~RetainCountChecker() { 2308 DeleteContainerSeconds(DeadSymbolTags); 2309 } 2310 2311 void checkEndAnalysis(ExplodedGraph &G, BugReporter &BR, 2312 ExprEngine &Eng) const { 2313 // FIXME: This is a hack to make sure the summary log gets cleared between 2314 // analyses of different code bodies. 2315 // 2316 // Why is this necessary? Because a checker's lifetime is tied to a 2317 // translation unit, but an ExplodedGraph's lifetime is just a code body. 2318 // Once in a blue moon, a new ExplodedNode will have the same address as an 2319 // old one with an associated summary, and the bug report visitor gets very 2320 // confused. (To make things worse, the summary lifetime is currently also 2321 // tied to a code body, so we get a crash instead of incorrect results.) 2322 // 2323 // Why is this a bad solution? Because if the lifetime of the ExplodedGraph 2324 // changes, things will start going wrong again. Really the lifetime of this 2325 // log needs to be tied to either the specific nodes in it or the entire 2326 // ExplodedGraph, not to a specific part of the code being analyzed. 2327 // 2328 // (Also, having stateful local data means that the same checker can't be 2329 // used from multiple threads, but a lot of checkers have incorrect 2330 // assumptions about that anyway. So that wasn't a priority at the time of 2331 // this fix.) 2332 // 2333 // This happens at the end of analysis, but bug reports are emitted /after/ 2334 // this point. So we can't just clear the summary log now. Instead, we mark 2335 // that the next time we access the summary log, it should be cleared. 2336 2337 // If we never reset the summary log during /this/ code body analysis, 2338 // there were no new summaries. There might still have been summaries from 2339 // the /last/ analysis, so clear them out to make sure the bug report 2340 // visitors don't get confused. 2341 if (ShouldResetSummaryLog) 2342 SummaryLog.clear(); 2343 2344 ShouldResetSummaryLog = !SummaryLog.empty(); 2345 } 2346 2347 CFRefBug *getLeakWithinFunctionBug(const LangOptions &LOpts, 2348 bool GCEnabled) const { 2349 if (GCEnabled) { 2350 if (!leakWithinFunctionGC) 2351 leakWithinFunctionGC.reset(new LeakWithinFunction("Leak of object when " 2352 "using garbage " 2353 "collection")); 2354 return leakWithinFunctionGC.get(); 2355 } else { 2356 if (!leakWithinFunction) { 2357 if (LOpts.getGC() == LangOptions::HybridGC) { 2358 leakWithinFunction.reset(new LeakWithinFunction("Leak of object when " 2359 "not using garbage " 2360 "collection (GC) in " 2361 "dual GC/non-GC " 2362 "code")); 2363 } else { 2364 leakWithinFunction.reset(new LeakWithinFunction("Leak")); 2365 } 2366 } 2367 return leakWithinFunction.get(); 2368 } 2369 } 2370 2371 CFRefBug *getLeakAtReturnBug(const LangOptions &LOpts, bool GCEnabled) const { 2372 if (GCEnabled) { 2373 if (!leakAtReturnGC) 2374 leakAtReturnGC.reset(new LeakAtReturn("Leak of returned object when " 2375 "using garbage collection")); 2376 return leakAtReturnGC.get(); 2377 } else { 2378 if (!leakAtReturn) { 2379 if (LOpts.getGC() == LangOptions::HybridGC) { 2380 leakAtReturn.reset(new LeakAtReturn("Leak of returned object when " 2381 "not using garbage collection " 2382 "(GC) in dual GC/non-GC code")); 2383 } else { 2384 leakAtReturn.reset(new LeakAtReturn("Leak of returned object")); 2385 } 2386 } 2387 return leakAtReturn.get(); 2388 } 2389 } 2390 2391 RetainSummaryManager &getSummaryManager(ASTContext &Ctx, 2392 bool GCEnabled) const { 2393 // FIXME: We don't support ARC being turned on and off during one analysis. 2394 // (nor, for that matter, do we support changing ASTContexts) 2395 bool ARCEnabled = (bool)Ctx.getLangOptions().ObjCAutoRefCount; 2396 if (GCEnabled) { 2397 if (!SummariesGC) 2398 SummariesGC.reset(new RetainSummaryManager(Ctx, true, ARCEnabled)); 2399 else 2400 assert(SummariesGC->isARCEnabled() == ARCEnabled); 2401 return *SummariesGC; 2402 } else { 2403 if (!Summaries) 2404 Summaries.reset(new RetainSummaryManager(Ctx, false, ARCEnabled)); 2405 else 2406 assert(Summaries->isARCEnabled() == ARCEnabled); 2407 return *Summaries; 2408 } 2409 } 2410 2411 RetainSummaryManager &getSummaryManager(CheckerContext &C) const { 2412 return getSummaryManager(C.getASTContext(), C.isObjCGCEnabled()); 2413 } 2414 2415 void printState(raw_ostream &Out, const ProgramState *State, 2416 const char *NL, const char *Sep) const; 2417 2418 void checkBind(SVal loc, SVal val, const Stmt *S, CheckerContext &C) const; 2419 void checkPostStmt(const BlockExpr *BE, CheckerContext &C) const; 2420 void checkPostStmt(const CastExpr *CE, CheckerContext &C) const; 2421 2422 void checkPostStmt(const CallExpr *CE, CheckerContext &C) const; 2423 void checkPostStmt(const CXXConstructExpr *CE, CheckerContext &C) const; 2424 void checkPostObjCMessage(const ObjCMessage &Msg, CheckerContext &C) const; 2425 void checkSummary(const RetainSummary &Summ, const CallOrObjCMessage &Call, 2426 CheckerContext &C) const; 2427 2428 bool evalCall(const CallExpr *CE, CheckerContext &C) const; 2429 2430 const ProgramState *evalAssume(const ProgramState *state, SVal Cond, 2431 bool Assumption) const; 2432 2433 const ProgramState * 2434 checkRegionChanges(const ProgramState *state, 2435 const StoreManager::InvalidatedSymbols *invalidated, 2436 ArrayRef<const MemRegion *> ExplicitRegions, 2437 ArrayRef<const MemRegion *> Regions) const; 2438 2439 bool wantsRegionChangeUpdate(const ProgramState *state) const { 2440 return true; 2441 } 2442 2443 void checkPreStmt(const ReturnStmt *S, CheckerContext &C) const; 2444 void checkReturnWithRetEffect(const ReturnStmt *S, CheckerContext &C, 2445 ExplodedNode *Pred, RetEffect RE, RefVal X, 2446 SymbolRef Sym, const ProgramState *state) const; 2447 2448 void checkDeadSymbols(SymbolReaper &SymReaper, CheckerContext &C) const; 2449 void checkEndPath(EndOfFunctionNodeBuilder &Builder, ExprEngine &Eng) const; 2450 2451 const ProgramState *updateSymbol(const ProgramState *state, SymbolRef sym, 2452 RefVal V, ArgEffect E, RefVal::Kind &hasErr, 2453 CheckerContext &C) const; 2454 2455 void processNonLeakError(const ProgramState *St, SourceRange ErrorRange, 2456 RefVal::Kind ErrorKind, SymbolRef Sym, 2457 CheckerContext &C) const; 2458 2459 const ProgramPointTag *getDeadSymbolTag(SymbolRef sym) const; 2460 2461 const ProgramState *handleSymbolDeath(const ProgramState *state, 2462 SymbolRef sid, RefVal V, 2463 SmallVectorImpl<SymbolRef> &Leaked) const; 2464 2465 std::pair<ExplodedNode *, const ProgramState *> 2466 handleAutoreleaseCounts(const ProgramState *state, 2467 GenericNodeBuilderRefCount Bd, ExplodedNode *Pred, 2468 ExprEngine &Eng, SymbolRef Sym, RefVal V) const; 2469 2470 ExplodedNode *processLeaks(const ProgramState *state, 2471 SmallVectorImpl<SymbolRef> &Leaked, 2472 GenericNodeBuilderRefCount &Builder, 2473 ExprEngine &Eng, 2474 ExplodedNode *Pred = 0) const; 2475}; 2476} // end anonymous namespace 2477 2478namespace { 2479class StopTrackingCallback : public SymbolVisitor { 2480 const ProgramState *state; 2481public: 2482 StopTrackingCallback(const ProgramState *st) : state(st) {} 2483 const ProgramState *getState() const { return state; } 2484 2485 bool VisitSymbol(SymbolRef sym) { 2486 state = state->remove<RefBindings>(sym); 2487 return true; 2488 } 2489}; 2490} // end anonymous namespace 2491 2492//===----------------------------------------------------------------------===// 2493// Handle statements that may have an effect on refcounts. 2494//===----------------------------------------------------------------------===// 2495 2496void RetainCountChecker::checkPostStmt(const BlockExpr *BE, 2497 CheckerContext &C) const { 2498 2499 // Scan the BlockDecRefExprs for any object the retain count checker 2500 // may be tracking. 2501 if (!BE->getBlockDecl()->hasCaptures()) 2502 return; 2503 2504 const ProgramState *state = C.getState(); 2505 const BlockDataRegion *R = 2506 cast<BlockDataRegion>(state->getSVal(BE).getAsRegion()); 2507 2508 BlockDataRegion::referenced_vars_iterator I = R->referenced_vars_begin(), 2509 E = R->referenced_vars_end(); 2510 2511 if (I == E) 2512 return; 2513 2514 // FIXME: For now we invalidate the tracking of all symbols passed to blocks 2515 // via captured variables, even though captured variables result in a copy 2516 // and in implicit increment/decrement of a retain count. 2517 SmallVector<const MemRegion*, 10> Regions; 2518 const LocationContext *LC = C.getPredecessor()->getLocationContext(); 2519 MemRegionManager &MemMgr = C.getSValBuilder().getRegionManager(); 2520 2521 for ( ; I != E; ++I) { 2522 const VarRegion *VR = *I; 2523 if (VR->getSuperRegion() == R) { 2524 VR = MemMgr.getVarRegion(VR->getDecl(), LC); 2525 } 2526 Regions.push_back(VR); 2527 } 2528 2529 state = 2530 state->scanReachableSymbols<StopTrackingCallback>(Regions.data(), 2531 Regions.data() + Regions.size()).getState(); 2532 C.addTransition(state); 2533} 2534 2535void RetainCountChecker::checkPostStmt(const CastExpr *CE, 2536 CheckerContext &C) const { 2537 const ObjCBridgedCastExpr *BE = dyn_cast<ObjCBridgedCastExpr>(CE); 2538 if (!BE) 2539 return; 2540 2541 ArgEffect AE = IncRef; 2542 2543 switch (BE->getBridgeKind()) { 2544 case clang::OBC_Bridge: 2545 // Do nothing. 2546 return; 2547 case clang::OBC_BridgeRetained: 2548 AE = IncRef; 2549 break; 2550 case clang::OBC_BridgeTransfer: 2551 AE = DecRefBridgedTransfered; 2552 break; 2553 } 2554 2555 const ProgramState *state = C.getState(); 2556 SymbolRef Sym = state->getSVal(CE).getAsLocSymbol(); 2557 if (!Sym) 2558 return; 2559 const RefVal* T = state->get<RefBindings>(Sym); 2560 if (!T) 2561 return; 2562 2563 RefVal::Kind hasErr = (RefVal::Kind) 0; 2564 state = updateSymbol(state, Sym, *T, AE, hasErr, C); 2565 2566 if (hasErr) { 2567 // FIXME: If we get an error during a bridge cast, should we report it? 2568 // Should we assert that there is no error? 2569 return; 2570 } 2571 2572 C.generateNode(state); 2573} 2574 2575void RetainCountChecker::checkPostStmt(const CallExpr *CE, 2576 CheckerContext &C) const { 2577 // Get the callee. 2578 const ProgramState *state = C.getState(); 2579 const Expr *Callee = CE->getCallee(); 2580 SVal L = state->getSVal(Callee); 2581 2582 RetainSummaryManager &Summaries = getSummaryManager(C); 2583 const RetainSummary *Summ = 0; 2584 2585 // FIXME: Better support for blocks. For now we stop tracking anything 2586 // that is passed to blocks. 2587 // FIXME: Need to handle variables that are "captured" by the block. 2588 if (dyn_cast_or_null<BlockDataRegion>(L.getAsRegion())) { 2589 Summ = Summaries.getPersistentStopSummary(); 2590 } else if (const FunctionDecl *FD = L.getAsFunctionDecl()) { 2591 Summ = Summaries.getSummary(FD); 2592 } else if (const CXXMemberCallExpr *me = dyn_cast<CXXMemberCallExpr>(CE)) { 2593 if (const CXXMethodDecl *MD = me->getMethodDecl()) 2594 Summ = Summaries.getSummary(MD); 2595 } 2596 2597 if (!Summ) 2598 Summ = Summaries.getDefaultSummary(); 2599 2600 checkSummary(*Summ, CallOrObjCMessage(CE, state), C); 2601} 2602 2603void RetainCountChecker::checkPostStmt(const CXXConstructExpr *CE, 2604 CheckerContext &C) const { 2605 const CXXConstructorDecl *Ctor = CE->getConstructor(); 2606 if (!Ctor) 2607 return; 2608 2609 RetainSummaryManager &Summaries = getSummaryManager(C); 2610 const RetainSummary *Summ = Summaries.getSummary(Ctor); 2611 2612 // If we didn't get a summary, this constructor doesn't affect retain counts. 2613 if (!Summ) 2614 return; 2615 2616 const ProgramState *state = C.getState(); 2617 checkSummary(*Summ, CallOrObjCMessage(CE, state), C); 2618} 2619 2620void RetainCountChecker::checkPostObjCMessage(const ObjCMessage &Msg, 2621 CheckerContext &C) const { 2622 const ProgramState *state = C.getState(); 2623 ExplodedNode *Pred = C.getPredecessor(); 2624 2625 RetainSummaryManager &Summaries = getSummaryManager(C); 2626 2627 const RetainSummary *Summ; 2628 if (Msg.isInstanceMessage()) { 2629 const LocationContext *LC = Pred->getLocationContext(); 2630 Summ = Summaries.getInstanceMethodSummary(Msg, state, LC); 2631 } else { 2632 Summ = Summaries.getClassMethodSummary(Msg); 2633 } 2634 2635 // If we didn't get a summary, this message doesn't affect retain counts. 2636 if (!Summ) 2637 return; 2638 2639 checkSummary(*Summ, CallOrObjCMessage(Msg, state), C); 2640} 2641 2642/// GetReturnType - Used to get the return type of a message expression or 2643/// function call with the intention of affixing that type to a tracked symbol. 2644/// While the the return type can be queried directly from RetEx, when 2645/// invoking class methods we augment to the return type to be that of 2646/// a pointer to the class (as opposed it just being id). 2647// FIXME: We may be able to do this with related result types instead. 2648// This function is probably overestimating. 2649static QualType GetReturnType(const Expr *RetE, ASTContext &Ctx) { 2650 QualType RetTy = RetE->getType(); 2651 // If RetE is not a message expression just return its type. 2652 // If RetE is a message expression, return its types if it is something 2653 /// more specific than id. 2654 if (const ObjCMessageExpr *ME = dyn_cast<ObjCMessageExpr>(RetE)) 2655 if (const ObjCObjectPointerType *PT = RetTy->getAs<ObjCObjectPointerType>()) 2656 if (PT->isObjCQualifiedIdType() || PT->isObjCIdType() || 2657 PT->isObjCClassType()) { 2658 // At this point we know the return type of the message expression is 2659 // id, id<...>, or Class. If we have an ObjCInterfaceDecl, we know this 2660 // is a call to a class method whose type we can resolve. In such 2661 // cases, promote the return type to XXX* (where XXX is the class). 2662 const ObjCInterfaceDecl *D = ME->getReceiverInterface(); 2663 return !D ? RetTy : 2664 Ctx.getObjCObjectPointerType(Ctx.getObjCInterfaceType(D)); 2665 } 2666 2667 return RetTy; 2668} 2669 2670void RetainCountChecker::checkSummary(const RetainSummary &Summ, 2671 const CallOrObjCMessage &CallOrMsg, 2672 CheckerContext &C) const { 2673 const ProgramState *state = C.getState(); 2674 2675 // Evaluate the effect of the arguments. 2676 RefVal::Kind hasErr = (RefVal::Kind) 0; 2677 SourceRange ErrorRange; 2678 SymbolRef ErrorSym = 0; 2679 2680 for (unsigned idx = 0, e = CallOrMsg.getNumArgs(); idx != e; ++idx) { 2681 SVal V = CallOrMsg.getArgSVal(idx); 2682 2683 if (SymbolRef Sym = V.getAsLocSymbol()) { 2684 if (RefBindings::data_type *T = state->get<RefBindings>(Sym)) { 2685 state = updateSymbol(state, Sym, *T, Summ.getArg(idx), hasErr, C); 2686 if (hasErr) { 2687 ErrorRange = CallOrMsg.getArgSourceRange(idx); 2688 ErrorSym = Sym; 2689 break; 2690 } 2691 } 2692 } 2693 } 2694 2695 // Evaluate the effect on the message receiver. 2696 bool ReceiverIsTracked = false; 2697 if (!hasErr && CallOrMsg.isObjCMessage()) { 2698 const LocationContext *LC = C.getPredecessor()->getLocationContext(); 2699 SVal Receiver = CallOrMsg.getInstanceMessageReceiver(LC); 2700 if (SymbolRef Sym = Receiver.getAsLocSymbol()) { 2701 if (const RefVal *T = state->get<RefBindings>(Sym)) { 2702 ReceiverIsTracked = true; 2703 state = updateSymbol(state, Sym, *T, Summ.getReceiverEffect(), 2704 hasErr, C); 2705 if (hasErr) { 2706 ErrorRange = CallOrMsg.getReceiverSourceRange(); 2707 ErrorSym = Sym; 2708 } 2709 } 2710 } 2711 } 2712 2713 // Process any errors. 2714 if (hasErr) { 2715 processNonLeakError(state, ErrorRange, hasErr, ErrorSym, C); 2716 return; 2717 } 2718 2719 // Consult the summary for the return value. 2720 RetEffect RE = Summ.getRetEffect(); 2721 2722 if (RE.getKind() == RetEffect::OwnedWhenTrackedReceiver) { 2723 if (ReceiverIsTracked) 2724 RE = getSummaryManager(C).getObjAllocRetEffect(); 2725 else 2726 RE = RetEffect::MakeNoRet(); 2727 } 2728 2729 switch (RE.getKind()) { 2730 default: 2731 llvm_unreachable("Unhandled RetEffect."); break; 2732 2733 case RetEffect::NoRet: 2734 // No work necessary. 2735 break; 2736 2737 case RetEffect::OwnedAllocatedSymbol: 2738 case RetEffect::OwnedSymbol: { 2739 SymbolRef Sym = state->getSVal(CallOrMsg.getOriginExpr()).getAsSymbol(); 2740 if (!Sym) 2741 break; 2742 2743 // Use the result type from callOrMsg as it automatically adjusts 2744 // for methods/functions that return references. 2745 QualType ResultTy = CallOrMsg.getResultType(C.getASTContext()); 2746 state = state->set<RefBindings>(Sym, RefVal::makeOwned(RE.getObjKind(), 2747 ResultTy)); 2748 2749 // FIXME: Add a flag to the checker where allocations are assumed to 2750 // *not* fail. (The code below is out-of-date, though.) 2751#if 0 2752 if (RE.getKind() == RetEffect::OwnedAllocatedSymbol) { 2753 bool isFeasible; 2754 state = state.assume(loc::SymbolVal(Sym), true, isFeasible); 2755 assert(isFeasible && "Cannot assume fresh symbol is non-null."); 2756 } 2757#endif 2758 2759 break; 2760 } 2761 2762 case RetEffect::GCNotOwnedSymbol: 2763 case RetEffect::ARCNotOwnedSymbol: 2764 case RetEffect::NotOwnedSymbol: { 2765 const Expr *Ex = CallOrMsg.getOriginExpr(); 2766 SymbolRef Sym = state->getSVal(Ex).getAsSymbol(); 2767 if (!Sym) 2768 break; 2769 2770 // Use GetReturnType in order to give [NSFoo alloc] the type NSFoo *. 2771 QualType ResultTy = GetReturnType(Ex, C.getASTContext()); 2772 state = state->set<RefBindings>(Sym, RefVal::makeNotOwned(RE.getObjKind(), 2773 ResultTy)); 2774 break; 2775 } 2776 } 2777 2778 // This check is actually necessary; otherwise the statement builder thinks 2779 // we've hit a previously-found path. 2780 // Normally addTransition takes care of this, but we want the node pointer. 2781 ExplodedNode *NewNode; 2782 if (state == C.getState()) { 2783 NewNode = C.getPredecessor(); 2784 } else { 2785 NewNode = C.generateNode(state); 2786 } 2787 2788 // Annotate the node with summary we used. 2789 if (NewNode) { 2790 // FIXME: This is ugly. See checkEndAnalysis for why it's necessary. 2791 if (ShouldResetSummaryLog) { 2792 SummaryLog.clear(); 2793 ShouldResetSummaryLog = false; 2794 } 2795 SummaryLog[NewNode] = &Summ; 2796 } 2797} 2798 2799 2800const ProgramState * 2801RetainCountChecker::updateSymbol(const ProgramState *state, SymbolRef sym, 2802 RefVal V, ArgEffect E, RefVal::Kind &hasErr, 2803 CheckerContext &C) const { 2804 // In GC mode [... release] and [... retain] do nothing. 2805 // In ARC mode they shouldn't exist at all, but we just ignore them. 2806 bool IgnoreRetainMsg = C.isObjCGCEnabled(); 2807 if (!IgnoreRetainMsg) 2808 IgnoreRetainMsg = (bool)C.getASTContext().getLangOptions().ObjCAutoRefCount; 2809 2810 switch (E) { 2811 default: break; 2812 case IncRefMsg: E = IgnoreRetainMsg ? DoNothing : IncRef; break; 2813 case DecRefMsg: E = IgnoreRetainMsg ? DoNothing : DecRef; break; 2814 case MakeCollectable: E = C.isObjCGCEnabled() ? DecRef : DoNothing; break; 2815 case NewAutoreleasePool: E = C.isObjCGCEnabled() ? DoNothing : 2816 NewAutoreleasePool; break; 2817 } 2818 2819 // Handle all use-after-releases. 2820 if (!C.isObjCGCEnabled() && V.getKind() == RefVal::Released) { 2821 V = V ^ RefVal::ErrorUseAfterRelease; 2822 hasErr = V.getKind(); 2823 return state->set<RefBindings>(sym, V); 2824 } 2825 2826 switch (E) { 2827 case DecRefMsg: 2828 case IncRefMsg: 2829 case MakeCollectable: 2830 llvm_unreachable("DecRefMsg/IncRefMsg/MakeCollectable already converted"); 2831 return state; 2832 2833 case Dealloc: 2834 // Any use of -dealloc in GC is *bad*. 2835 if (C.isObjCGCEnabled()) { 2836 V = V ^ RefVal::ErrorDeallocGC; 2837 hasErr = V.getKind(); 2838 break; 2839 } 2840 2841 switch (V.getKind()) { 2842 default: 2843 llvm_unreachable("Invalid RefVal state for an explicit dealloc."); 2844 break; 2845 case RefVal::Owned: 2846 // The object immediately transitions to the released state. 2847 V = V ^ RefVal::Released; 2848 V.clearCounts(); 2849 return state->set<RefBindings>(sym, V); 2850 case RefVal::NotOwned: 2851 V = V ^ RefVal::ErrorDeallocNotOwned; 2852 hasErr = V.getKind(); 2853 break; 2854 } 2855 break; 2856 2857 case NewAutoreleasePool: 2858 assert(!C.isObjCGCEnabled()); 2859 return state->add<AutoreleaseStack>(sym); 2860 2861 case MayEscape: 2862 if (V.getKind() == RefVal::Owned) { 2863 V = V ^ RefVal::NotOwned; 2864 break; 2865 } 2866 2867 // Fall-through. 2868 2869 case DoNothing: 2870 return state; 2871 2872 case Autorelease: 2873 if (C.isObjCGCEnabled()) 2874 return state; 2875 2876 // Update the autorelease counts. 2877 state = SendAutorelease(state, ARCountFactory, sym); 2878 V = V.autorelease(); 2879 break; 2880 2881 case StopTracking: 2882 return state->remove<RefBindings>(sym); 2883 2884 case IncRef: 2885 switch (V.getKind()) { 2886 default: 2887 llvm_unreachable("Invalid RefVal state for a retain."); 2888 break; 2889 case RefVal::Owned: 2890 case RefVal::NotOwned: 2891 V = V + 1; 2892 break; 2893 case RefVal::Released: 2894 // Non-GC cases are handled above. 2895 assert(C.isObjCGCEnabled()); 2896 V = (V ^ RefVal::Owned) + 1; 2897 break; 2898 } 2899 break; 2900 2901 case SelfOwn: 2902 V = V ^ RefVal::NotOwned; 2903 // Fall-through. 2904 case DecRef: 2905 case DecRefBridgedTransfered: 2906 switch (V.getKind()) { 2907 default: 2908 // case 'RefVal::Released' handled above. 2909 llvm_unreachable("Invalid RefVal state for a release."); 2910 break; 2911 2912 case RefVal::Owned: 2913 assert(V.getCount() > 0); 2914 if (V.getCount() == 1) 2915 V = V ^ (E == DecRefBridgedTransfered ? 2916 RefVal::NotOwned : RefVal::Released); 2917 V = V - 1; 2918 break; 2919 2920 case RefVal::NotOwned: 2921 if (V.getCount() > 0) 2922 V = V - 1; 2923 else { 2924 V = V ^ RefVal::ErrorReleaseNotOwned; 2925 hasErr = V.getKind(); 2926 } 2927 break; 2928 2929 case RefVal::Released: 2930 // Non-GC cases are handled above. 2931 assert(C.isObjCGCEnabled()); 2932 V = V ^ RefVal::ErrorUseAfterRelease; 2933 hasErr = V.getKind(); 2934 break; 2935 } 2936 break; 2937 } 2938 return state->set<RefBindings>(sym, V); 2939} 2940 2941void RetainCountChecker::processNonLeakError(const ProgramState *St, 2942 SourceRange ErrorRange, 2943 RefVal::Kind ErrorKind, 2944 SymbolRef Sym, 2945 CheckerContext &C) const { 2946 ExplodedNode *N = C.generateSink(St); 2947 if (!N) 2948 return; 2949 2950 CFRefBug *BT; 2951 switch (ErrorKind) { 2952 default: 2953 llvm_unreachable("Unhandled error."); 2954 return; 2955 case RefVal::ErrorUseAfterRelease: 2956 if (!useAfterRelease) 2957 useAfterRelease.reset(new UseAfterRelease()); 2958 BT = &*useAfterRelease; 2959 break; 2960 case RefVal::ErrorReleaseNotOwned: 2961 if (!releaseNotOwned) 2962 releaseNotOwned.reset(new BadRelease()); 2963 BT = &*releaseNotOwned; 2964 break; 2965 case RefVal::ErrorDeallocGC: 2966 if (!deallocGC) 2967 deallocGC.reset(new DeallocGC()); 2968 BT = &*deallocGC; 2969 break; 2970 case RefVal::ErrorDeallocNotOwned: 2971 if (!deallocNotOwned) 2972 deallocNotOwned.reset(new DeallocNotOwned()); 2973 BT = &*deallocNotOwned; 2974 break; 2975 } 2976 2977 assert(BT); 2978 CFRefReport *report = new CFRefReport(*BT, C.getASTContext().getLangOptions(), 2979 C.isObjCGCEnabled(), SummaryLog, 2980 N, Sym); 2981 report->addRange(ErrorRange); 2982 C.EmitReport(report); 2983} 2984 2985//===----------------------------------------------------------------------===// 2986// Handle the return values of retain-count-related functions. 2987//===----------------------------------------------------------------------===// 2988 2989bool RetainCountChecker::evalCall(const CallExpr *CE, CheckerContext &C) const { 2990 // Get the callee. We're only interested in simple C functions. 2991 const ProgramState *state = C.getState(); 2992 const Expr *Callee = CE->getCallee(); 2993 SVal L = state->getSVal(Callee); 2994 2995 const FunctionDecl *FD = L.getAsFunctionDecl(); 2996 if (!FD) 2997 return false; 2998 2999 IdentifierInfo *II = FD->getIdentifier(); 3000 if (!II) 3001 return false; 3002 3003 // For now, we're only handling the functions that return aliases of their 3004 // arguments: CFRetain and CFMakeCollectable (and their families). 3005 // Eventually we should add other functions we can model entirely, 3006 // such as CFRelease, which don't invalidate their arguments or globals. 3007 if (CE->getNumArgs() != 1) 3008 return false; 3009 3010 // Get the name of the function. 3011 StringRef FName = II->getName(); 3012 FName = FName.substr(FName.find_first_not_of('_')); 3013 3014 // See if it's one of the specific functions we know how to eval. 3015 bool canEval = false; 3016 3017 QualType ResultTy = FD->getResultType(); 3018 if (ResultTy->isObjCIdType()) { 3019 // Handle: id NSMakeCollectable(CFTypeRef) 3020 canEval = II->isStr("NSMakeCollectable"); 3021 } else if (ResultTy->isPointerType()) { 3022 // Handle: (CF|CG)Retain 3023 // CFMakeCollectable 3024 // It's okay to be a little sloppy here (CGMakeCollectable doesn't exist). 3025 if (cocoa::isRefType(ResultTy, "CF", FName) || 3026 cocoa::isRefType(ResultTy, "CG", FName)) { 3027 canEval = isRetain(FD, FName) || isMakeCollectable(FD, FName); 3028 } 3029 } 3030 3031 if (!canEval) 3032 return false; 3033 3034 // Bind the return value. 3035 SVal RetVal = state->getSVal(CE->getArg(0)); 3036 if (RetVal.isUnknown()) { 3037 // If the receiver is unknown, conjure a return value. 3038 SValBuilder &SVB = C.getSValBuilder(); 3039 unsigned Count = C.getCurrentBlockCount(); 3040 SVal RetVal = SVB.getConjuredSymbolVal(0, CE, ResultTy, Count); 3041 } 3042 state = state->BindExpr(CE, RetVal, false); 3043 3044 // FIXME: This should not be necessary, but otherwise the argument seems to be 3045 // considered alive during the next statement. 3046 if (const MemRegion *ArgRegion = RetVal.getAsRegion()) { 3047 // Save the refcount status of the argument. 3048 SymbolRef Sym = RetVal.getAsLocSymbol(); 3049 RefBindings::data_type *Binding = 0; 3050 if (Sym) 3051 Binding = state->get<RefBindings>(Sym); 3052 3053 // Invalidate the argument region. 3054 unsigned Count = C.getCurrentBlockCount(); 3055 state = state->invalidateRegions(ArgRegion, CE, Count); 3056 3057 // Restore the refcount status of the argument. 3058 if (Binding) 3059 state = state->set<RefBindings>(Sym, *Binding); 3060 } 3061 3062 C.addTransition(state); 3063 return true; 3064} 3065 3066//===----------------------------------------------------------------------===// 3067// Handle return statements. 3068//===----------------------------------------------------------------------===// 3069 3070void RetainCountChecker::checkPreStmt(const ReturnStmt *S, 3071 CheckerContext &C) const { 3072 const Expr *RetE = S->getRetValue(); 3073 if (!RetE) 3074 return; 3075 3076 const ProgramState *state = C.getState(); 3077 SymbolRef Sym = state->getSValAsScalarOrLoc(RetE).getAsLocSymbol(); 3078 if (!Sym) 3079 return; 3080 3081 // Get the reference count binding (if any). 3082 const RefVal *T = state->get<RefBindings>(Sym); 3083 if (!T) 3084 return; 3085 3086 // Change the reference count. 3087 RefVal X = *T; 3088 3089 switch (X.getKind()) { 3090 case RefVal::Owned: { 3091 unsigned cnt = X.getCount(); 3092 assert(cnt > 0); 3093 X.setCount(cnt - 1); 3094 X = X ^ RefVal::ReturnedOwned; 3095 break; 3096 } 3097 3098 case RefVal::NotOwned: { 3099 unsigned cnt = X.getCount(); 3100 if (cnt) { 3101 X.setCount(cnt - 1); 3102 X = X ^ RefVal::ReturnedOwned; 3103 } 3104 else { 3105 X = X ^ RefVal::ReturnedNotOwned; 3106 } 3107 break; 3108 } 3109 3110 default: 3111 return; 3112 } 3113 3114 // Update the binding. 3115 state = state->set<RefBindings>(Sym, X); 3116 ExplodedNode *Pred = C.generateNode(state); 3117 3118 // At this point we have updated the state properly. 3119 // Everything after this is merely checking to see if the return value has 3120 // been over- or under-retained. 3121 3122 // Did we cache out? 3123 if (!Pred) 3124 return; 3125 3126 // Update the autorelease counts. 3127 static SimpleProgramPointTag 3128 AutoreleaseTag("RetainCountChecker : Autorelease"); 3129 GenericNodeBuilderRefCount Bd(C, &AutoreleaseTag); 3130 llvm::tie(Pred, state) = handleAutoreleaseCounts(state, Bd, Pred, 3131 C.getEngine(), Sym, X); 3132 3133 // Did we cache out? 3134 if (!Pred) 3135 return; 3136 3137 // Get the updated binding. 3138 T = state->get<RefBindings>(Sym); 3139 assert(T); 3140 X = *T; 3141 3142 // Consult the summary of the enclosing method. 3143 RetainSummaryManager &Summaries = getSummaryManager(C); 3144 const Decl *CD = &Pred->getCodeDecl(); 3145 3146 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(CD)) { 3147 // Unlike regular functions, /all/ ObjC methods are assumed to always 3148 // follow Cocoa retain-count conventions, not just those with special 3149 // names or attributes. 3150 const RetainSummary *Summ = Summaries.getMethodSummary(MD); 3151 RetEffect RE = Summ ? Summ->getRetEffect() : RetEffect::MakeNoRet(); 3152 checkReturnWithRetEffect(S, C, Pred, RE, X, Sym, state); 3153 } 3154 3155 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(CD)) { 3156 if (!isa<CXXMethodDecl>(FD)) 3157 if (const RetainSummary *Summ = Summaries.getSummary(FD)) 3158 checkReturnWithRetEffect(S, C, Pred, Summ->getRetEffect(), X, 3159 Sym, state); 3160 } 3161} 3162 3163void RetainCountChecker::checkReturnWithRetEffect(const ReturnStmt *S, 3164 CheckerContext &C, 3165 ExplodedNode *Pred, 3166 RetEffect RE, RefVal X, 3167 SymbolRef Sym, 3168 const ProgramState *state) const { 3169 // Any leaks or other errors? 3170 if (X.isReturnedOwned() && X.getCount() == 0) { 3171 if (RE.getKind() != RetEffect::NoRet) { 3172 bool hasError = false; 3173 if (C.isObjCGCEnabled() && RE.getObjKind() == RetEffect::ObjC) { 3174 // Things are more complicated with garbage collection. If the 3175 // returned object is suppose to be an Objective-C object, we have 3176 // a leak (as the caller expects a GC'ed object) because no 3177 // method should return ownership unless it returns a CF object. 3178 hasError = true; 3179 X = X ^ RefVal::ErrorGCLeakReturned; 3180 } 3181 else if (!RE.isOwned()) { 3182 // Either we are using GC and the returned object is a CF type 3183 // or we aren't using GC. In either case, we expect that the 3184 // enclosing method is expected to return ownership. 3185 hasError = true; 3186 X = X ^ RefVal::ErrorLeakReturned; 3187 } 3188 3189 if (hasError) { 3190 // Generate an error node. 3191 state = state->set<RefBindings>(Sym, X); 3192 3193 static SimpleProgramPointTag 3194 ReturnOwnLeakTag("RetainCountChecker : ReturnsOwnLeak"); 3195 ExplodedNode *N = C.generateNode(state, Pred, &ReturnOwnLeakTag); 3196 if (N) { 3197 const LangOptions &LOpts = C.getASTContext().getLangOptions(); 3198 bool GCEnabled = C.isObjCGCEnabled(); 3199 CFRefReport *report = 3200 new CFRefLeakReport(*getLeakAtReturnBug(LOpts, GCEnabled), 3201 LOpts, GCEnabled, SummaryLog, 3202 N, Sym, C.getEngine()); 3203 C.EmitReport(report); 3204 } 3205 } 3206 } 3207 } else if (X.isReturnedNotOwned()) { 3208 if (RE.isOwned()) { 3209 // Trying to return a not owned object to a caller expecting an 3210 // owned object. 3211 state = state->set<RefBindings>(Sym, X ^ RefVal::ErrorReturnedNotOwned); 3212 3213 static SimpleProgramPointTag 3214 ReturnNotOwnedTag("RetainCountChecker : ReturnNotOwnedForOwned"); 3215 ExplodedNode *N = C.generateNode(state, Pred, &ReturnNotOwnedTag); 3216 if (N) { 3217 if (!returnNotOwnedForOwned) 3218 returnNotOwnedForOwned.reset(new ReturnedNotOwnedForOwned()); 3219 3220 CFRefReport *report = 3221 new CFRefReport(*returnNotOwnedForOwned, 3222 C.getASTContext().getLangOptions(), 3223 C.isObjCGCEnabled(), SummaryLog, N, Sym); 3224 C.EmitReport(report); 3225 } 3226 } 3227 } 3228} 3229 3230//===----------------------------------------------------------------------===// 3231// Check various ways a symbol can be invalidated. 3232//===----------------------------------------------------------------------===// 3233 3234void RetainCountChecker::checkBind(SVal loc, SVal val, const Stmt *S, 3235 CheckerContext &C) const { 3236 // Are we storing to something that causes the value to "escape"? 3237 bool escapes = true; 3238 3239 // A value escapes in three possible cases (this may change): 3240 // 3241 // (1) we are binding to something that is not a memory region. 3242 // (2) we are binding to a memregion that does not have stack storage 3243 // (3) we are binding to a memregion with stack storage that the store 3244 // does not understand. 3245 const ProgramState *state = C.getState(); 3246 3247 if (loc::MemRegionVal *regionLoc = dyn_cast<loc::MemRegionVal>(&loc)) { 3248 escapes = !regionLoc->getRegion()->hasStackStorage(); 3249 3250 if (!escapes) { 3251 // To test (3), generate a new state with the binding added. If it is 3252 // the same state, then it escapes (since the store cannot represent 3253 // the binding). 3254 escapes = (state == (state->bindLoc(*regionLoc, val))); 3255 } 3256 } 3257 3258 // If our store can represent the binding and we aren't storing to something 3259 // that doesn't have local storage then just return and have the simulation 3260 // state continue as is. 3261 if (!escapes) 3262 return; 3263 3264 // Otherwise, find all symbols referenced by 'val' that we are tracking 3265 // and stop tracking them. 3266 state = state->scanReachableSymbols<StopTrackingCallback>(val).getState(); 3267 C.addTransition(state); 3268} 3269 3270const ProgramState *RetainCountChecker::evalAssume(const ProgramState *state, 3271 SVal Cond, 3272 bool Assumption) const { 3273 3274 // FIXME: We may add to the interface of evalAssume the list of symbols 3275 // whose assumptions have changed. For now we just iterate through the 3276 // bindings and check if any of the tracked symbols are NULL. This isn't 3277 // too bad since the number of symbols we will track in practice are 3278 // probably small and evalAssume is only called at branches and a few 3279 // other places. 3280 RefBindings B = state->get<RefBindings>(); 3281 3282 if (B.isEmpty()) 3283 return state; 3284 3285 bool changed = false; 3286 RefBindings::Factory &RefBFactory = state->get_context<RefBindings>(); 3287 3288 for (RefBindings::iterator I = B.begin(), E = B.end(); I != E; ++I) { 3289 // Check if the symbol is null (or equal to any constant). 3290 // If this is the case, stop tracking the symbol. 3291 if (state->getSymVal(I.getKey())) { 3292 changed = true; 3293 B = RefBFactory.remove(B, I.getKey()); 3294 } 3295 } 3296 3297 if (changed) 3298 state = state->set<RefBindings>(B); 3299 3300 return state; 3301} 3302 3303const ProgramState * 3304RetainCountChecker::checkRegionChanges(const ProgramState *state, 3305 const StoreManager::InvalidatedSymbols *invalidated, 3306 ArrayRef<const MemRegion *> ExplicitRegions, 3307 ArrayRef<const MemRegion *> Regions) const { 3308 if (!invalidated) 3309 return state; 3310 3311 llvm::SmallPtrSet<SymbolRef, 8> WhitelistedSymbols; 3312 for (ArrayRef<const MemRegion *>::iterator I = ExplicitRegions.begin(), 3313 E = ExplicitRegions.end(); I != E; ++I) { 3314 if (const SymbolicRegion *SR = (*I)->StripCasts()->getAs<SymbolicRegion>()) 3315 WhitelistedSymbols.insert(SR->getSymbol()); 3316 } 3317 3318 for (StoreManager::InvalidatedSymbols::const_iterator I=invalidated->begin(), 3319 E = invalidated->end(); I!=E; ++I) { 3320 SymbolRef sym = *I; 3321 if (WhitelistedSymbols.count(sym)) 3322 continue; 3323 // Remove any existing reference-count binding. 3324 state = state->remove<RefBindings>(sym); 3325 } 3326 return state; 3327} 3328 3329//===----------------------------------------------------------------------===// 3330// Handle dead symbols and end-of-path. 3331//===----------------------------------------------------------------------===// 3332 3333std::pair<ExplodedNode *, const ProgramState *> 3334RetainCountChecker::handleAutoreleaseCounts(const ProgramState *state, 3335 GenericNodeBuilderRefCount Bd, 3336 ExplodedNode *Pred, ExprEngine &Eng, 3337 SymbolRef Sym, RefVal V) const { 3338 unsigned ACnt = V.getAutoreleaseCount(); 3339 3340 // No autorelease counts? Nothing to be done. 3341 if (!ACnt) 3342 return std::make_pair(Pred, state); 3343 3344 assert(!Eng.isObjCGCEnabled() && "Autorelease counts in GC mode?"); 3345 unsigned Cnt = V.getCount(); 3346 3347 // FIXME: Handle sending 'autorelease' to already released object. 3348 3349 if (V.getKind() == RefVal::ReturnedOwned) 3350 ++Cnt; 3351 3352 if (ACnt <= Cnt) { 3353 if (ACnt == Cnt) { 3354 V.clearCounts(); 3355 if (V.getKind() == RefVal::ReturnedOwned) 3356 V = V ^ RefVal::ReturnedNotOwned; 3357 else 3358 V = V ^ RefVal::NotOwned; 3359 } else { 3360 V.setCount(Cnt - ACnt); 3361 V.setAutoreleaseCount(0); 3362 } 3363 state = state->set<RefBindings>(Sym, V); 3364 ExplodedNode *N = Bd.MakeNode(state, Pred); 3365 if (N == 0) 3366 state = 0; 3367 return std::make_pair(N, state); 3368 } 3369 3370 // Woah! More autorelease counts then retain counts left. 3371 // Emit hard error. 3372 V = V ^ RefVal::ErrorOverAutorelease; 3373 state = state->set<RefBindings>(Sym, V); 3374 3375 if (ExplodedNode *N = Bd.MakeNode(state, Pred, true)) { 3376 llvm::SmallString<128> sbuf; 3377 llvm::raw_svector_ostream os(sbuf); 3378 os << "Object over-autoreleased: object was sent -autorelease "; 3379 if (V.getAutoreleaseCount() > 1) 3380 os << V.getAutoreleaseCount() << " times "; 3381 os << "but the object has a +" << V.getCount() << " retain count"; 3382 3383 if (!overAutorelease) 3384 overAutorelease.reset(new OverAutorelease()); 3385 3386 const LangOptions &LOpts = Eng.getContext().getLangOptions(); 3387 CFRefReport *report = 3388 new CFRefReport(*overAutorelease, LOpts, /* GCEnabled = */ false, 3389 SummaryLog, N, Sym, os.str()); 3390 Eng.getBugReporter().EmitReport(report); 3391 } 3392 3393 return std::make_pair((ExplodedNode *)0, (const ProgramState *)0); 3394} 3395 3396const ProgramState * 3397RetainCountChecker::handleSymbolDeath(const ProgramState *state, 3398 SymbolRef sid, RefVal V, 3399 SmallVectorImpl<SymbolRef> &Leaked) const { 3400 bool hasLeak = false; 3401 if (V.isOwned()) 3402 hasLeak = true; 3403 else if (V.isNotOwned() || V.isReturnedOwned()) 3404 hasLeak = (V.getCount() > 0); 3405 3406 if (!hasLeak) 3407 return state->remove<RefBindings>(sid); 3408 3409 Leaked.push_back(sid); 3410 return state->set<RefBindings>(sid, V ^ RefVal::ErrorLeak); 3411} 3412 3413ExplodedNode * 3414RetainCountChecker::processLeaks(const ProgramState *state, 3415 SmallVectorImpl<SymbolRef> &Leaked, 3416 GenericNodeBuilderRefCount &Builder, 3417 ExprEngine &Eng, ExplodedNode *Pred) const { 3418 if (Leaked.empty()) 3419 return Pred; 3420 3421 // Generate an intermediate node representing the leak point. 3422 ExplodedNode *N = Builder.MakeNode(state, Pred); 3423 3424 if (N) { 3425 for (SmallVectorImpl<SymbolRef>::iterator 3426 I = Leaked.begin(), E = Leaked.end(); I != E; ++I) { 3427 3428 const LangOptions &LOpts = Eng.getContext().getLangOptions(); 3429 bool GCEnabled = Eng.isObjCGCEnabled(); 3430 CFRefBug *BT = Pred ? getLeakWithinFunctionBug(LOpts, GCEnabled) 3431 : getLeakAtReturnBug(LOpts, GCEnabled); 3432 assert(BT && "BugType not initialized."); 3433 3434 CFRefLeakReport *report = new CFRefLeakReport(*BT, LOpts, GCEnabled, 3435 SummaryLog, N, *I, Eng); 3436 Eng.getBugReporter().EmitReport(report); 3437 } 3438 } 3439 3440 return N; 3441} 3442 3443void RetainCountChecker::checkEndPath(EndOfFunctionNodeBuilder &Builder, 3444 ExprEngine &Eng) const { 3445 const ProgramState *state = Builder.getState(); 3446 GenericNodeBuilderRefCount Bd(Builder); 3447 RefBindings B = state->get<RefBindings>(); 3448 ExplodedNode *Pred = Builder.getPredecessor(); 3449 3450 for (RefBindings::iterator I = B.begin(), E = B.end(); I != E; ++I) { 3451 llvm::tie(Pred, state) = handleAutoreleaseCounts(state, Bd, Pred, Eng, 3452 I->first, I->second); 3453 if (!state) 3454 return; 3455 } 3456 3457 B = state->get<RefBindings>(); 3458 SmallVector<SymbolRef, 10> Leaked; 3459 3460 for (RefBindings::iterator I = B.begin(), E = B.end(); I != E; ++I) 3461 state = handleSymbolDeath(state, I->first, I->second, Leaked); 3462 3463 processLeaks(state, Leaked, Bd, Eng, Pred); 3464} 3465 3466const ProgramPointTag * 3467RetainCountChecker::getDeadSymbolTag(SymbolRef sym) const { 3468 const SimpleProgramPointTag *&tag = DeadSymbolTags[sym]; 3469 if (!tag) { 3470 llvm::SmallString<64> buf; 3471 llvm::raw_svector_ostream out(buf); 3472 out << "RetainCountChecker : Dead Symbol : " << sym->getSymbolID(); 3473 tag = new SimpleProgramPointTag(out.str()); 3474 } 3475 return tag; 3476} 3477 3478void RetainCountChecker::checkDeadSymbols(SymbolReaper &SymReaper, 3479 CheckerContext &C) const { 3480 ExprEngine &Eng = C.getEngine(); 3481 ExplodedNode *Pred = C.getPredecessor(); 3482 3483 const ProgramState *state = C.getState(); 3484 RefBindings B = state->get<RefBindings>(); 3485 3486 // Update counts from autorelease pools 3487 for (SymbolReaper::dead_iterator I = SymReaper.dead_begin(), 3488 E = SymReaper.dead_end(); I != E; ++I) { 3489 SymbolRef Sym = *I; 3490 if (const RefVal *T = B.lookup(Sym)){ 3491 // Use the symbol as the tag. 3492 // FIXME: This might not be as unique as we would like. 3493 GenericNodeBuilderRefCount Bd(C, getDeadSymbolTag(Sym)); 3494 llvm::tie(Pred, state) = handleAutoreleaseCounts(state, Bd, Pred, Eng, 3495 Sym, *T); 3496 if (!state) 3497 return; 3498 } 3499 } 3500 3501 B = state->get<RefBindings>(); 3502 SmallVector<SymbolRef, 10> Leaked; 3503 3504 for (SymbolReaper::dead_iterator I = SymReaper.dead_begin(), 3505 E = SymReaper.dead_end(); I != E; ++I) { 3506 if (const RefVal *T = B.lookup(*I)) 3507 state = handleSymbolDeath(state, *I, *T, Leaked); 3508 } 3509 3510 { 3511 GenericNodeBuilderRefCount Bd(C, this); 3512 Pred = processLeaks(state, Leaked, Bd, Eng, Pred); 3513 } 3514 3515 // Did we cache out? 3516 if (!Pred) 3517 return; 3518 3519 // Now generate a new node that nukes the old bindings. 3520 RefBindings::Factory &F = state->get_context<RefBindings>(); 3521 3522 for (SymbolReaper::dead_iterator I = SymReaper.dead_begin(), 3523 E = SymReaper.dead_end(); I != E; ++I) 3524 B = F.remove(B, *I); 3525 3526 state = state->set<RefBindings>(B); 3527 C.generateNode(state, Pred); 3528} 3529 3530//===----------------------------------------------------------------------===// 3531// Debug printing of refcount bindings and autorelease pools. 3532//===----------------------------------------------------------------------===// 3533 3534static void PrintPool(raw_ostream &Out, SymbolRef Sym, 3535 const ProgramState *State) { 3536 Out << ' '; 3537 if (Sym) 3538 Out << Sym->getSymbolID(); 3539 else 3540 Out << "<pool>"; 3541 Out << ":{"; 3542 3543 // Get the contents of the pool. 3544 if (const ARCounts *Cnts = State->get<AutoreleasePoolContents>(Sym)) 3545 for (ARCounts::iterator I = Cnts->begin(), E = Cnts->end(); I != E; ++I) 3546 Out << '(' << I.getKey() << ',' << I.getData() << ')'; 3547 3548 Out << '}'; 3549} 3550 3551static bool UsesAutorelease(const ProgramState *state) { 3552 // A state uses autorelease if it allocated an autorelease pool or if it has 3553 // objects in the caller's autorelease pool. 3554 return !state->get<AutoreleaseStack>().isEmpty() || 3555 state->get<AutoreleasePoolContents>(SymbolRef()); 3556} 3557 3558void RetainCountChecker::printState(raw_ostream &Out, const ProgramState *State, 3559 const char *NL, const char *Sep) const { 3560 3561 RefBindings B = State->get<RefBindings>(); 3562 3563 if (!B.isEmpty()) 3564 Out << Sep << NL; 3565 3566 for (RefBindings::iterator I = B.begin(), E = B.end(); I != E; ++I) { 3567 Out << I->first << " : "; 3568 I->second.print(Out); 3569 Out << NL; 3570 } 3571 3572 // Print the autorelease stack. 3573 if (UsesAutorelease(State)) { 3574 Out << Sep << NL << "AR pool stack:"; 3575 ARStack Stack = State->get<AutoreleaseStack>(); 3576 3577 PrintPool(Out, SymbolRef(), State); // Print the caller's pool. 3578 for (ARStack::iterator I = Stack.begin(), E = Stack.end(); I != E; ++I) 3579 PrintPool(Out, *I, State); 3580 3581 Out << NL; 3582 } 3583} 3584 3585//===----------------------------------------------------------------------===// 3586// Checker registration. 3587//===----------------------------------------------------------------------===// 3588 3589void ento::registerRetainCountChecker(CheckerManager &Mgr) { 3590 Mgr.registerChecker<RetainCountChecker>(); 3591} 3592 3593