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