summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnna Zaks <ganna@apple.com>2012-12-11 00:17:53 +0000
committerAnna Zaks <ganna@apple.com>2012-12-11 00:17:53 +0000
commita7b1c47c1abb7e97173cbc4027687229121c2724 (patch)
tree4604309054e43fc6a5ddd93230c454f0b6034579
parentdb1450800aa00302ccf9283379f734e0b219a404 (diff)
downloadbcm5719-llvm-a7b1c47c1abb7e97173cbc4027687229121c2724.tar.gz
bcm5719-llvm-a7b1c47c1abb7e97173cbc4027687229121c2724.zip
[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. llvm-svn: 169795
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp3
-rw-r--r--clang/test/Analysis/malloc.mm15
2 files changed, 18 insertions, 0 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
index 6d48f0258b4..26fd1c26ea7 100644
--- a/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
+++ b/clang/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/clang/test/Analysis/malloc.mm b/clang/test/Analysis/malloc.mm
index c92c966459c..f2a195ce1d4 100644
--- a/clang/test/Analysis/malloc.mm
+++ b/clang/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];
OpenPOWER on IntegriCloud