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