From c2cca2361aeafdf9170de2695b17d8bcd1c6f7db Mon Sep 17 00:00:00 2001 From: Anna Zaks Date: Tue, 11 Dec 2012 00:17:53 +0000 Subject: [PATCH] [analyzer] Don't generate a summary for "freeWhenDone" if method is inlined. Fixes a false positive that occurs if a user writes their own initWithBytesNoCopy:freeWhenDone wrapper. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@169795 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/StaticAnalyzer/Checkers/MallocChecker.cpp | 3 +++ test/Analysis/malloc.mm | 15 +++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/lib/StaticAnalyzer/Checkers/MallocChecker.cpp b/lib/StaticAnalyzer/Checkers/MallocChecker.cpp index 6d48f0258b..26fd1c26ea 100644 --- a/lib/StaticAnalyzer/Checkers/MallocChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/MallocChecker.cpp @@ -499,6 +499,9 @@ static bool isFreeWhenDoneSetToZero(const ObjCMethodCall &Call) { void MallocChecker::checkPostObjCMessage(const ObjCMethodCall &Call, CheckerContext &C) const { + if (C.wasInlined) + return; + // If the first selector is dataWithBytesNoCopy, assume that the memory will // be released with 'free' by the new object. // Ex: [NSData dataWithBytesNoCopy:bytes length:10]; diff --git a/test/Analysis/malloc.mm b/test/Analysis/malloc.mm index c92c966459..f2a195ce1d 100644 --- a/test/Analysis/malloc.mm +++ b/test/Analysis/malloc.mm @@ -5,6 +5,16 @@ typedef __typeof(sizeof(int)) size_t; void *malloc(size_t); void free(void *); +@interface Wrapper : NSData +- (id)initWithBytesNoCopy:(void *)bytes length:(NSUInteger)len; +@end + +@implementation Wrapper +- (id)initWithBytesNoCopy:(void *)bytes length:(NSUInteger)len { + return [self initWithBytesNoCopy:bytes length:len freeWhenDone:1]; // no-warning +} +@end + // Done with headers. Start testing. void testNSDatafFreeWhenDoneNoError(NSUInteger dataLength) { unsigned char *data = (unsigned char *)malloc(42); @@ -21,6 +31,11 @@ void testNSDataFreeWhenDoneYES2(NSUInteger dataLength) { NSData *nsdata = [[NSData alloc] initWithBytesNoCopy:data length:dataLength freeWhenDone:1]; // no-warning } +void testNSDataFreeWhenDoneYES2_with_wrapper(NSUInteger dataLength) { + unsigned char *data = (unsigned char *)malloc(42); + Wrapper *nsdata = [[Wrapper alloc] initWithBytesNoCopy:data length:dataLength]; // no-warning +} + void testNSStringFreeWhenDoneYES3(NSUInteger dataLength) { unsigned char *data = (unsigned char *)malloc(42); NSString *nsstr = [[NSString alloc] initWithBytesNoCopy:data length:dataLength encoding:NSUTF8StringEncoding freeWhenDone:1]; -- 2.40.0