aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/StaticAnalyzer/Core/ExprEngine.cpp6
-rw-r--r--test/Analysis/malloc-annotations.c16
-rw-r--r--test/Analysis/malloc.c40
-rw-r--r--test/Analysis/malloc.cpp7
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
+}