zcov: / lib/Checker/NSAutoreleasePoolChecker.cpp


Files: 1 Branches Taken: 81.2% 13 / 16
Generated: 2010-02-10 01:31 Branches Executed: 87.5% 14 / 16
Line Coverage: 96.2% 25 / 26


Programs: 1 Runs 2897


       1                 : //=- NSAutoreleasePoolChecker.cpp --------------------------------*- C++ -*-==//
       2                 : //
       3                 : //                     The LLVM Compiler Infrastructure
       4                 : //
       5                 : // This file is distributed under the University of Illinois Open Source
       6                 : // License. See LICENSE.TXT for details.
       7                 : //
       8                 : //===----------------------------------------------------------------------===//
       9                 : //
      10                 : //  This file defines a NSAutoreleasePoolChecker, a small checker that warns
      11                 : //  about subpar uses of NSAutoreleasePool.  Note that while the check itself
      12                 : //  (in it's current form) could be written as a flow-insensitive check, in
      13                 : //  can be potentially enhanced in the future with flow-sensitive information.
      14                 : //  It is also a good example of the CheckerVisitor interface. 
      15                 : //
      16                 : //===----------------------------------------------------------------------===//
      17                 : 
      18                 : #include "clang/Checker/BugReporter/BugReporter.h"
      19                 : #include "clang/Checker/PathSensitive/GRExprEngine.h"
      20                 : #include "clang/Checker/PathSensitive/CheckerVisitor.h"
      21                 : #include "BasicObjCFoundationChecks.h"
      22                 : #include "clang/AST/DeclObjC.h"
      23                 : #include "clang/AST/Decl.h"
      24                 : 
      25                 : using namespace clang;
      26                 : 
      27                 : namespace {
      28                 : class NSAutoreleasePoolChecker
                      430: branch 1 taken
                        0: branch 2 not taken
                        0: branch 5 not taken
                        0: branch 6 not taken
      29              430:   : public CheckerVisitor<NSAutoreleasePoolChecker> {
      30                 :       
      31                 :   Selector releaseS;
      32                 : 
      33                 : public:
      34              430:     NSAutoreleasePoolChecker(Selector release_s) : releaseS(release_s) {}
      35                 :     
      36              430:   static void *getTag() {
      37                 :     static int x = 0;
      38              430:     return &x;
      39                 :   }
      40                 : 
      41                 :   void PreVisitObjCMessageExpr(CheckerContext &C, const ObjCMessageExpr *ME);    
      42                 : };
      43                 : 
      44                 : } // end anonymous namespace
      45                 : 
      46                 : 
      47             2138: void clang::RegisterNSAutoreleasePoolChecks(GRExprEngine &Eng) {
      48             2138:   ASTContext &Ctx = Eng.getContext();
                      430: branch 2 taken
                     1708: branch 3 taken
      49             2138:   if (Ctx.getLangOptions().getGCMode() != LangOptions::NonGC) {    
      50                 :     Eng.registerCheck(new NSAutoreleasePoolChecker(GetNullarySelector("release",
      51              430:                                                                       Ctx)));
      52                 :   }
      53             2138: }
      54                 : 
      55                 : void
      56                 : NSAutoreleasePoolChecker::PreVisitObjCMessageExpr(CheckerContext &C,
      57              184:                                                   const ObjCMessageExpr *ME) {
      58                 :   
      59              184:   const Expr *receiver = ME->getReceiver();
                       24: branch 0 taken
                      160: branch 1 taken
      60              184:   if (!receiver)
      61               24:     return;
      62                 :   
      63                 :   // FIXME: Enhance with value-tracking information instead of consulting
      64                 :   // the type of the expression.
      65                 :   const ObjCObjectPointerType* PT =
      66              160:     receiver->getType()->getAs<ObjCObjectPointerType>();
      67                 :   
                        2: branch 0 taken
                      158: branch 1 taken
      68              160:   if (!PT)
      69                2:     return;  
      70              158:   const ObjCInterfaceDecl* OD = PT->getInterfaceDecl();
                      124: branch 0 taken
                       34: branch 1 taken
      71              158:   if (!OD)
      72              124:     return;  
                       20: branch 4 taken
                       14: branch 5 taken
      73               34:   if (!OD->getIdentifier()->getName().equals("NSAutoreleasePool"))
      74               20:     return;
      75                 :   
      76                 :   // Sending 'release' message?
                       12: branch 2 taken
                        2: branch 3 taken
      77               14:   if (ME->getSelector() != releaseS)
      78               12:     return;
      79                 :                      
      80                2:   SourceRange R = ME->getSourceRange();
      81                 : 
      82                 :   C.getBugReporter().EmitBasicReport("Use -drain instead of -release",
      83                 :     "API Upgrade (Apple)",
      84                 :     "Use -drain instead of -release when using NSAutoreleasePool "
      85                2:     "and garbage collection", ME->getLocStart(), &R, 1);
      86                0: }

Generated: 2010-02-10 01:31 by zcov