 |
|
 |
|
| 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 |
| |
 |
|
 |
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