aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/StaticAnalyzer/Checkers/MallocChecker.cpp6
-rw-r--r--test/Analysis/malloc-annotations.c3
-rw-r--r--test/Analysis/malloc.c35
3 files changed, 43 insertions, 1 deletions
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<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 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);
+}