From d99bd55a5e092774214ba31fc5a871bfc31e711c Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Thu, 23 Dec 2010 19:38:26 +0000 Subject: Chris Lattner has strong opinions about directory layout. :) Rename the 'EntoSA' directories to 'StaticAnalyzer'. Internally we will still use the 'ento' namespace for the analyzer engine (unless there are further sabre rattlings...). llvm-svn: 122514 --- .../EntoSA/Checkers/NSAutoreleasePoolChecker.cpp | 87 ++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 clang/lib/StaticAnalyzer/EntoSA/Checkers/NSAutoreleasePoolChecker.cpp (limited to 'clang/lib/StaticAnalyzer/EntoSA/Checkers/NSAutoreleasePoolChecker.cpp') diff --git a/clang/lib/StaticAnalyzer/EntoSA/Checkers/NSAutoreleasePoolChecker.cpp b/clang/lib/StaticAnalyzer/EntoSA/Checkers/NSAutoreleasePoolChecker.cpp new file mode 100644 index 00000000000..6ef242ba427 --- /dev/null +++ b/clang/lib/StaticAnalyzer/EntoSA/Checkers/NSAutoreleasePoolChecker.cpp @@ -0,0 +1,87 @@ +//=- NSAutoreleasePoolChecker.cpp --------------------------------*- C++ -*-==// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines a NSAutoreleasePoolChecker, a small checker that warns +// about subpar uses of NSAutoreleasePool. Note that while the check itself +// (in it's current form) could be written as a flow-insensitive check, in +// can be potentially enhanced in the future with flow-sensitive information. +// It is also a good example of the CheckerVisitor interface. +// +//===----------------------------------------------------------------------===// + +#include "clang/StaticAnalyzer/BugReporter/BugReporter.h" +#include "clang/StaticAnalyzer/PathSensitive/ExprEngine.h" +#include "clang/StaticAnalyzer/PathSensitive/CheckerVisitor.h" +#include "BasicObjCFoundationChecks.h" +#include "clang/AST/DeclObjC.h" +#include "clang/AST/Decl.h" + +using namespace clang; +using namespace ento; + +namespace { +class NSAutoreleasePoolChecker + : public CheckerVisitor { + + Selector releaseS; + +public: + NSAutoreleasePoolChecker(Selector release_s) : releaseS(release_s) {} + + static void *getTag() { + static int x = 0; + return &x; + } + + void PreVisitObjCMessageExpr(CheckerContext &C, const ObjCMessageExpr *ME); +}; + +} // end anonymous namespace + + +void ento::RegisterNSAutoreleasePoolChecks(ExprEngine &Eng) { + ASTContext &Ctx = Eng.getContext(); + if (Ctx.getLangOptions().getGCMode() != LangOptions::NonGC) { + Eng.registerCheck(new NSAutoreleasePoolChecker(GetNullarySelector("release", + Ctx))); + } +} + +void +NSAutoreleasePoolChecker::PreVisitObjCMessageExpr(CheckerContext &C, + const ObjCMessageExpr *ME) { + + const Expr *receiver = ME->getInstanceReceiver(); + if (!receiver) + return; + + // FIXME: Enhance with value-tracking information instead of consulting + // the type of the expression. + const ObjCObjectPointerType* PT = + receiver->getType()->getAs(); + + if (!PT) + return; + const ObjCInterfaceDecl* OD = PT->getInterfaceDecl(); + if (!OD) + return; + if (!OD->getIdentifier()->getName().equals("NSAutoreleasePool")) + return; + + // Sending 'release' message? + if (ME->getSelector() != releaseS) + return; + + SourceRange R = ME->getSourceRange(); + + C.getBugReporter().EmitBasicReport("Use -drain instead of -release", + "API Upgrade (Apple)", + "Use -drain instead of -release when using NSAutoreleasePool " + "and garbage collection", ME->getLocStart(), &R, 1); +} -- cgit v1.2.3