blob: e0b53e4387c16f4d6f11faa78e2536f39b223cdb [file] [log] [blame]
George Karpenkov70c2ee32018-08-17 21:41:07 +00001//== RetainCountDiagnostics.h - Checks for leaks and other issues -*- C++ -*--//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// 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
George Karpenkov70c2ee32018-08-17 21:41:07 +00006//
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
George Karpenkov70c2ee32018-08-17 21:41:07 +000017#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
18#include "clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h"
19#include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h"
George Karpenkovefef49c2018-08-21 03:09:02 +000020#include "clang/StaticAnalyzer/Core/RetainSummaryManager.h"
George Karpenkov70c2ee32018-08-17 21:41:07 +000021
22namespace clang {
23namespace ento {
24namespace retaincountchecker {
25
George Karpenkov0bb17c42019-01-10 18:16:25 +000026class RefCountBug : public BugType {
Vlad Tsyrklevichd5dd6a52019-01-18 08:43:22 +000027public:
George Karpenkov2c2d0b62019-01-18 19:24:55 +000028 enum RefCountBugType {
29 UseAfterRelease,
30 ReleaseNotOwned,
31 DeallocNotOwned,
32 FreeNotOwned,
33 OverAutorelease,
34 ReturnNotOwnedForOwned,
35 LeakWithinFunction,
36 LeakAtReturn,
37 };
38 RefCountBug(const CheckerBase *checker, RefCountBugType BT);
39 StringRef getDescription() const;
George Karpenkova9e29562019-01-22 19:51:00 +000040
George Karpenkov2c2d0b62019-01-18 19:24:55 +000041 RefCountBugType getBugType() const {
42 return BT;
43 }
Vlad Tsyrklevichd5dd6a52019-01-18 08:43:22 +000044
George Karpenkova9e29562019-01-22 19:51:00 +000045 const CheckerBase *getChecker() const {
46 return Checker;
47 }
48
George Karpenkov2c2d0b62019-01-18 19:24:55 +000049private:
50 RefCountBugType BT;
George Karpenkova9e29562019-01-22 19:51:00 +000051 const CheckerBase *Checker;
George Karpenkov2c2d0b62019-01-18 19:24:55 +000052 static StringRef bugTypeToName(RefCountBugType BT);
George Karpenkov70c2ee32018-08-17 21:41:07 +000053};
54
George Karpenkov0bb17c42019-01-10 18:16:25 +000055class RefCountReport : public BugReport {
George Karpenkovf893ea12018-11-30 02:17:44 +000056protected:
57 SymbolRef Sym;
George Karpenkov2c2d0b62019-01-18 19:24:55 +000058 bool isLeak = false;
George Karpenkov70c2ee32018-08-17 21:41:07 +000059
60public:
George Karpenkov2c2d0b62019-01-18 19:24:55 +000061 RefCountReport(const RefCountBug &D, const LangOptions &LOpts,
George Karpenkov717c4c02019-01-10 18:15:17 +000062 ExplodedNode *n, SymbolRef sym,
George Karpenkov2c2d0b62019-01-18 19:24:55 +000063 bool isLeak=false);
George Karpenkov70c2ee32018-08-17 21:41:07 +000064
George Karpenkov2c2d0b62019-01-18 19:24:55 +000065 RefCountReport(const RefCountBug &D, const LangOptions &LOpts,
George Karpenkov717c4c02019-01-10 18:15:17 +000066 ExplodedNode *n, SymbolRef sym,
George Karpenkov62db8862018-11-30 02:18:23 +000067 StringRef endText);
George Karpenkov70c2ee32018-08-17 21:41:07 +000068
69 llvm::iterator_range<ranges_iterator> getRanges() override {
George Karpenkov2c2d0b62019-01-18 19:24:55 +000070 if (!isLeak)
George Karpenkov70c2ee32018-08-17 21:41:07 +000071 return BugReport::getRanges();
72 return llvm::make_range(ranges_iterator(), ranges_iterator());
73 }
74};
75
George Karpenkov0bb17c42019-01-10 18:16:25 +000076class RefLeakReport : public RefCountReport {
George Karpenkov70c2ee32018-08-17 21:41:07 +000077 const MemRegion* AllocBinding;
78 const Stmt *AllocStmt;
79
80 // Finds the function declaration where a leak warning for the parameter
81 // 'sym' should be raised.
82 void deriveParamLocation(CheckerContext &Ctx, SymbolRef sym);
83 // Finds the location where a leak warning for 'sym' should be raised.
84 void deriveAllocLocation(CheckerContext &Ctx, SymbolRef sym);
85 // Produces description of a leak warning which is printed on the console.
George Karpenkov936a9c92018-12-07 20:21:37 +000086 void createDescription(CheckerContext &Ctx);
George Karpenkov70c2ee32018-08-17 21:41:07 +000087
88public:
George Karpenkov2c2d0b62019-01-18 19:24:55 +000089 RefLeakReport(const RefCountBug &D, const LangOptions &LOpts, ExplodedNode *n,
George Karpenkov0bb17c42019-01-10 18:16:25 +000090 SymbolRef sym, CheckerContext &Ctx);
George Karpenkov70c2ee32018-08-17 21:41:07 +000091
92 PathDiagnosticLocation getLocation(const SourceManager &SM) const override {
93 assert(Location.isValid());
94 return Location;
95 }
96};
97
98} // end namespace retaincountchecker
99} // end namespace ento
100} // end namespace clang
101
102#endif