1 //==--- RetainCountChecker.h - Checks for leaks and other issues -*- C++ -*--// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file defines the methods for RetainCountChecker, which implements 10 // a reference count checker for Core Foundation and Cocoa on (Mac OS X). 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_RETAINCOUNTCHECKER_H 15 #define LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_RETAINCOUNTCHECKER_H 16 17 #include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" 18 #include "RetainCountDiagnostics.h" 19 #include "clang/AST/Attr.h" 20 #include "clang/AST/DeclCXX.h" 21 #include "clang/AST/DeclObjC.h" 22 #include "clang/AST/ParentMap.h" 23 #include "clang/Analysis/DomainSpecific/CocoaConventions.h" 24 #include "clang/Analysis/PathDiagnostic.h" 25 #include "clang/Analysis/RetainSummaryManager.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/Checker.h" 31 #include "clang/StaticAnalyzer/Core/CheckerManager.h" 32 #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" 33 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" 34 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h" 35 #include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h" 36 #include "llvm/ADT/DenseMap.h" 37 #include "llvm/ADT/FoldingSet.h" 38 #include "llvm/ADT/ImmutableList.h" 39 #include "llvm/ADT/ImmutableMap.h" 40 #include "llvm/ADT/STLExtras.h" 41 #include "llvm/ADT/SmallString.h" 42 #include "llvm/ADT/StringExtras.h" 43 #include <cstdarg> 44 #include <utility> 45 46 namespace clang { 47 namespace ento { 48 namespace retaincountchecker { 49 50 /// Metadata on reference. 51 class RefVal { 52 public: 53 enum Kind { 54 Owned = 0, // Owning reference. 55 NotOwned, // Reference is not owned by still valid (not freed). 56 Released, // Object has been released. 57 ReturnedOwned, // Returned object passes ownership to caller. 58 ReturnedNotOwned, // Return object does not pass ownership to caller. 59 ERROR_START, 60 ErrorDeallocNotOwned, // -dealloc called on non-owned object. 61 ErrorUseAfterRelease, // Object used after released. 62 ErrorReleaseNotOwned, // Release of an object that was not owned. 63 ERROR_LEAK_START, 64 ErrorLeak, // A memory leak due to excessive reference counts. 65 ErrorLeakReturned, // A memory leak due to the returning method not having 66 // the correct naming conventions. 67 ErrorOverAutorelease, 68 ErrorReturnedNotOwned 69 }; 70 71 /// Tracks how an object referenced by an ivar has been used. 72 /// 73 /// This accounts for us not knowing if an arbitrary ivar is supposed to be 74 /// stored at +0 or +1. 75 enum class IvarAccessHistory { 76 None, 77 AccessedDirectly, 78 ReleasedAfterDirectAccess 79 }; 80 81 private: 82 /// The number of outstanding retains. 83 unsigned Cnt; 84 /// The number of outstanding autoreleases. 85 unsigned ACnt; 86 /// The (static) type of the object at the time we started tracking it. 87 QualType T; 88 89 /// The current state of the object. 90 /// 91 /// See the RefVal::Kind enum for possible values. 92 unsigned RawKind : 5; 93 94 /// The kind of object being tracked (CF or ObjC or OSObject), if known. 95 /// 96 /// See the ObjKind enum for possible values. 97 unsigned RawObjectKind : 3; 98 99 /// True if the current state and/or retain count may turn out to not be the 100 /// best possible approximation of the reference counting state. 101 /// 102 /// If true, the checker may decide to throw away ("override") this state 103 /// in favor of something else when it sees the object being used in new ways. 104 /// 105 /// This setting should not be propagated to state derived from this state. 106 /// Once we start deriving new states, it would be inconsistent to override 107 /// them. 108 unsigned RawIvarAccessHistory : 2; 109 110 RefVal(Kind k, ObjKind o, unsigned cnt, unsigned acnt, QualType t, 111 IvarAccessHistory IvarAccess) 112 : Cnt(cnt), ACnt(acnt), T(t), RawKind(static_cast<unsigned>(k)), 113 RawObjectKind(static_cast<unsigned>(o)), 114 RawIvarAccessHistory(static_cast<unsigned>(IvarAccess)) { 115 assert(getKind() == k && "not enough bits for the kind"); 116 assert(getObjKind() == o && "not enough bits for the object kind"); 117 assert(getIvarAccessHistory() == IvarAccess && "not enough bits"); 118 } 119 120 public: 121 Kind getKind() const { return static_cast<Kind>(RawKind); } 122 123 ObjKind getObjKind() const { 124 return static_cast<ObjKind>(RawObjectKind); 125 } 126 127 unsigned getCount() const { return Cnt; } 128 unsigned getAutoreleaseCount() const { return ACnt; } 129 unsigned getCombinedCounts() const { return Cnt + ACnt; } 130 void clearCounts() { 131 Cnt = 0; 132 ACnt = 0; 133 } 134 void setCount(unsigned i) { 135 Cnt = i; 136 } 137 void setAutoreleaseCount(unsigned i) { 138 ACnt = i; 139 } 140 141 QualType getType() const { return T; } 142 143 /// Returns what the analyzer knows about direct accesses to a particular 144 /// instance variable. 145 /// 146 /// If the object with this refcount wasn't originally from an Objective-C 147 /// ivar region, this should always return IvarAccessHistory::None. 148 IvarAccessHistory getIvarAccessHistory() const { 149 return static_cast<IvarAccessHistory>(RawIvarAccessHistory); 150 } 151 152 bool isOwned() const { 153 return getKind() == Owned; 154 } 155 156 bool isNotOwned() const { 157 return getKind() == NotOwned; 158 } 159 160 bool isReturnedOwned() const { 161 return getKind() == ReturnedOwned; 162 } 163 164 bool isReturnedNotOwned() const { 165 return getKind() == ReturnedNotOwned; 166 } 167 168 /// Create a state for an object whose lifetime is the responsibility of the 169 /// current function, at least partially. 170 /// 171 /// Most commonly, this is an owned object with a retain count of +1. 172 static RefVal makeOwned(ObjKind o, QualType t) { 173 return RefVal(Owned, o, /*Count=*/1, 0, t, IvarAccessHistory::None); 174 } 175 176 /// Create a state for an object whose lifetime is not the responsibility of 177 /// the current function. 178 /// 179 /// Most commonly, this is an unowned object with a retain count of +0. 180 static RefVal makeNotOwned(ObjKind o, QualType t) { 181 return RefVal(NotOwned, o, /*Count=*/0, 0, t, IvarAccessHistory::None); 182 } 183 184 RefVal operator-(size_t i) const { 185 return RefVal(getKind(), getObjKind(), getCount() - i, 186 getAutoreleaseCount(), getType(), getIvarAccessHistory()); 187 } 188 189 RefVal operator+(size_t i) const { 190 return RefVal(getKind(), getObjKind(), getCount() + i, 191 getAutoreleaseCount(), getType(), getIvarAccessHistory()); 192 } 193 194 RefVal operator^(Kind k) const { 195 return RefVal(k, getObjKind(), getCount(), getAutoreleaseCount(), 196 getType(), getIvarAccessHistory()); 197 } 198 199 RefVal autorelease() const { 200 return RefVal(getKind(), getObjKind(), getCount(), getAutoreleaseCount()+1, 201 getType(), getIvarAccessHistory()); 202 } 203 204 RefVal withIvarAccess() const { 205 assert(getIvarAccessHistory() == IvarAccessHistory::None); 206 return RefVal(getKind(), getObjKind(), getCount(), getAutoreleaseCount(), 207 getType(), IvarAccessHistory::AccessedDirectly); 208 } 209 210 RefVal releaseViaIvar() const { 211 assert(getIvarAccessHistory() == IvarAccessHistory::AccessedDirectly); 212 return RefVal(getKind(), getObjKind(), getCount(), getAutoreleaseCount(), 213 getType(), IvarAccessHistory::ReleasedAfterDirectAccess); 214 } 215 216 // Comparison, profiling, and pretty-printing. 217 bool hasSameState(const RefVal &X) const { 218 return getKind() == X.getKind() && Cnt == X.Cnt && ACnt == X.ACnt && 219 getIvarAccessHistory() == X.getIvarAccessHistory(); 220 } 221 222 bool operator==(const RefVal& X) const { 223 return T == X.T && hasSameState(X) && getObjKind() == X.getObjKind(); 224 } 225 226 void Profile(llvm::FoldingSetNodeID& ID) const { 227 ID.Add(T); 228 ID.AddInteger(RawKind); 229 ID.AddInteger(Cnt); 230 ID.AddInteger(ACnt); 231 ID.AddInteger(RawObjectKind); 232 ID.AddInteger(RawIvarAccessHistory); 233 } 234 235 void print(raw_ostream &Out) const; 236 }; 237 238 class RetainCountChecker 239 : public Checker< check::Bind, 240 check::DeadSymbols, 241 check::BeginFunction, 242 check::EndFunction, 243 check::PostStmt<BlockExpr>, 244 check::PostStmt<CastExpr>, 245 check::PostStmt<ObjCArrayLiteral>, 246 check::PostStmt<ObjCDictionaryLiteral>, 247 check::PostStmt<ObjCBoxedExpr>, 248 check::PostStmt<ObjCIvarRefExpr>, 249 check::PostCall, 250 check::RegionChanges, 251 eval::Assume, 252 eval::Call > { 253 254 public: 255 std::unique_ptr<RefCountBug> UseAfterRelease; 256 std::unique_ptr<RefCountBug> ReleaseNotOwned; 257 std::unique_ptr<RefCountBug> DeallocNotOwned; 258 std::unique_ptr<RefCountBug> FreeNotOwned; 259 std::unique_ptr<RefCountBug> OverAutorelease; 260 std::unique_ptr<RefCountBug> ReturnNotOwnedForOwned; 261 std::unique_ptr<RefCountBug> LeakWithinFunction; 262 std::unique_ptr<RefCountBug> LeakAtReturn; 263 264 mutable std::unique_ptr<RetainSummaryManager> Summaries; 265 266 static std::unique_ptr<CheckerProgramPointTag> DeallocSentTag; 267 static std::unique_ptr<CheckerProgramPointTag> CastFailTag; 268 269 /// Track Objective-C and CoreFoundation objects. 270 bool TrackObjCAndCFObjects = false; 271 272 /// Track sublcasses of OSObject. 273 bool TrackOSObjects = false; 274 275 /// Track initial parameters (for the entry point) for NS/CF objects. 276 bool TrackNSCFStartParam = false; 277 278 RetainCountChecker() {}; 279 280 RetainSummaryManager &getSummaryManager(ASTContext &Ctx) const { 281 if (!Summaries) 282 Summaries.reset( 283 new RetainSummaryManager(Ctx, TrackObjCAndCFObjects, TrackOSObjects)); 284 return *Summaries; 285 } 286 287 RetainSummaryManager &getSummaryManager(CheckerContext &C) const { 288 return getSummaryManager(C.getASTContext()); 289 } 290 291 void printState(raw_ostream &Out, ProgramStateRef State, 292 const char *NL, const char *Sep) const override; 293 294 void checkBind(SVal loc, SVal val, const Stmt *S, CheckerContext &C) const; 295 void checkPostStmt(const BlockExpr *BE, CheckerContext &C) const; 296 void checkPostStmt(const CastExpr *CE, CheckerContext &C) const; 297 298 void checkPostStmt(const ObjCArrayLiteral *AL, CheckerContext &C) const; 299 void checkPostStmt(const ObjCDictionaryLiteral *DL, CheckerContext &C) const; 300 void checkPostStmt(const ObjCBoxedExpr *BE, CheckerContext &C) const; 301 302 void checkPostStmt(const ObjCIvarRefExpr *IRE, CheckerContext &C) const; 303 304 void checkPostCall(const CallEvent &Call, CheckerContext &C) const; 305 306 void checkSummary(const RetainSummary &Summ, const CallEvent &Call, 307 CheckerContext &C) const; 308 309 void processSummaryOfInlined(const RetainSummary &Summ, 310 const CallEvent &Call, 311 CheckerContext &C) const; 312 313 bool evalCall(const CallEvent &Call, CheckerContext &C) const; 314 315 ProgramStateRef evalAssume(ProgramStateRef state, SVal Cond, 316 bool Assumption) const; 317 318 ProgramStateRef 319 checkRegionChanges(ProgramStateRef state, 320 const InvalidatedSymbols *invalidated, 321 ArrayRef<const MemRegion *> ExplicitRegions, 322 ArrayRef<const MemRegion *> Regions, 323 const LocationContext* LCtx, 324 const CallEvent *Call) const; 325 326 ExplodedNode* checkReturnWithRetEffect(const ReturnStmt *S, CheckerContext &C, 327 ExplodedNode *Pred, RetEffect RE, RefVal X, 328 SymbolRef Sym, ProgramStateRef state) const; 329 330 void checkDeadSymbols(SymbolReaper &SymReaper, CheckerContext &C) const; 331 void checkBeginFunction(CheckerContext &C) const; 332 void checkEndFunction(const ReturnStmt *RS, CheckerContext &C) const; 333 334 ProgramStateRef updateSymbol(ProgramStateRef state, SymbolRef sym, 335 RefVal V, ArgEffect E, RefVal::Kind &hasErr, 336 CheckerContext &C) const; 337 338 const RefCountBug &errorKindToBugKind(RefVal::Kind ErrorKind, 339 SymbolRef Sym) const; 340 341 void processNonLeakError(ProgramStateRef St, SourceRange ErrorRange, 342 RefVal::Kind ErrorKind, SymbolRef Sym, 343 CheckerContext &C) const; 344 345 void processObjCLiterals(CheckerContext &C, const Expr *Ex) const; 346 347 ProgramStateRef handleSymbolDeath(ProgramStateRef state, 348 SymbolRef sid, RefVal V, 349 SmallVectorImpl<SymbolRef> &Leaked) const; 350 351 ProgramStateRef 352 handleAutoreleaseCounts(ProgramStateRef state, ExplodedNode *Pred, 353 const ProgramPointTag *Tag, CheckerContext &Ctx, 354 SymbolRef Sym, 355 RefVal V, 356 const ReturnStmt *S=nullptr) const; 357 358 ExplodedNode *processLeaks(ProgramStateRef state, 359 SmallVectorImpl<SymbolRef> &Leaked, 360 CheckerContext &Ctx, 361 ExplodedNode *Pred = nullptr) const; 362 363 static const CheckerProgramPointTag &getDeallocSentTag() { 364 return *DeallocSentTag; 365 } 366 367 static const CheckerProgramPointTag &getCastFailTag() { return *CastFailTag; } 368 369 private: 370 /// Perform the necessary checks and state adjustments at the end of the 371 /// function. 372 /// \p S Return statement, may be null. 373 ExplodedNode * processReturn(const ReturnStmt *S, CheckerContext &C) const; 374 }; 375 376 //===----------------------------------------------------------------------===// 377 // RefBindings - State used to track object reference counts. 378 //===----------------------------------------------------------------------===// 379 380 const RefVal *getRefBinding(ProgramStateRef State, SymbolRef Sym); 381 382 /// Returns true if this stack frame is for an Objective-C method that is a 383 /// property getter or setter whose body has been synthesized by the analyzer. 384 inline bool isSynthesizedAccessor(const StackFrameContext *SFC) { 385 auto Method = dyn_cast_or_null<ObjCMethodDecl>(SFC->getDecl()); 386 if (!Method || !Method->isPropertyAccessor()) 387 return false; 388 389 return SFC->getAnalysisDeclContext()->isBodyAutosynthesized(); 390 } 391 392 } // end namespace retaincountchecker 393 } // end namespace ento 394 } // end namespace clang 395 396 #endif 397