diff options
-rw-r--r-- | lib/StaticAnalyzer/Checkers/MallocChecker.cpp | 12 | ||||
-rw-r--r-- | test/Analysis/malloc.c | 19 | ||||
-rw-r--r-- | test/Analysis/system-header-simulator.h | 7 |
3 files changed, 33 insertions, 5 deletions
diff --git a/lib/StaticAnalyzer/Checkers/MallocChecker.cpp b/lib/StaticAnalyzer/Checkers/MallocChecker.cpp index c22c6a2687..1adcca03fd 100644 --- a/lib/StaticAnalyzer/Checkers/MallocChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/MallocChecker.cpp @@ -1334,12 +1334,14 @@ bool MallocChecker::doesNotFreeMemory(const CallOrObjCMessage *Call, return false; } - // A bunch of other functions, which take ownership of a pointer (See retain - // release checker). Not all the parameters here are invalidated, but the - // Malloc checker cannot differentiate between them. The right way of doing - // this would be to implement a pointer escapes callback. - if (FName == "CVPixelBufferCreateWithBytes" || + // A bunch of other functions which either take ownership of a pointer or + // wrap the result up in a struct or object, meaning it can be freed later. + // (See RetainCountChecker.) Not all the parameters here are invalidated, + // but the Malloc checker cannot differentiate between them. The right way + // of doing this would be to implement a pointer escapes callback. + if (FName == "CGBitmapContextCreate" || FName == "CGBitmapContextCreateWithData" || + FName == "CVPixelBufferCreateWithBytes" || FName == "CVPixelBufferCreateWithPlanarBytes" || FName == "OSAtomicEnqueue") { return false; diff --git a/test/Analysis/malloc.c b/test/Analysis/malloc.c index 7c2196ac9e..c532d6813f 100644 --- a/test/Analysis/malloc.c +++ b/test/Analysis/malloc.c @@ -955,3 +955,22 @@ void test_double_assign_ints_positive() (void*)(long)(unsigned long)ptr; // expected-warning {{unused}} expected-warning {{leak}} } + +void testCGContextNoLeak() +{ + void *ptr = malloc(16); + CGContextRef context = CGBitmapContextCreate(ptr); + + // Because you can get the data back out like this, even much later, + // CGBitmapContextCreate is one of our "stop-tracking" exceptions. + free(CGBitmapContextGetData(context)); +} + +void testCGContextLeak() +{ + void *ptr = malloc(16); + CGContextRef context = CGBitmapContextCreate(ptr); + // However, this time we're just leaking the data, because the context + // object doesn't escape and it hasn't been freed in this function. +} + diff --git a/test/Analysis/system-header-simulator.h b/test/Analysis/system-header-simulator.h index a8cba9ce5b..d2fb2e8684 100644 --- a/test/Analysis/system-header-simulator.h +++ b/test/Analysis/system-header-simulator.h @@ -46,3 +46,10 @@ typedef struct { int dealocateMemWhenDoneByVal(void*, StWithCallback); int dealocateMemWhenDoneByRef(StWithCallback*, const void*); + +typedef struct CGContext *CGContextRef; +CGContextRef CGBitmapContextCreate(void *data/*, size_t width, size_t height, + size_t bitsPerComponent, size_t bytesPerRow, + CGColorSpaceRef space, + CGBitmapInfo bitmapInfo*/); +void *CGBitmapContextGetData(CGContextRef context); |