From: Anna Zaks Date: Thu, 16 Feb 2012 03:40:57 +0000 (+0000) Subject: [analyzer] Malloc Checker: Give up when a pointer escapes into a struct. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ac593008c2035fa241c80352a0c97c5d853facbf;p=clang [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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@150658 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/StaticAnalyzer/Checkers/MallocChecker.cpp b/lib/StaticAnalyzer/Checkers/MallocChecker.cpp index 88a0613a78..a14057980f 100644 --- a/lib/StaticAnalyzer/Checkers/MallocChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/MallocChecker.cpp @@ -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(regionLoc->getRegion()); + } } // If our store can represent the binding and we aren't storing to something diff --git a/test/Analysis/malloc-annotations.c b/test/Analysis/malloc-annotations.c index 98dc2e7269..4ee60ae14f 100644 --- a/test/Analysis/malloc-annotations.c +++ b/test/Analysis/malloc-annotations.c @@ -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. diff --git a/test/Analysis/malloc.c b/test/Analysis/malloc.c index ec9c19de88..62a4f29322 100644 --- a/test/Analysis/malloc.c +++ b/test/Analysis/malloc.c @@ -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); +}