[cfe-commits] r151121 - in /cfe/trunk: lib/StaticAnalyzer/Checkers/MallocChecker.cpp test/Analysis/malloc.c
Anna Zaks
ganna at apple.com
Tue Feb 21 18:36:01 PST 2012
Author: zaks
Date: Tue Feb 21 20:36:01 2012
New Revision: 151121
URL: http://llvm.org/viewvc/llvm-project?rev=151121&view=rev
Log:
[analyzer] Malloc: fix another false positive.
, when we return a symbol reachable to the malloced one via pointer
arithmetic.
Modified:
cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
cfe/trunk/test/Analysis/malloc.c
Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp?rev=151121&r1=151120&r2=151121&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp Tue Feb 21 20:36:01 2012
@@ -881,7 +881,17 @@
return;
// Check if we are returning a symbol.
- SymbolRef Sym = C.getState()->getSVal(E, C.getLocationContext()).getAsSymbol();
+ SVal RetVal = C.getState()->getSVal(E, C.getLocationContext());
+ SymbolRef Sym = RetVal.getAsSymbol();
+ if (!Sym)
+ // If we are returning a field of the allocated struct or an array element,
+ // the callee could still free the memory.
+ // TODO: This logic should be a part of generic symbol escape callback.
+ if (const MemRegion *MR = RetVal.getAsRegion())
+ if (isa<FieldRegion>(MR) || isa<ElementRegion>(MR))
+ if (const SymbolicRegion *BMR =
+ dyn_cast<SymbolicRegion>(MR->getBaseRegion()))
+ Sym = BMR->getSymbol();
if (!Sym)
return;
Modified: cfe/trunk/test/Analysis/malloc.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/malloc.c?rev=151121&r1=151120&r2=151121&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/malloc.c (original)
+++ cfe/trunk/test/Analysis/malloc.c Tue Feb 21 20:36:01 2012
@@ -631,6 +631,27 @@
p = ((__builtin_object_size (p, 0) != (size_t) -1) ? __builtin___strcpy_chk (p, s, __builtin_object_size (p, 2 > 1)) : __inline_strcpy_chk (p, s));
free(p);
}
+
+// Here we are returning a pointer one past the allocated value. An idiom which
+// can be used for implementing special malloc. The correct uses of this might
+// be rare enough so that we could keep this as a warning.
+static void *specialMalloc(int n){
+ int *p;
+ p = malloc( n+8 );
+ if( p ){
+ p[0] = n;
+ p++;
+ }
+ return p;
+}
+
+// Potentially, the user could free the struct by performing pointer arithmetic on the return value.
+// This is a variation of the specialMalloc issue, though probably would be more rare in correct code.
+int *specialMallocWithStruct() {
+ struct StructWithInt *px= malloc(sizeof(struct StructWithInt));
+ return &(px->g);
+}
+
// Below are the known false positives.
// TODO: There should be no warning here. This one might be difficult to get rid of.
@@ -650,20 +671,6 @@
return;
}
-// TODO: Should this be a warning?
-// Here we are returning a pointer one past the allocated value. An idiom which
-// can be used for implementing special malloc. The correct uses of this might
-// be rare enough so that we could keep this as a warning.
-static void *specialMalloc(int n){
- int *p;
- p = malloc( n+8 );
- if( p ){
- p[0] = n;
- p++;
- }
- return p;// expected-warning {{Memory is never released; potential memory leak}}
-}
-
// False negatives.
// TODO: This requires tracking symbols stored inside the structs/arrays.
@@ -673,6 +680,16 @@
pSt->memP = malloc(12);
}
+// TODO: This is another false negative.
+void testMallocWithParam(int **p) {
+ *p = (int*) malloc(sizeof(int));
+ *p = 0;
+}
+
+void testMallocWithParam_2(int **p) {
+ *p = (int*) malloc(sizeof(int));
+}
+
// TODO: This should produce a warning, similar to the previous issue.
void localArrayTest() {
char *p = (char*)malloc(12);
More information about the cfe-commits
mailing list