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