forked from OSchip/llvm-project
[analyzer] Malloc Checker: Give up when a pointer escapes into a struct.
We are not properly handling the memory regions that escape into struct fields, which led to a bunch of false positives. Be conservative here and give up when a pointer escapes into a struct. llvm-svn: 150658
This commit is contained in:
parent
17100bad0a
commit
d32ead82d9
|
@ -924,6 +924,12 @@ void MallocChecker::checkBind(SVal loc, SVal val, const Stmt *S,
|
|||
// the binding).
|
||||
escapes = (state == (state->bindLoc(*regionLoc, val)));
|
||||
}
|
||||
if (!escapes) {
|
||||
// Case 4: We do not currently model what happens when a symbol is
|
||||
// assigned to a struct field, so be conservative here and let the symbol
|
||||
// go. TODO: This could definitely be improved upon.
|
||||
escapes = !isa<VarRegion>(regionLoc->getRegion());
|
||||
}
|
||||
}
|
||||
|
||||
// If our store can represent the binding and we aren't storing to something
|
||||
|
|
|
@ -68,9 +68,10 @@ void af1_c() {
|
|||
myglobalpointer = my_malloc(12); // no-warning
|
||||
}
|
||||
|
||||
// TODO: We will be able to handle this after we add support for tracking allocations stored in struct fields.
|
||||
void af1_d() {
|
||||
struct stuff mystuff;
|
||||
mystuff.somefield = my_malloc(12); // expected-warning{{Allocated memory never released. Potential memory leak.}}
|
||||
mystuff.somefield = my_malloc(12); // false negative
|
||||
}
|
||||
|
||||
// Test that we can pass out allocated memory via pointer-to-pointer.
|
||||
|
|
|
@ -485,6 +485,33 @@ void GlobalStructMallocFree() {
|
|||
free(GlS.x);
|
||||
}
|
||||
|
||||
// Make sure that we properly handle a pointer stored into a local struct/array.
|
||||
typedef struct _StructWithPtr {
|
||||
int *memP;
|
||||
} StructWithPtr;
|
||||
|
||||
static StructWithPtr arrOfStructs[10];
|
||||
|
||||
void testMalloc() {
|
||||
int *x = malloc(12);
|
||||
StructWithPtr St;
|
||||
St.memP = x;
|
||||
arrOfStructs[0] = St;
|
||||
}
|
||||
|
||||
StructWithPtr testMalloc2() {
|
||||
int *x = malloc(12);
|
||||
StructWithPtr St;
|
||||
St.memP = x;
|
||||
return St;
|
||||
}
|
||||
|
||||
int *testMalloc3() {
|
||||
int *x = malloc(12);
|
||||
int *y = x;
|
||||
return y;
|
||||
}
|
||||
|
||||
// Region escape testing.
|
||||
|
||||
unsigned takePtrToPtr(int **p);
|
||||
|
@ -600,3 +627,11 @@ void symbolLostWithStrcpy(char *s) {
|
|||
free(p);// expected-warning {{leak}}
|
||||
}
|
||||
|
||||
// False negatives.
|
||||
|
||||
// TODO: This requires tracking symbols stored inside the structs/arrays.
|
||||
void testMalloc5() {
|
||||
StructWithPtr St;
|
||||
StructWithPtr *pSt = &St;
|
||||
pSt->memP = malloc(12);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue