1 //==--- RetainCountChecker.h - 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 #ifndef LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_RETAINCOUNTCHECKER_H 16 #define LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_RETAINCOUNTCHECKER_H 17 18 #include "../ClangSACheckers.h" 19 #include "../AllocationDiagnostics.h" 20 #include "RetainCountDiagnostics.h" 21 #include "clang/AST/Attr.h" 22 #include "clang/AST/DeclCXX.h" 23 #include "clang/AST/DeclObjC.h" 24 #include "clang/AST/ParentMap.h" 25 #include "clang/Analysis/DomainSpecific/CocoaConventions.h" 26 #include "clang/Basic/LangOptions.h" 27 #include "clang/Basic/SourceManager.h" 28 #include "clang/Analysis/SelectorExtras.h" 29 #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" 30 #include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h" 31 #include "clang/StaticAnalyzer/Core/Checker.h" 32 #include "clang/StaticAnalyzer/Core/CheckerManager.h" 33 #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" 34 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" 35 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h" 36 #include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h" 37 #include "clang/StaticAnalyzer/Core/RetainSummaryManager.h" 38 #include "llvm/ADT/DenseMap.h" 39 #include "llvm/ADT/FoldingSet.h" 40 #include "llvm/ADT/ImmutableList.h" 41 #include "llvm/ADT/ImmutableMap.h" 42 #include "llvm/ADT/STLExtras.h" 43 #include "llvm/ADT/SmallString.h" 44 #include "llvm/ADT/StringExtras.h" 45 #include <cstdarg> 46 #include <utility> 47 48 namespace clang { 49 namespace ento { 50 namespace retaincountchecker { 51 52 /// Metadata on reference. 53 class RefVal { 54 public: 55 enum Kind { 56 Owned = 0, // Owning reference. 57 NotOwned, // Reference is not owned by still valid (not freed). 58 Released, // Object has been released. 59 ReturnedOwned, // Returned object passes ownership to caller. 60 ReturnedNotOwned, // Return object does not pass ownership to caller. 61 ERROR_START, 62 ErrorDeallocNotOwned, // -dealloc called on non-owned object. 63 ErrorUseAfterRelease, // Object used after released. 64 ErrorReleaseNotOwned, // Release of an object that was not owned. 65 ERROR_LEAK_START, 66 ErrorLeak, // A memory leak due to excessive reference counts. 67 ErrorLeakReturned, // A memory leak due to the returning method not having 68 // the correct naming conventions. 69 ErrorOverAutorelease, 70 ErrorReturnedNotOwned 71 }; 72 73 /// Tracks how an object referenced by an ivar has been used. 74 /// 75 /// This accounts for us not knowing if an arbitrary ivar is supposed to be 76 /// stored at +0 or +1. 77 enum class IvarAccessHistory { 78 None, 79 AccessedDirectly, 80 ReleasedAfterDirectAccess 81 }; 82 83 private: 84 /// The number of outstanding retains. 85 unsigned Cnt; 86 /// The number of outstanding autoreleases. 87 unsigned ACnt; 88 /// The (static) type of the object at the time we started tracking it. 89 QualType T; 90 91 /// The current state of the object. 92 /// 93 /// See the RefVal::Kind enum for possible values. 94 unsigned RawKind : 5; 95 96 /// The kind of object being tracked (CF or ObjC), if known. 97 /// 98 /// See the RetEffect::ObjKind enum for possible values. 99 unsigned RawObjectKind : 3; 100 101 /// True if the current state and/or retain count may turn out to not be the 102 /// best possible approximation of the reference counting state. 103 /// 104 /// If true, the checker may decide to throw away ("override") this state 105 /// in favor of something else when it sees the object being used in new ways. 106 /// 107 /// This setting should not be propagated to state derived from this state. 108 /// Once we start deriving new states, it would be inconsistent to override 109 /// them. 110 unsigned RawIvarAccessHistory : 2; 111 112 RefVal(Kind k, RetEffect::ObjKind o, unsigned cnt, unsigned acnt, QualType t, 113 IvarAccessHistory IvarAccess) 114 : Cnt(cnt), ACnt(acnt), T(t), RawKind(static_cast<unsigned>(k)), 115 RawObjectKind(static_cast<unsigned>(o)), 116 RawIvarAccessHistory(static_cast<unsigned>(IvarAccess)) { 117 assert(getKind() == k && "not enough bits for the kind"); 118 assert(getObjKind() == o && "not enough bits for the object kind"); 119 assert(getIvarAccessHistory() == IvarAccess && "not enough bits"); 120 } 121 122 public: 123 Kind getKind() const { return static_cast<Kind>(RawKind); } 124 125 RetEffect::ObjKind getObjKind() const { 126 return static_cast<RetEffect::ObjKind>(RawObjectKind); 127 } 128 129 unsigned getCount() const { return Cnt; } 130 unsigned getAutoreleaseCount() const { return ACnt; } 131 unsigned getCombinedCounts() const { return Cnt + ACnt; } 132 void clearCounts() { 133 Cnt = 0; 134 ACnt = 0; 135 } 136 void setCount(unsigned i) { 137 Cnt = i; 138 } 139 void setAutoreleaseCount(unsigned i) { 140 ACnt = i; 141 } 142 143 QualType getType() const { return T; } 144 145 /// Returns what the analyzer knows about direct accesses to a particular 146 /// instance variable. 147 /// 148 /// If the object with this refcount wasn't originally from an Objective-C 149 /// ivar region, this should always return IvarAccessHistory::None. 150 IvarAccessHistory getIvarAccessHistory() const { 151 return static_cast<IvarAccessHistory>(RawIvarAccessHistory); 152 } 153 154 bool isOwned() const { 155 return getKind() == Owned; 156 } 157 158 bool isNotOwned() const { 159 return getKind() == NotOwned; 160 } 161 162 bool isReturnedOwned() const { 163 return getKind() == ReturnedOwned; 164 } 165 166 bool isReturnedNotOwned() const { 167 return getKind() == ReturnedNotOwned; 168 } 169 170 /// Create a state for an object whose lifetime is the responsibility of the 171 /// current function, at least partially. 172 /// 173 /// Most commonly, this is an owned object with a retain count of +1. 174 static RefVal makeOwned(RetEffect::ObjKind o, QualType t) { 175 return RefVal(Owned, o, /*Count=*/1, 0, t, IvarAccessHistory::None); 176 } 177 178 /// Create a state for an object whose lifetime is not the responsibility of 179 /// the current function. 180 /// 181 /// Most commonly, this is an unowned object with a retain count of +0. 182 static RefVal makeNotOwned(RetEffect::ObjKind o, QualType t) { 183 return RefVal(NotOwned, o, /*Count=*/0, 0, t, IvarAccessHistory::None); 184 } 185 186 RefVal operator-(size_t i) const { 187 return RefVal(getKind(), getObjKind(), getCount() - i, 188 getAutoreleaseCount(), getType(), getIvarAccessHistory()); 189 } 190 191 RefVal operator+(size_t i) const { 192 return RefVal(getKind(), getObjKind(), getCount() + i, 193 getAutoreleaseCount(), getType(), getIvarAccessHistory()); 194 } 195 196 RefVal operator^(Kind k) const { 197 return RefVal(k, getObjKind(), getCount(), getAutoreleaseCount(), 198 getType(), getIvarAccessHistory()); 199 } 200 201 RefVal autorelease() const { 202 return RefVal(getKind(), getObjKind(), getCount(), getAutoreleaseCount()+1, 203 getType(), getIvarAccessHistory()); 204 } 205 206 RefVal withIvarAccess() const { 207 assert(getIvarAccessHistory() == IvarAccessHistory::None); 208 return RefVal(getKind(), getObjKind(), getCount(), getAutoreleaseCount(), 209 getType(), IvarAccessHistory::AccessedDirectly); 210 } 211 212 RefVal releaseViaIvar() const { 213 assert(getIvarAccessHistory() == IvarAccessHistory::AccessedDirectly); 214 return RefVal(getKind(), getObjKind(), getCount(), getAutoreleaseCount(), 215 getType(), IvarAccessHistory::ReleasedAfterDirectAccess); 216 } 217 218 // Comparison, profiling, and pretty-printing. 219 bool hasSameState(const RefVal &X) const { 220 return getKind() == X.getKind() && Cnt == X.Cnt && ACnt == X.ACnt && 221 getIvarAccessHistory() == X.getIvarAccessHistory(); 222 } 223 224 bool operator==(const RefVal& X) const { 225 return T == X.T && hasSameState(X) && getObjKind() == X.getObjKind(); 226 } 227 228 void Profile(llvm::FoldingSetNodeID& ID) const { 229 ID.Add(T); 230 ID.AddInteger(RawKind); 231 ID.AddInteger(Cnt); 232 ID.AddInteger(ACnt); 233 ID.AddInteger(RawObjectKind); 234 ID.AddInteger(RawIvarAccessHistory); 235 } 236 237 void print(raw_ostream &Out) const; 238 }; 239 240 class RetainCountChecker 241 : public Checker< check::Bind, 242 check::DeadSymbols, 243 check::EndAnalysis, 244 check::BeginFunction, 245 check::EndFunction, 246 check::PostStmt<BlockExpr>, 247 check::PostStmt<CastExpr>, 248 check::PostStmt<ObjCArrayLiteral>, 249 check::PostStmt<ObjCDictionaryLiteral>, 250 check::PostStmt<ObjCBoxedExpr>, 251 check::PostStmt<ObjCIvarRefExpr>, 252 check::PostCall, 253 check::RegionChanges, 254 eval::Assume, 255 eval::Call > { 256 mutable std::unique_ptr<CFRefBug> useAfterRelease, releaseNotOwned; 257 mutable std::unique_ptr<CFRefBug> deallocNotOwned; 258 mutable std::unique_ptr<CFRefBug> overAutorelease, returnNotOwnedForOwned; 259 mutable std::unique_ptr<CFRefBug> leakWithinFunction, leakAtReturn; 260 261 typedef llvm::DenseMap<SymbolRef, const CheckerProgramPointTag *> SymbolTagMap; 262 263 // This map is only used to ensure proper deletion of any allocated tags. 264 mutable SymbolTagMap DeadSymbolTags; 265 266 mutable std::unique_ptr<RetainSummaryManager> Summaries; 267 mutable SummaryLogTy SummaryLog; 268 269 AnalyzerOptions &Options; 270 mutable bool ShouldResetSummaryLog; 271 272 /// Optional setting to indicate if leak reports should include 273 /// the allocation line. 274 mutable bool IncludeAllocationLine; 275 276 public: 277 RetainCountChecker(AnalyzerOptions &Options) 278 : Options(Options), ShouldResetSummaryLog(false), 279 IncludeAllocationLine( 280 shouldIncludeAllocationSiteInLeakDiagnostics(Options)) {} 281 282 ~RetainCountChecker() override { DeleteContainerSeconds(DeadSymbolTags); } 283 284 bool shouldCheckOSObjectRetainCount() const { 285 return Options.getBooleanOption("CheckOSObject", false, this); 286 } 287 288 void checkEndAnalysis(ExplodedGraph &G, BugReporter &BR, 289 ExprEngine &Eng) const { 290 // FIXME: This is a hack to make sure the summary log gets cleared between 291 // analyses of different code bodies. 292 // 293 // Why is this necessary? Because a checker's lifetime is tied to a 294 // translation unit, but an ExplodedGraph's lifetime is just a code body. 295 // Once in a blue moon, a new ExplodedNode will have the same address as an 296 // old one with an associated summary, and the bug report visitor gets very 297 // confused. (To make things worse, the summary lifetime is currently also 298 // tied to a code body, so we get a crash instead of incorrect results.) 299 // 300 // Why is this a bad solution? Because if the lifetime of the ExplodedGraph 301 // changes, things will start going wrong again. Really the lifetime of this 302 // log needs to be tied to either the specific nodes in it or the entire 303 // ExplodedGraph, not to a specific part of the code being analyzed. 304 // 305 // (Also, having stateful local data means that the same checker can't be 306 // used from multiple threads, but a lot of checkers have incorrect 307 // assumptions about that anyway. So that wasn't a priority at the time of 308 // this fix.) 309 // 310 // This happens at the end of analysis, but bug reports are emitted /after/ 311 // this point. So we can't just clear the summary log now. Instead, we mark 312 // that the next time we access the summary log, it should be cleared. 313 314 // If we never reset the summary log during /this/ code body analysis, 315 // there were no new summaries. There might still have been summaries from 316 // the /last/ analysis, so clear them out to make sure the bug report 317 // visitors don't get confused. 318 if (ShouldResetSummaryLog) 319 SummaryLog.clear(); 320 321 ShouldResetSummaryLog = !SummaryLog.empty(); 322 } 323 324 CFRefBug *getLeakWithinFunctionBug(const LangOptions &LOpts) const { 325 if (!leakWithinFunction) 326 leakWithinFunction.reset(new Leak(this, "Leak")); 327 return leakWithinFunction.get(); 328 } 329 330 CFRefBug *getLeakAtReturnBug(const LangOptions &LOpts) const { 331 if (!leakAtReturn) 332 leakAtReturn.reset(new Leak(this, "Leak of returned object")); 333 return leakAtReturn.get(); 334 } 335 336 RetainSummaryManager &getSummaryManager(ASTContext &Ctx) const { 337 // FIXME: We don't support ARC being turned on and off during one analysis. 338 // (nor, for that matter, do we support changing ASTContexts) 339 bool ARCEnabled = (bool)Ctx.getLangOpts().ObjCAutoRefCount; 340 if (!Summaries) { 341 Summaries.reset(new RetainSummaryManager( 342 Ctx, ARCEnabled, shouldCheckOSObjectRetainCount())); 343 } else { 344 assert(Summaries->isARCEnabled() == ARCEnabled); 345 } 346 return *Summaries; 347 } 348 349 RetainSummaryManager &getSummaryManager(CheckerContext &C) const { 350 return getSummaryManager(C.getASTContext()); 351 } 352 353 void printState(raw_ostream &Out, ProgramStateRef State, 354 const char *NL, const char *Sep) const override; 355 356 void checkBind(SVal loc, SVal val, const Stmt *S, CheckerContext &C) const; 357 void checkPostStmt(const BlockExpr *BE, CheckerContext &C) const; 358 void checkPostStmt(const CastExpr *CE, CheckerContext &C) const; 359 360 void checkPostStmt(const ObjCArrayLiteral *AL, CheckerContext &C) const; 361 void checkPostStmt(const ObjCDictionaryLiteral *DL, CheckerContext &C) const; 362 void checkPostStmt(const ObjCBoxedExpr *BE, CheckerContext &C) const; 363 364 void checkPostStmt(const ObjCIvarRefExpr *IRE, CheckerContext &C) const; 365 366 void checkPostCall(const CallEvent &Call, CheckerContext &C) const; 367 368 void checkSummary(const RetainSummary &Summ, const CallEvent &Call, 369 CheckerContext &C) const; 370 371 void processSummaryOfInlined(const RetainSummary &Summ, 372 const CallEvent &Call, 373 CheckerContext &C) const; 374 375 bool evalCall(const CallExpr *CE, CheckerContext &C) const; 376 377 ProgramStateRef evalAssume(ProgramStateRef state, SVal Cond, 378 bool Assumption) const; 379 380 ProgramStateRef 381 checkRegionChanges(ProgramStateRef state, 382 const InvalidatedSymbols *invalidated, 383 ArrayRef<const MemRegion *> ExplicitRegions, 384 ArrayRef<const MemRegion *> Regions, 385 const LocationContext* LCtx, 386 const CallEvent *Call) const; 387 388 ExplodedNode* checkReturnWithRetEffect(const ReturnStmt *S, CheckerContext &C, 389 ExplodedNode *Pred, RetEffect RE, RefVal X, 390 SymbolRef Sym, ProgramStateRef state) const; 391 392 void checkDeadSymbols(SymbolReaper &SymReaper, CheckerContext &C) const; 393 void checkBeginFunction(CheckerContext &C) const; 394 void checkEndFunction(const ReturnStmt *RS, CheckerContext &C) const; 395 396 ProgramStateRef updateSymbol(ProgramStateRef state, SymbolRef sym, 397 RefVal V, ArgEffect E, RefVal::Kind &hasErr, 398 CheckerContext &C) const; 399 400 void processNonLeakError(ProgramStateRef St, SourceRange ErrorRange, 401 RefVal::Kind ErrorKind, SymbolRef Sym, 402 CheckerContext &C) const; 403 404 void processObjCLiterals(CheckerContext &C, const Expr *Ex) const; 405 406 const ProgramPointTag *getDeadSymbolTag(SymbolRef sym) const; 407 408 ProgramStateRef handleSymbolDeath(ProgramStateRef state, 409 SymbolRef sid, RefVal V, 410 SmallVectorImpl<SymbolRef> &Leaked) const; 411 412 ProgramStateRef 413 handleAutoreleaseCounts(ProgramStateRef state, ExplodedNode *Pred, 414 const ProgramPointTag *Tag, CheckerContext &Ctx, 415 SymbolRef Sym, 416 RefVal V, 417 const ReturnStmt *S=nullptr) const; 418 419 ExplodedNode *processLeaks(ProgramStateRef state, 420 SmallVectorImpl<SymbolRef> &Leaked, 421 CheckerContext &Ctx, 422 ExplodedNode *Pred = nullptr) const; 423 424 private: 425 /// Perform the necessary checks and state adjustments at the end of the 426 /// function. 427 /// \p S Return statement, may be null. 428 ExplodedNode * processReturn(const ReturnStmt *S, CheckerContext &C) const; 429 }; 430 431 //===----------------------------------------------------------------------===// 432 // RefBindings - State used to track object reference counts. 433 //===----------------------------------------------------------------------===// 434 435 const RefVal *getRefBinding(ProgramStateRef State, SymbolRef Sym); 436 437 ProgramStateRef setRefBinding(ProgramStateRef State, SymbolRef Sym, 438 RefVal Val); 439 440 ProgramStateRef removeRefBinding(ProgramStateRef State, SymbolRef Sym); 441 442 /// Returns true if this stack frame is for an Objective-C method that is a 443 /// property getter or setter whose body has been synthesized by the analyzer. 444 inline bool isSynthesizedAccessor(const StackFrameContext *SFC) { 445 auto Method = dyn_cast_or_null<ObjCMethodDecl>(SFC->getDecl()); 446 if (!Method || !Method->isPropertyAccessor()) 447 return false; 448 449 return SFC->getAnalysisDeclContext()->isBodyAutosynthesized(); 450 } 451 452 } // end namespace retaincountchecker 453 } // end namespace ento 454 } // end namespace clang 455 456 #endif 457