r262272 - [analyzer] Teach CheckObjCDealloc about Block_release().

Devin Coughlin via cfe-commits cfe-commits at lists.llvm.org
Mon Feb 29 15:57:10 PST 2016


Author: dcoughlin
Date: Mon Feb 29 17:57:10 2016
New Revision: 262272

URL: http://llvm.org/viewvc/llvm-project?rev=262272&view=rev
Log:
[analyzer] Teach CheckObjCDealloc about Block_release().

It now treats Block_release(b) as a release in addition to [b release].

Modified:
    cfe/trunk/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp
    cfe/trunk/test/Analysis/DeallocMissingRelease.m
    cfe/trunk/test/Analysis/Inputs/system-header-simulator-for-objc-dealloc.h

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp?rev=262272&r1=262271&r2=262272&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp Mon Feb 29 17:57:10 2016
@@ -92,12 +92,13 @@ namespace {
 class ObjCDeallocChecker
     : public Checker<check::ASTDecl<ObjCImplementationDecl>,
                      check::PreObjCMessage, check::PostObjCMessage,
+                     check::PreCall,
                      check::BeginFunction, check::EndFunction,
                      eval::Assume,
                      check::PointerEscape,
                      check::PreStmt<ReturnStmt>> {
 
-  mutable IdentifierInfo *NSObjectII, *SenTestCaseII;
+  mutable IdentifierInfo *NSObjectII, *SenTestCaseII, *Block_releaseII;
   mutable Selector DeallocSel, ReleaseSel;
 
   std::unique_ptr<BugType> MissingReleaseBugType;
@@ -110,6 +111,7 @@ public:
                     BugReporter &BR) const;
   void checkBeginFunction(CheckerContext &Ctx) const;
   void checkPreObjCMessage(const ObjCMethodCall &M, CheckerContext &C) const;
+  void checkPreCall(const CallEvent &Call, CheckerContext &C) const;
   void checkPostObjCMessage(const ObjCMethodCall &M, CheckerContext &C) const;
 
   ProgramStateRef evalAssume(ProgramStateRef State, SVal Cond,
@@ -152,6 +154,7 @@ private:
   const ObjCPropertyDecl *
   findShadowedPropertyDecl(const ObjCPropertyImplDecl *PropImpl) const;
 
+  void transitionToReleaseValue(CheckerContext &C, SymbolRef Value) const;
   ProgramStateRef removeValueRequiringRelease(ProgramStateRef State,
                                               SymbolRef InstanceSym,
                                               SymbolRef ValueSym) const;
@@ -341,19 +344,26 @@ void ObjCDeallocChecker::checkPreObjCMes
   if (!ReleasedValue)
     return;
 
-  SymbolRef InstanceSym = getInstanceSymbolFromIvarSymbol(ReleasedValue);
-  if (!InstanceSym)
+  transitionToReleaseValue(C, ReleasedValue);
+}
+
+/// If we are in -dealloc or -dealloc is on the stack, handle the call if it is
+/// call to Block_release().
+void ObjCDeallocChecker::checkPreCall(const CallEvent &Call,
+                                      CheckerContext &C) const {
+  const IdentifierInfo *II = Call.getCalleeIdentifier();
+  if (II != Block_releaseII)
     return;
-  ProgramStateRef InitialState = C.getState();
 
-  ProgramStateRef ReleasedState =
-      removeValueRequiringRelease(InitialState, InstanceSym, ReleasedValue);
+  if (Call.getNumArgs() != 1)
+    return;
 
-  if (ReleasedState != InitialState) {
-    C.addTransition(ReleasedState);
-  }
-}
+  SymbolRef ReleasedValue = Call.getArgSVal(0).getAsSymbol();
+  if (!ReleasedValue)
+    return;
 
+  transitionToReleaseValue(C, ReleasedValue);
+}
 /// If the message was a call to '[super dealloc]', diagnose any missing
 /// releases.
 void ObjCDeallocChecker::checkPostObjCMessage(
@@ -684,6 +694,7 @@ void ObjCDeallocChecker::initIdentifierI
 
   NSObjectII = &Ctx.Idents.get("NSObject");
   SenTestCaseII = &Ctx.Idents.get("SenTestCase");
+  Block_releaseII = &Ctx.Idents.get("_Block_release");
 
   IdentifierInfo *DeallocII = &Ctx.Idents.get("dealloc");
   IdentifierInfo *ReleaseII = &Ctx.Idents.get("release");
@@ -739,6 +750,23 @@ const ObjCPropertyDecl *ObjCDeallocCheck
   return nullptr;
 }
 
+/// Add a transition noting the release of the given value.
+void ObjCDeallocChecker::transitionToReleaseValue(CheckerContext &C,
+                                                  SymbolRef Value) const {
+  assert(Value);
+  SymbolRef InstanceSym = getInstanceSymbolFromIvarSymbol(Value);
+  if (!InstanceSym)
+    return;
+  ProgramStateRef InitialState = C.getState();
+
+  ProgramStateRef ReleasedState =
+      removeValueRequiringRelease(InitialState, InstanceSym, Value);
+
+  if (ReleasedState != InitialState) {
+    C.addTransition(ReleasedState);
+  }
+}
+
 /// Remove the Value requiring a release from the tracked set for
 /// Instance and return the resultant state.
 ProgramStateRef ObjCDeallocChecker::removeValueRequiringRelease(

Modified: cfe/trunk/test/Analysis/DeallocMissingRelease.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/DeallocMissingRelease.m?rev=262272&r1=262271&r2=262272&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/DeallocMissingRelease.m (original)
+++ cfe/trunk/test/Analysis/DeallocMissingRelease.m Mon Feb 29 17:57:10 2016
@@ -125,6 +125,9 @@
   void (^_blockPropertyIvar)(void);
 }
 @property (copy) void (^blockProperty)(void);
+ at property (copy) void (^blockProperty2)(void);
+ at property (copy) void (^blockProperty3)(void);
+
 @end
 
 @implementation MyPropertyClass4
@@ -132,6 +135,9 @@
 - (void)dealloc
 {
 #if NON_ARC
+  [_blockProperty2 release];
+  Block_release(_blockProperty3);
+
   [super dealloc]; // expected-warning {{The '_blockPropertyIvar' ivar in 'MyPropertyClass4' was copied by a synthesized property but not released before '[super dealloc]'}}
 #endif
 }

Modified: cfe/trunk/test/Analysis/Inputs/system-header-simulator-for-objc-dealloc.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/Inputs/system-header-simulator-for-objc-dealloc.h?rev=262272&r1=262271&r2=262272&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/Inputs/system-header-simulator-for-objc-dealloc.h (original)
+++ cfe/trunk/test/Analysis/Inputs/system-header-simulator-for-objc-dealloc.h Mon Feb 29 17:57:10 2016
@@ -27,3 +27,6 @@ typedef signed char BOOL;
 @end
 
 typedef struct objc_selector *SEL;
+
+void _Block_release(const void *aBlock);
+#define Block_release(...) _Block_release((const void *)(__VA_ARGS__))




More information about the cfe-commits mailing list