[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