summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp3
-rw-r--r--clang/test/Analysis/Inputs/system-header-simulator-objc.h5
-rw-r--r--clang/test/Analysis/malloc.mm23
3 files changed, 29 insertions, 2 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
index 01c7afe5204..09306383d53 100644
--- a/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
@@ -1469,6 +1469,9 @@ void MallocChecker::checkPostObjCMessage(const ObjCMethodCall &Call,
if (!*FreeWhenDone)
return;
+ if (Call.hasNonZeroCallbackArg())
+ return;
+
bool IsKnownToBeAllocatedMemory;
ProgramStateRef State =
FreeMemAux(C, Call.getArgExpr(0), Call.getOriginExpr(), C.getState(),
diff --git a/clang/test/Analysis/Inputs/system-header-simulator-objc.h b/clang/test/Analysis/Inputs/system-header-simulator-objc.h
index df751d03e64..0dc6b369b01 100644
--- a/clang/test/Analysis/Inputs/system-header-simulator-objc.h
+++ b/clang/test/Analysis/Inputs/system-header-simulator-objc.h
@@ -117,7 +117,10 @@ typedef double NSTimeInterval;
+ (id)dataWithBytesNoCopy:(void *)bytes length:(NSUInteger)length freeWhenDone:(BOOL)b;
- (id)initWithBytesNoCopy:(void *)bytes length:(NSUInteger)length;
- (id)initWithBytesNoCopy:(void *)bytes length:(NSUInteger)length freeWhenDone:(BOOL)b;
-- (id)initWithBytes:(void *)bytes length:(NSUInteger) length;
+- (id)initWithBytesNoCopy:(void *)bytes
+ length:(NSUInteger)length
+ deallocator:(void (^)(void *bytes, NSUInteger length))deallocator;
+- (id)initWithBytes:(void *)bytes length:(NSUInteger)length;
@end
typedef struct {
diff --git a/clang/test/Analysis/malloc.mm b/clang/test/Analysis/malloc.mm
index e84644b9dd7..1b7dd2756e1 100644
--- a/clang/test/Analysis/malloc.mm
+++ b/clang/test/Analysis/malloc.mm
@@ -1,4 +1,8 @@
-// RUN: %clang_analyze_cc1 -std=c++14 -analyzer-checker=core,unix.Malloc -analyzer-store=region -verify -fblocks %s
+// RUN: %clang_analyze_cc1 -std=c++14 \
+// RUN: -analyzer-checker=core,unix.Malloc,cplusplus.NewDelete \
+// RUN: -analyzer-checker=unix.MismatchedDeallocator \
+// RUN: -verify -fblocks %s
+
#import "Inputs/system-header-simulator-objc.h"
#import "Inputs/system-header-simulator-for-malloc.h"
@@ -61,6 +65,23 @@ void testNSStringFreeWhenDoneNO(NSUInteger dataLength) {
NSString *nsstr = [[NSString alloc] initWithBytesNoCopy:data length:dataLength encoding:NSUTF8StringEncoding freeWhenDone:0]; // expected-warning{{leak}}
}
+void testNSStringFreeWhenDoneNewDelete(NSUInteger dataLength) {
+ unsigned char *data = new unsigned char(42);
+ NSData *nsdata = [[NSData alloc] initWithBytesNoCopy:data
+ length:dataLength freeWhenDone:1];
+ // expected-warning@-2{{-initWithBytesNoCopy:length:freeWhenDone: cannot take ownership of memory allocated by 'new'}}
+}
+
+void testNSStringFreeWhenDoneNewDelete2(NSUInteger dataLength) {
+ unsigned char *data = new unsigned char(42);
+ NSData *nsdata = [[NSData alloc] initWithBytesNoCopy:data
+ length:dataLength
+ deallocator:^(void *bytes,
+ NSUInteger length) {
+ delete (unsigned char *)bytes;
+ }]; // no-warning
+}
+
void testNSStringFreeWhenDoneNO2(NSUInteger dataLength) {
unichar *data = (unichar*)malloc(42);
NSString *nsstr = [[NSString alloc] initWithCharactersNoCopy:data length:dataLength freeWhenDone:0]; // expected-warning{{leak}}
OpenPOWER on IntegriCloud