blob: 8b19d75fb127fecbd3dce56cc8f272495e509f87 [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;
40 RefCountBugType getBugType() const {
41 return BT;
42 }
Vlad Tsyrklevichd5dd6a52019-01-18 08:43:22 +000043
George Karpenkov2c2d0b62019-01-18 19:24:55 +000044private:
45 RefCountBugType BT;
46 static StringRef bugTypeToName(RefCountBugType BT);
George Karpenkov70c2ee32018-08-17 21:41:07 +000047};
48
George Karpenkov0bb17c42019-01-10 18:16:25 +000049class RefCountReport : public BugReport {
George Karpenkovf893ea12018-11-30 02:17:44 +000050protected:
51 SymbolRef Sym;
George Karpenkov2c2d0b62019-01-18 19:24:55 +000052 bool isLeak = false;
George Karpenkov70c2ee32018-08-17 21:41:07 +000053
54public:
George Karpenkov2c2d0b62019-01-18 19:24:55 +000055 RefCountReport(const RefCountBug &D, const LangOptions &LOpts,
George Karpenkov717c4c02019-01-10 18:15:17 +000056 ExplodedNode *n, SymbolRef sym,
George Karpenkov2c2d0b62019-01-18 19:24:55 +000057 bool isLeak=false);
George Karpenkov70c2ee32018-08-17 21:41:07 +000058
George Karpenkov2c2d0b62019-01-18 19:24:55 +000059 RefCountReport(const RefCountBug &D, const LangOptions &LOpts,
George Karpenkov717c4c02019-01-10 18:15:17 +000060 ExplodedNode *n, SymbolRef sym,
George Karpenkov62db8862018-11-30 02:18:23 +000061 StringRef endText);
George Karpenkov70c2ee32018-08-17 21:41:07 +000062
63 llvm::iterator_range<ranges_iterator> getRanges() override {
George Karpenkov2c2d0b62019-01-18 19:24:55 +000064 if (!isLeak)
George Karpenkov70c2ee32018-08-17 21:41:07 +000065 return BugReport::getRanges();
66 return llvm::make_range(ranges_iterator(), ranges_iterator());
67 }
68};
69
George Karpenkov0bb17c42019-01-10 18:16:25 +000070class RefLeakReport : public RefCountReport {
George Karpenkov70c2ee32018-08-17 21:41:07 +000071 const MemRegion* AllocBinding;
72 const Stmt *AllocStmt;
73
74 // Finds the function declaration where a leak warning for the parameter
75 // 'sym' should be raised.
76 void deriveParamLocation(CheckerContext &Ctx, SymbolRef sym);
77 // Finds the location where a leak warning for 'sym' should be raised.
78 void deriveAllocLocation(CheckerContext &Ctx, SymbolRef sym);
79 // Produces description of a leak warning which is printed on the console.
George Karpenkov936a9c92018-12-07 20:21:37 +000080 void createDescription(CheckerContext &Ctx);
George Karpenkov70c2ee32018-08-17 21:41:07 +000081
82public:
George Karpenkov2c2d0b62019-01-18 19:24:55 +000083 RefLeakReport(const RefCountBug &D, const LangOptions &LOpts, ExplodedNode *n,
George Karpenkov0bb17c42019-01-10 18:16:25 +000084 SymbolRef sym, CheckerContext &Ctx);
George Karpenkov70c2ee32018-08-17 21:41:07 +000085
86 PathDiagnosticLocation getLocation(const SourceManager &SM) const override {
87 assert(Location.isValid());
88 return Location;
89 }
90};
91
92} // end namespace retaincountchecker
93} // end namespace ento
94} // end namespace clang
95
96#endif