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