[cfe-commits] r156135 - in /cfe/trunk: lib/StaticAnalyzer/Core/ObjCMessage.cpp test/Analysis/malloc.c test/Analysis/system-header-simulator.h

Anna Zaks ganna at apple.com
Thu May 3 16:50:33 PDT 2012


Author: zaks
Date: Thu May  3 18:50:33 2012
New Revision: 156135

URL: http://llvm.org/viewvc/llvm-project?rev=156135&view=rev
Log:
[analyzer] Assume pointer escapes when a callback is passed inside
a struct.

Modified:
    cfe/trunk/lib/StaticAnalyzer/Core/ObjCMessage.cpp
    cfe/trunk/test/Analysis/malloc.c
    cfe/trunk/test/Analysis/system-header-simulator.h

Modified: cfe/trunk/lib/StaticAnalyzer/Core/ObjCMessage.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ObjCMessage.cpp?rev=156135&r1=156134&r2=156135&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/ObjCMessage.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ObjCMessage.cpp Thu May  3 18:50:33 2012
@@ -89,10 +89,28 @@
 }
 
 bool CallOrObjCMessage::isCallbackArg(unsigned Idx, const Type *T) const {
-  // Should we dig into struct fields, arrays ect?
+  // If the parameter is 0, it's harmless.
+  if (getArgSVal(Idx).isZeroConstant())
+    return false;
+    
+  // If a parameter is a block or a callback, assume it can modify pointer.
   if (T->isBlockPointerType() || T->isFunctionPointerType())
-    if (!getArgSVal(Idx).isZeroConstant())
-      return true;
+    return true;
+
+  // Check if a callback is passed inside a struct (for both, struct passed by
+  // reference and by value). Dig just one level into the struct for now.
+  if (const PointerType *PT = dyn_cast<PointerType>(T))
+    T = PT->getPointeeType().getTypePtr();
+
+  if (const RecordType *RT = T->getAsStructureType()) {
+    const RecordDecl *RD = RT->getDecl();
+    for (RecordDecl::field_iterator I = RD->field_begin(),
+                                    E = RD->field_end(); I != E; ++I ) {
+      const Type *FieldT = I->getType().getTypePtr();
+      if (FieldT->isBlockPointerType() || FieldT->isFunctionPointerType())
+        return true;
+    }
+  }
   return false;
 }
 

Modified: cfe/trunk/test/Analysis/malloc.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/malloc.c?rev=156135&r1=156134&r2=156135&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/malloc.c (original)
+++ cfe/trunk/test/Analysis/malloc.c Thu May  3 18:50:33 2012
@@ -819,6 +819,16 @@
   sqlite3_bind_text_my(0, x, 12, free); // no - warning
 }
 
+// Passing callbacks in a struct.
+void r11160612_5(StWithCallback St) {
+  void *x = malloc(12);
+  dealocateMemWhenDoneByVal(x, St);
+}
+void r11160612_6(StWithCallback St) {
+  void *x = malloc(12);
+  dealocateMemWhenDoneByRef(&St, x);
+}
+
 // ----------------------------------------------------------------------------
 // Below are the known false positives.
 

Modified: cfe/trunk/test/Analysis/system-header-simulator.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/system-header-simulator.h?rev=156135&r1=156134&r2=156135&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/system-header-simulator.h (original)
+++ cfe/trunk/test/Analysis/system-header-simulator.h Thu May  3 18:50:33 2012
@@ -37,3 +37,12 @@
                  int (*)(void *));
 
 int sqlite3_bind_text_my(int, const char*, int n, void(*)(void*));
+
+typedef void (*freeCallback) (void*);
+typedef struct {
+  int i;
+  freeCallback fc;
+} StWithCallback;
+
+int dealocateMemWhenDoneByVal(void*, StWithCallback);
+int dealocateMemWhenDoneByRef(StWithCallback*, const void*);





More information about the cfe-commits mailing list