1e5dd7070Spatrick //== RetainCountDiagnostics.h - Checks for leaks and other issues -*- C++ -*--// 2e5dd7070Spatrick // 3e5dd7070Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4e5dd7070Spatrick // See https://llvm.org/LICENSE.txt for license information. 5e5dd7070Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6e5dd7070Spatrick // 7e5dd7070Spatrick //===----------------------------------------------------------------------===// 8e5dd7070Spatrick // 9e5dd7070Spatrick // This file defines diagnostics for RetainCountChecker, which implements 10e5dd7070Spatrick // a reference count checker for Core Foundation and Cocoa on (Mac OS X). 11e5dd7070Spatrick // 12e5dd7070Spatrick //===----------------------------------------------------------------------===// 13e5dd7070Spatrick 14e5dd7070Spatrick #ifndef LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_RETAINCOUNTCHECKER_DIAGNOSTICS_H 15e5dd7070Spatrick #define LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_RETAINCOUNTCHECKER_DIAGNOSTICS_H 16e5dd7070Spatrick 17e5dd7070Spatrick #include "clang/Analysis/PathDiagnostic.h" 18e5dd7070Spatrick #include "clang/Analysis/RetainSummaryManager.h" 19e5dd7070Spatrick #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" 20e5dd7070Spatrick #include "clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h" 21e5dd7070Spatrick #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" 22e5dd7070Spatrick 23e5dd7070Spatrick namespace clang { 24e5dd7070Spatrick namespace ento { 25e5dd7070Spatrick namespace retaincountchecker { 26e5dd7070Spatrick 27e5dd7070Spatrick class RefCountBug : public BugType { 28e5dd7070Spatrick public: 29ec727ea7Spatrick enum RefCountBugKind { 30e5dd7070Spatrick UseAfterRelease, 31e5dd7070Spatrick ReleaseNotOwned, 32e5dd7070Spatrick DeallocNotOwned, 33e5dd7070Spatrick FreeNotOwned, 34e5dd7070Spatrick OverAutorelease, 35e5dd7070Spatrick ReturnNotOwnedForOwned, 36e5dd7070Spatrick LeakWithinFunction, 37e5dd7070Spatrick LeakAtReturn, 38e5dd7070Spatrick }; 39ec727ea7Spatrick RefCountBug(CheckerNameRef Checker, RefCountBugKind BT); 40e5dd7070Spatrick StringRef getDescription() const; 41e5dd7070Spatrick getBugType()42ec727ea7Spatrick RefCountBugKind getBugType() const { return BT; } 43e5dd7070Spatrick 44e5dd7070Spatrick private: 45ec727ea7Spatrick RefCountBugKind BT; 46ec727ea7Spatrick static StringRef bugTypeToName(RefCountBugKind BT); 47e5dd7070Spatrick }; 48e5dd7070Spatrick 49e5dd7070Spatrick class RefCountReport : public PathSensitiveBugReport { 50e5dd7070Spatrick protected: 51e5dd7070Spatrick SymbolRef Sym; 52e5dd7070Spatrick bool isLeak = false; 53e5dd7070Spatrick 54e5dd7070Spatrick public: 55e5dd7070Spatrick RefCountReport(const RefCountBug &D, const LangOptions &LOpts, 56e5dd7070Spatrick ExplodedNode *n, SymbolRef sym, 57e5dd7070Spatrick bool isLeak=false); 58e5dd7070Spatrick 59e5dd7070Spatrick RefCountReport(const RefCountBug &D, const LangOptions &LOpts, 60e5dd7070Spatrick ExplodedNode *n, SymbolRef sym, 61e5dd7070Spatrick StringRef endText); 62e5dd7070Spatrick getRanges()63e5dd7070Spatrick ArrayRef<SourceRange> getRanges() const override { 64e5dd7070Spatrick if (!isLeak) 65e5dd7070Spatrick return PathSensitiveBugReport::getRanges(); 66e5dd7070Spatrick return {}; 67e5dd7070Spatrick } 68e5dd7070Spatrick }; 69e5dd7070Spatrick 70e5dd7070Spatrick class RefLeakReport : public RefCountReport { 71*a9ac8606Spatrick const MemRegion *AllocFirstBinding = nullptr; 72*a9ac8606Spatrick const MemRegion *AllocBindingToReport = nullptr; 73*a9ac8606Spatrick const Stmt *AllocStmt = nullptr; 74e5dd7070Spatrick PathDiagnosticLocation Location; 75e5dd7070Spatrick 76e5dd7070Spatrick // Finds the function declaration where a leak warning for the parameter 77e5dd7070Spatrick // 'sym' should be raised. 78*a9ac8606Spatrick void deriveParamLocation(CheckerContext &Ctx); 79*a9ac8606Spatrick // Finds the location where the leaking object is allocated. 80*a9ac8606Spatrick void deriveAllocLocation(CheckerContext &Ctx); 81e5dd7070Spatrick // Produces description of a leak warning which is printed on the console. 82e5dd7070Spatrick void createDescription(CheckerContext &Ctx); 83*a9ac8606Spatrick // Finds the binding that we should use in a leak warning. 84*a9ac8606Spatrick void findBindingToReport(CheckerContext &Ctx, ExplodedNode *Node); 85e5dd7070Spatrick 86e5dd7070Spatrick public: 87e5dd7070Spatrick RefLeakReport(const RefCountBug &D, const LangOptions &LOpts, ExplodedNode *n, 88e5dd7070Spatrick SymbolRef sym, CheckerContext &Ctx); getLocation()89e5dd7070Spatrick PathDiagnosticLocation getLocation() const override { 90e5dd7070Spatrick assert(Location.isValid()); 91e5dd7070Spatrick return Location; 92e5dd7070Spatrick } 93e5dd7070Spatrick getEndOfPath()94e5dd7070Spatrick PathDiagnosticLocation getEndOfPath() const { 95e5dd7070Spatrick return PathSensitiveBugReport::getLocation(); 96e5dd7070Spatrick } 97e5dd7070Spatrick }; 98e5dd7070Spatrick 99e5dd7070Spatrick } // end namespace retaincountchecker 100e5dd7070Spatrick } // end namespace ento 101e5dd7070Spatrick } // end namespace clang 102e5dd7070Spatrick 103e5dd7070Spatrick #endif 104