From e5a3d59aded860bf572543561b3fb45d938ba962 Mon Sep 17 00:00:00 2001 From: Jordan Rose Date: Tue, 7 Jan 2014 21:39:48 +0000 Subject: [PATCH] [analyzer] Pointers escape into +[NSValue valueWithPointer:]... ...even though the argument is declared "const void *", because this is just a way to pass pointers around as objects. (Though NSData is often a better one.) PR18262 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@198710 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../StaticAnalyzer/Core/PathSensitive/CallEvent.h | 2 ++ lib/StaticAnalyzer/Checkers/MallocChecker.cpp | 3 ++- lib/StaticAnalyzer/Core/CallEvent.cpp | 11 +++++++++++ test/Analysis/Inputs/system-header-simulator-objc.h | 7 +++++-- test/Analysis/malloc.m | 5 +++++ 5 files changed, 25 insertions(+), 3 deletions(-) diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h index d69f50a9a2..e2baf38e0b 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h @@ -885,6 +885,8 @@ public: virtual RuntimeDefinition getRuntimeDefinition() const; + virtual bool argumentsMayEscape() const; + virtual void getInitialStackFrameContents(const StackFrameContext *CalleeCtx, BindingsTy &Bindings) const; diff --git a/lib/StaticAnalyzer/Checkers/MallocChecker.cpp b/lib/StaticAnalyzer/Checkers/MallocChecker.cpp index 82a1aa2257..87d7e89e52 100644 --- a/lib/StaticAnalyzer/Checkers/MallocChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/MallocChecker.cpp @@ -1907,7 +1907,8 @@ bool MallocChecker::mayFreeAnyEscapedMemoryOrIsModeledExplicitly( // that the pointers get freed by following the container itself. if (FirstSlot.startswith("addPointer") || FirstSlot.startswith("insertPointer") || - FirstSlot.startswith("replacePointer")) { + FirstSlot.startswith("replacePointer") || + FirstSlot.equals("valueWithPointer")) { return true; } diff --git a/lib/StaticAnalyzer/Core/CallEvent.cpp b/lib/StaticAnalyzer/Core/CallEvent.cpp index e0392bd147..838d273cc0 100644 --- a/lib/StaticAnalyzer/Core/CallEvent.cpp +++ b/lib/StaticAnalyzer/Core/CallEvent.cpp @@ -886,6 +886,17 @@ RuntimeDefinition ObjCMethodCall::getRuntimeDefinition() const { return RuntimeDefinition(); } +bool ObjCMethodCall::argumentsMayEscape() const { + if (isInSystemHeader() && !isInstanceMessage()) { + Selector Sel = getSelector(); + if (Sel.getNumArgs() == 1 && + Sel.getIdentifierInfoForSlot(0)->isStr("valueWithPointer")) + return true; + } + + return CallEvent::argumentsMayEscape(); +} + void ObjCMethodCall::getInitialStackFrameContents( const StackFrameContext *CalleeCtx, BindingsTy &Bindings) const { diff --git a/test/Analysis/Inputs/system-header-simulator-objc.h b/test/Analysis/Inputs/system-header-simulator-objc.h index 3e1d9555bb..8a5d3b6403 100644 --- a/test/Analysis/Inputs/system-header-simulator-objc.h +++ b/test/Analysis/Inputs/system-header-simulator-objc.h @@ -66,8 +66,11 @@ typedef struct { NSFastEnumerationState; @protocol NSFastEnumeration - (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)stackbuf count:(NSUInteger)len; @end @class NSString, NSDictionary; -@interface NSValue : NSObject - (void)getValue:(void *)value; -@end @interface NSNumber : NSValue - (char)charValue; +@interface NSValue : NSObject ++ (NSValue *)valueWithPointer:(const void *)p; +- (void)getValue:(void *)value; +@end +@interface NSNumber : NSValue - (char)charValue; - (id)initWithInt:(int)value; @end @class NSString; @interface NSArray : NSObject - (NSUInteger)count; diff --git a/test/Analysis/malloc.m b/test/Analysis/malloc.m index ad16db52df..9201c2b75f 100644 --- a/test/Analysis/malloc.m +++ b/test/Analysis/malloc.m @@ -49,4 +49,9 @@ void _ArrayCreate() { void testNSDataTruePositiveLeak() { char *b = (char *)malloc(12); NSData *d = [[NSData alloc] initWithBytes: b length: 12]; // expected-warning {{Potential leak of memory pointed to by 'b'}} +} + +id wrapInNSValue() { + void *buffer = malloc(4); + return [NSValue valueWithPointer:buffer]; // no-warning } \ No newline at end of file -- 2.40.0