]> granicus.if.org Git - clang/commitdiff
Fix leak in ObjCSelfInitChecker, found by LSan.
authorNico Weber <nicolasweber@gmx.de>
Tue, 6 May 2014 17:33:42 +0000 (17:33 +0000)
committerNico Weber <nicolasweber@gmx.de>
Tue, 6 May 2014 17:33:42 +0000 (17:33 +0000)
BugReport doesn't take ownership of the bug type, so let the checker own the
the bug type.  (Requires making the bug type mutable, which is icky, but which
is also what other checkers do.)

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@208110 91177308-0d34-0410-b5e6-96231b3b80d8

lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp

index 6c33084c2db7be85e155967ea4bc161a1ae7f239..3eec6815c9049c582463e655a8ccebba3978b343 100644 (file)
@@ -55,6 +55,13 @@ static bool isInitMessage(const ObjCMethodCall &Msg);
 static bool isSelfVar(SVal location, CheckerContext &C);
 
 namespace {
+class InitSelfBug : public BugType {
+public:
+  InitSelfBug(const CheckerBase *Checker)
+      : BugType(Checker, "Missing \"self = [(super or self) init...]\"",
+                categories::CoreFoundationObjectiveC) {}
+};
+
 class ObjCSelfInitChecker : public Checker<  check::PostObjCMessage,
                                              check::PostStmt<ObjCIvarRefExpr>,
                                              check::PreStmt<ReturnStmt>,
@@ -62,7 +69,13 @@ class ObjCSelfInitChecker : public Checker<  check::PostObjCMessage,
                                              check::PostCall,
                                              check::Location,
                                              check::Bind > {
+  mutable InitSelfBug InitSelfBugType;
+
+  void checkForInvalidSelf(const Expr *E, CheckerContext &C,
+                           const char *errorStr) const;
+
 public:
+  ObjCSelfInitChecker() : InitSelfBugType(this) {}
   void checkPostObjCMessage(const ObjCMethodCall &Msg, CheckerContext &C) const;
   void checkPostStmt(const ObjCIvarRefExpr *E, CheckerContext &C) const;
   void checkPreStmt(const ReturnStmt *S, CheckerContext &C) const;
@@ -78,17 +91,6 @@ public:
 };
 } // end anonymous namespace
 
-namespace {
-
-class InitSelfBug : public BugType {
-public:
-  InitSelfBug(const CheckerBase *Checker)
-      : BugType(Checker, "Missing \"self = [(super or self) init...]\"",
-                categories::CoreFoundationObjectiveC) {}
-};
-
-} // end anonymous namespace
-
 namespace {
 enum SelfFlagEnum {
   /// \brief No flag set.
@@ -146,9 +148,8 @@ static bool isInvalidSelf(const Expr *E, CheckerContext &C) {
   return true;
 }
 
-static void checkForInvalidSelf(const Expr *E, CheckerContext &C,
-                                const char *errorStr,
-                                const CheckerBase *Checker) {
+void ObjCSelfInitChecker::checkForInvalidSelf(const Expr *E, CheckerContext &C,
+                                              const char *errorStr) const {
   if (!E)
     return;
   
@@ -163,7 +164,7 @@ static void checkForInvalidSelf(const Expr *E, CheckerContext &C,
   if (!N)
     return;
 
-  BugReport *report = new BugReport(*new InitSelfBug(Checker), errorStr, N);
+  BugReport *report = new BugReport(InitSelfBugType, errorStr, N);
   C.emitReport(report);
 }
 
@@ -208,8 +209,7 @@ void ObjCSelfInitChecker::checkPostStmt(const ObjCIvarRefExpr *E,
   checkForInvalidSelf(
       E->getBase(), C,
       "Instance variable used while 'self' is not set to the result of "
-      "'[(super or self) init...]'",
-      this);
+      "'[(super or self) init...]'");
 }
 
 void ObjCSelfInitChecker::checkPreStmt(const ReturnStmt *S,
@@ -221,8 +221,7 @@ void ObjCSelfInitChecker::checkPreStmt(const ReturnStmt *S,
 
   checkForInvalidSelf(S->getRetValue(), C,
                       "Returning 'self' while it is not set to the result of "
-                      "'[(super or self) init...]'",
-                      this);
+                      "'[(super or self) init...]'");
 }
 
 // When a call receives a reference to 'self', [Pre/Post]Call pass