xref: /openbsd-src/gnu/llvm/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.h (revision a9ac8606c53d55cee9c3a39778b249c51df111ef)
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