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