diff options
-rw-r--r-- | lib/StaticAnalyzer/Core/ExprEngine.cpp | 6 | ||||
-rw-r--r-- | test/Analysis/malloc-annotations.c | 16 | ||||
-rw-r--r-- | test/Analysis/malloc.c | 40 | ||||
-rw-r--r-- | test/Analysis/malloc.cpp | 7 |
4 files changed, 46 insertions, 23 deletions
diff --git a/lib/StaticAnalyzer/Core/ExprEngine.cpp b/lib/StaticAnalyzer/Core/ExprEngine.cpp index 26a3f9b1f5..636aa3bd0d 100644 --- a/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ b/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -1627,6 +1627,12 @@ ProgramStateRef ExprEngine::processPointerEscapedOnBind(ProgramStateRef State, if (StoredVal != Val) 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 diff --git a/test/Analysis/malloc-annotations.c b/test/Analysis/malloc-annotations.c index 3a260c3aef..bdd50c6be5 100644 --- a/test/Analysis/malloc-annotations.c +++ b/test/Analysis/malloc-annotations.c @@ -70,11 +70,6 @@ void af1_c() { myglobalpointer = my_malloc(12); // no-warning } -void af1_d() { - struct stuff mystuff; - mystuff.somefield = my_malloc(12); -} // expected-warning{{Memory is never released; potential leak}} - // Test that we can pass out allocated memory via pointer-to-pointer. void af1_e(void **pp) { *pp = my_malloc(42); // no-warning @@ -267,3 +262,14 @@ void testMultipleFreeAnnotations() { my_freeBoth(p, q); } +// ---------------------------------------------------------------------------- + +// False negatives. + +// Pending on removal of the escaping on assignment to struct fields. +void af1_d() { + struct stuff mystuff; + mystuff.somefield = my_malloc(12); +} // missing warning + + diff --git a/test/Analysis/malloc.c b/test/Analysis/malloc.c index 3e5f914e9d..ed2d8e9d50 100644 --- a/test/Analysis/malloc.c +++ b/test/Analysis/malloc.c @@ -530,12 +530,6 @@ int *testMalloc3() { return y; // no-warning } -void testStructLeak() { - StructWithPtr St; - St.memP = malloc(12); - return; // expected-warning {{Memory is never released; potential leak of memory pointed to by 'St.memP'}} -} - void testElemRegion1() { char *x = (void*)malloc(2); int *ix = (int*)x; @@ -934,18 +928,6 @@ int cmpHeapAllocationToUnknown() { return 0; } -void localArrayTest() { - char *p = (char*)malloc(12); - char *ArrayL[12]; - ArrayL[0] = p; -} // expected-warning {{leak}} - -void localStructTest() { - StructWithPtr St; - StructWithPtr *pSt = &St; - pSt->memP = malloc(12); -} // expected-warning{{Memory is never released; potential leak}} - #ifdef __INTPTR_TYPE__ // Test double assignment through integers. typedef __INTPTR_TYPE__ intptr_t; @@ -1053,3 +1035,25 @@ void testMallocWithParam(int **p) { void testMallocWithParam_2(int **p) { *p = (int*) malloc(sizeof(int)); } + +// Pending on removal of the escaping on assignment to struct fields. +void testStructLeak() { + StructWithPtr St; + St.memP = malloc(12); + return; // missing warning +} + +void localArrayTest() { + char *p = (char*)malloc(12); + char *ArrayL[12]; + ArrayL[0] = p; +} // missing warning + +void localStructTest() { + StructWithPtr St; + StructWithPtr *pSt = &St; + pSt->memP = malloc(12); +} // missing warning + + + diff --git a/test/Analysis/malloc.cpp b/test/Analysis/malloc.cpp index 58b94ea774..a7c365289f 100644 --- a/test/Analysis/malloc.cpp +++ b/test/Analysis/malloc.cpp @@ -60,3 +60,10 @@ namespace PR13751 { } } +struct X { void *a; }; + +struct X get() { + struct X result; + result.a = malloc(4); + return result; // no-warning +} |