1 //== RetainCountDiagnostics.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 diagnostics 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_DIAGNOSTICS_H 15 #define LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_RETAINCOUNTCHECKER_DIAGNOSTICS_H 16 17 #include "clang/Analysis/PathDiagnostic.h" 18 #include "clang/Analysis/RetainSummaryManager.h" 19 #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" 20 #include "clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h" 21 #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" 22 23 namespace clang { 24 namespace ento { 25 namespace retaincountchecker { 26 27 class RefCountBug : public BugType { 28 public: 29 enum RefCountBugKind { 30 UseAfterRelease, 31 ReleaseNotOwned, 32 DeallocNotOwned, 33 FreeNotOwned, 34 OverAutorelease, 35 ReturnNotOwnedForOwned, 36 LeakWithinFunction, 37 LeakAtReturn, 38 }; 39 RefCountBug(CheckerNameRef Checker, RefCountBugKind BT); 40 StringRef getDescription() const; 41 42 RefCountBugKind getBugType() const { return BT; } 43 44 private: 45 RefCountBugKind BT; 46 static StringRef bugTypeToName(RefCountBugKind BT); 47 }; 48 49 class RefCountReport : public PathSensitiveBugReport { 50 protected: 51 SymbolRef Sym; 52 bool isLeak = false; 53 54 public: 55 RefCountReport(const RefCountBug &D, const LangOptions &LOpts, 56 ExplodedNode *n, SymbolRef sym, 57 bool isLeak=false); 58 59 RefCountReport(const RefCountBug &D, const LangOptions &LOpts, 60 ExplodedNode *n, SymbolRef sym, 61 StringRef endText); 62 63 ArrayRef<SourceRange> getRanges() const override { 64 if (!isLeak) 65 return PathSensitiveBugReport::getRanges(); 66 return {}; 67 } 68 }; 69 70 class RefLeakReport : public RefCountReport { 71 const MemRegion *AllocFirstBinding = nullptr; 72 const MemRegion *AllocBindingToReport = nullptr; 73 const Stmt *AllocStmt = nullptr; 74 PathDiagnosticLocation Location; 75 76 // Finds the function declaration where a leak warning for the parameter 77 // 'sym' should be raised. 78 void deriveParamLocation(CheckerContext &Ctx); 79 // Finds the location where the leaking object is allocated. 80 void deriveAllocLocation(CheckerContext &Ctx); 81 // Produces description of a leak warning which is printed on the console. 82 void createDescription(CheckerContext &Ctx); 83 // Finds the binding that we should use in a leak warning. 84 void findBindingToReport(CheckerContext &Ctx, ExplodedNode *Node); 85 86 public: 87 RefLeakReport(const RefCountBug &D, const LangOptions &LOpts, ExplodedNode *n, 88 SymbolRef sym, CheckerContext &Ctx); 89 PathDiagnosticLocation getLocation() const override { 90 assert(Location.isValid()); 91 return Location; 92 } 93 94 PathDiagnosticLocation getEndOfPath() const { 95 return PathSensitiveBugReport::getLocation(); 96 } 97 }; 98 99 } // end namespace retaincountchecker 100 } // end namespace ento 101 } // end namespace clang 102 103 #endif 104