[cfe-commits] r156215 - in /cfe/trunk: lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp test/Analysis/retain-release.m

Anna Zaks ganna at apple.com
Fri May 4 15:18:39 PDT 2012


Author: zaks
Date: Fri May  4 17:18:39 2012
New Revision: 156215

URL: http://llvm.org/viewvc/llvm-project?rev=156215&view=rev
Log:
[analyzer] RetainCountChecker: Allow objects to escape through callbacks

Fixes radar://10973977.

Modified:
    cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
    cfe/trunk/test/Analysis/retain-release.m

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp?rev=156215&r1=156214&r2=156215&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp Fri May  4 17:18:39 2012
@@ -739,7 +739,8 @@
     InitializeMethodSummaries();
   }
 
-  const RetainSummary *getSummary(const FunctionDecl *FD);
+  const RetainSummary *getSummary(const FunctionDecl *FD,
+                                  const CallOrObjCMessage *CME = 0);
 
   const RetainSummary *getMethodSummary(Selector S, IdentifierInfo *ClsName,
                                         const ObjCInterfaceDecl *ID,
@@ -886,7 +887,9 @@
   return FName.find("MakeCollectable") != StringRef::npos;
 }
 
-const RetainSummary * RetainSummaryManager::getSummary(const FunctionDecl *FD) {
+const RetainSummary *
+RetainSummaryManager::getSummary(const FunctionDecl *FD,
+                                 const CallOrObjCMessage *CME) {
   // Look up a summary in our cache of FunctionDecls -> Summaries.
   FuncSummariesTy::iterator I = FuncSummaries.find(FD);
   if (I != FuncSummaries.end())
@@ -1001,6 +1004,11 @@
       ScratchArgs = AF.add(ScratchArgs, 1, StopTracking);
       ScratchArgs = AF.add(ScratchArgs, 2, StopTracking);
       S = getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, DoNothing);
+    } else if (CME && CME->hasNonZeroCallbackArg()) {
+      // Allow objects to escape throug callbacks. radar://10973977
+      for (unsigned I = 0; I < CME->getNumArgs(); ++I)
+        ScratchArgs = AF.add(ScratchArgs, I, StopTracking);
+      S = getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, DoNothing);
     }
 
     // Did we get a summary?
@@ -2633,10 +2641,13 @@
   if (dyn_cast_or_null<BlockDataRegion>(L.getAsRegion())) {
     Summ = Summaries.getPersistentStopSummary();
   } else if (const FunctionDecl *FD = L.getAsFunctionDecl()) {
-    Summ = Summaries.getSummary(FD);
+    CallOrObjCMessage CME(CE, state, C.getLocationContext());
+    Summ = Summaries.getSummary(FD, &CME);
   } else if (const CXXMemberCallExpr *me = dyn_cast<CXXMemberCallExpr>(CE)) {
-    if (const CXXMethodDecl *MD = me->getMethodDecl())
-      Summ = Summaries.getSummary(MD);
+    if (const CXXMethodDecl *MD = me->getMethodDecl()) {
+      CallOrObjCMessage CME(CE, state, C.getLocationContext());
+      Summ = Summaries.getSummary(MD, &CME);
+    }
   }
 
   if (!Summ)
@@ -2652,13 +2663,14 @@
     return;
 
   RetainSummaryManager &Summaries = getSummaryManager(C);
-  const RetainSummary *Summ = Summaries.getSummary(Ctor);
+  ProgramStateRef state = C.getState();
+  CallOrObjCMessage CME(CE, state, C.getLocationContext());
+  const RetainSummary *Summ = Summaries.getSummary(Ctor, &CME);
 
   // If we didn't get a summary, this constructor doesn't affect retain counts.
   if (!Summ)
     return;
 
-  ProgramStateRef state = C.getState();
   checkSummary(*Summ, CallOrObjCMessage(CE, state, C.getLocationContext()), C);
 }
 
@@ -3250,7 +3262,7 @@
 
   if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(CD)) {
     if (!isa<CXXMethodDecl>(FD))
-      if (const RetainSummary *Summ = Summaries.getSummary(FD))
+      if (const RetainSummary *Summ = Summaries.getSummary(FD, 0))
         checkReturnWithRetEffect(S, C, Pred, Summ->getRetEffect(), X,
                                  Sym, state);
   }

Modified: cfe/trunk/test/Analysis/retain-release.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/retain-release.m?rev=156215&r1=156214&r2=156215&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/retain-release.m (original)
+++ cfe/trunk/test/Analysis/retain-release.m Fri May  4 17:18:39 2012
@@ -1686,6 +1686,32 @@
   }
 }
 
+// Stop tracking objects passed to functions, which take callbacks as parameters.
+// radar://10973977
+typedef int (*CloseCallback) (void *);
+void ReaderForIO(CloseCallback ioclose, void *ioctx);
+int IOClose(void *context);
+
+ at protocol SInS <NSObject>
+ at end
+
+ at interface radar10973977 : NSObject
+- (id<SInS>)inputS;
+- (void)reader;
+ at end
+
+ at implementation radar10973977
+- (void)reader
+{
+    id<SInS> inputS = [[self inputS] retain];
+    ReaderForIO(IOClose, inputS);
+}
+- (id<SInS>)inputS
+{
+    return 0;
+}
+ at end
+
 //===----------------------------------------------------------------------===//
 // Test returning allocated memory in a struct.
 // 





More information about the cfe-commits mailing list