brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.7 KiB · 6ceb86f Raw
123 lines · c
1//== RetainCountDiagnostics.h - Checks for leaks and other issues -*- C++ -*--//2//3// 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-exception6//7//===----------------------------------------------------------------------===//8//9//  This file defines diagnostics for RetainCountChecker, which implements10//  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_H15#define LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_RETAINCOUNTCHECKER_DIAGNOSTICS_H16 17#include "clang/Analysis/PathDiagnostic.h"18#include "clang/Analysis/RetainSummaryManager.h"19#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"20#include "clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h"21#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"22 23namespace clang {24namespace ento {25namespace retaincountchecker {26 27class RefCountBug : public BugType {28  StringRef ReportMessage;29 30public:31  RefCountBug(const CheckerFrontend *CF, StringRef Desc, StringRef ReportMsg,32              bool SuppressOnSink = false)33      : BugType(CF, Desc, categories::MemoryRefCount, SuppressOnSink),34        ReportMessage(ReportMsg) {}35  StringRef getReportMessage() const { return ReportMessage; }36};37 38class RefCountFrontend : public CheckerFrontend {39public:40  const RefCountBug UseAfterRelease{41      this, "Use-after-release",42      "Reference-counted object is used after it is released"};43  const RefCountBug ReleaseNotOwned{44      this, "Bad release",45      "Incorrect decrement of the reference count of an object that is not "46      "owned at this point by the caller"};47  const RefCountBug DeallocNotOwned{48      this, "-dealloc sent to non-exclusively owned object",49      "-dealloc sent to object that may be referenced elsewhere"};50  const RefCountBug FreeNotOwned{51      this, "freeing non-exclusively owned object",52      "'free' called on an object that may be referenced elsewhere"};53  const RefCountBug OverAutorelease{this, "Object autoreleased too many times",54                                    "Object autoreleased too many times"};55  const RefCountBug ReturnNotOwnedForOwned{56      this, "Method should return an owned object",57      "Object with a +0 retain count returned to caller where a +1 (owning) "58      "retain count is expected"};59  // For these two bug types the report message will be generated dynamically60  // by `RefLeakReport::createDescription` so the empty string taken from the61  // BugType will be ignored (overwritten).62  const RefCountBug LeakWithinFunction{this, "Leak", /*ReportMsg=*/"",63                                       /*SuppressOnSink=*/true};64  const RefCountBug LeakAtReturn{this, "Leak of returned object",65                                 /*ReportMsg=*/"", /*SuppressOnSink=*/true};66};67 68class RefCountReport : public PathSensitiveBugReport {69protected:70  SymbolRef Sym;71  bool isLeak = false;72 73public:74  RefCountReport(const RefCountBug &D, const LangOptions &LOpts,75                 ExplodedNode *n, SymbolRef sym, bool isLeak = false,76                 bool IsReleaseUnowned = false);77 78  RefCountReport(const RefCountBug &D, const LangOptions &LOpts,79              ExplodedNode *n, SymbolRef sym,80              StringRef endText);81 82  ArrayRef<SourceRange> getRanges() const override {83    if (!isLeak)84      return PathSensitiveBugReport::getRanges();85    return {};86  }87};88 89class RefLeakReport : public RefCountReport {90  const MemRegion *AllocFirstBinding = nullptr;91  const MemRegion *AllocBindingToReport = nullptr;92  const Stmt *AllocStmt = nullptr;93  PathDiagnosticLocation Location;94 95  // Finds the function declaration where a leak warning for the parameter96  // 'sym' should be raised.97  void deriveParamLocation(CheckerContext &Ctx);98  // Finds the location where the leaking object is allocated.99  void deriveAllocLocation(CheckerContext &Ctx);100  // Produces description of a leak warning which is printed on the console.101  void createDescription(CheckerContext &Ctx);102  // Finds the binding that we should use in a leak warning.103  void findBindingToReport(CheckerContext &Ctx, ExplodedNode *Node);104 105public:106  RefLeakReport(const RefCountBug &D, const LangOptions &LOpts, ExplodedNode *n,107                SymbolRef sym, CheckerContext &Ctx);108  PathDiagnosticLocation getLocation() const override {109    assert(Location.isValid());110    return Location;111  }112 113  PathDiagnosticLocation getEndOfPath() const {114    return PathSensitiveBugReport::getLocation();115  }116};117 118} // end namespace retaincountchecker119} // end namespace ento120} // end namespace clang121 122#endif123