1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
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/RetainSummaryManager.h" |
18 | #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" |
19 | #include "clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h" |
20 | #include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.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 RefCountBugType { |
30 | UseAfterRelease, |
31 | ReleaseNotOwned, |
32 | DeallocNotOwned, |
33 | FreeNotOwned, |
34 | OverAutorelease, |
35 | ReturnNotOwnedForOwned, |
36 | LeakWithinFunction, |
37 | LeakAtReturn, |
38 | }; |
39 | RefCountBug(const CheckerBase *checker, RefCountBugType BT); |
40 | StringRef getDescription() const; |
41 | |
42 | RefCountBugType getBugType() const { |
43 | return BT; |
44 | } |
45 | |
46 | const CheckerBase *getChecker() const { |
47 | return Checker; |
48 | } |
49 | |
50 | private: |
51 | RefCountBugType BT; |
52 | const CheckerBase *Checker; |
53 | static StringRef bugTypeToName(RefCountBugType BT); |
54 | }; |
55 | |
56 | class RefCountReport : public BugReport { |
57 | protected: |
58 | SymbolRef Sym; |
59 | bool isLeak = false; |
60 | |
61 | public: |
62 | RefCountReport(const RefCountBug &D, const LangOptions &LOpts, |
63 | ExplodedNode *n, SymbolRef sym, |
64 | bool isLeak=false); |
65 | |
66 | RefCountReport(const RefCountBug &D, const LangOptions &LOpts, |
67 | ExplodedNode *n, SymbolRef sym, |
68 | StringRef endText); |
69 | |
70 | llvm::iterator_range<ranges_iterator> getRanges() override { |
71 | if (!isLeak) |
72 | return BugReport::getRanges(); |
73 | return llvm::make_range(ranges_iterator(), ranges_iterator()); |
74 | } |
75 | }; |
76 | |
77 | class RefLeakReport : public RefCountReport { |
78 | const MemRegion* AllocBinding; |
79 | const Stmt *AllocStmt; |
80 | |
81 | |
82 | |
83 | void deriveParamLocation(CheckerContext &Ctx, SymbolRef sym); |
84 | |
85 | void deriveAllocLocation(CheckerContext &Ctx, SymbolRef sym); |
86 | |
87 | void createDescription(CheckerContext &Ctx); |
88 | |
89 | public: |
90 | RefLeakReport(const RefCountBug &D, const LangOptions &LOpts, ExplodedNode *n, |
91 | SymbolRef sym, CheckerContext &Ctx); |
92 | |
93 | PathDiagnosticLocation getLocation(const SourceManager &SM) const override { |
94 | assert(Location.isValid()); |
95 | return Location; |
96 | } |
97 | }; |
98 | |
99 | } |
100 | } |
101 | } |
102 | |
103 | #endif |
104 | |