diff options
author | Artem Dergachev <artem.dergachev@gmail.com> | 2019-12-18 13:19:44 -0800 |
---|---|---|
committer | Artem Dergachev <artem.dergachev@gmail.com> | 2019-12-18 14:19:17 -0800 |
commit | bce1cce6bf1286541c57690ab1129fbc02c60f93 (patch) | |
tree | 4cf25681fce27f6ddb0180fea571a739ad98a615 /clang/test/Analysis/malloc.mm | |
parent | 997bc8b2e6b973dd8c9b17414310cac822543f79 (diff) | |
download | bcm5719-llvm-bce1cce6bf1286541c57690ab1129fbc02c60f93.tar.gz bcm5719-llvm-bce1cce6bf1286541c57690ab1129fbc02c60f93.zip |
[analyzer] Teach MismatchedDealloc about initWithBytesNoCopy with deallocator.
MallocChecker warns when memory is passed into -[NSData initWithBytesNoCopy]
but isn't allocated by malloc(), because it will be deallocated by free().
However, initWithBytesNoCopy has an overload that takes an arbitrary block
for deallocating the object. If such overload is used, it is no longer
necessary to make sure that the memory is allocated by malloc().
Diffstat (limited to 'clang/test/Analysis/malloc.mm')
-rw-r--r-- | clang/test/Analysis/malloc.mm | 23 |
1 files changed, 22 insertions, 1 deletions
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}} |