[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

llvm-svn: 198710
This commit is contained in:
Jordan Rose 2014-01-07 21:39:48 +00:00
parent 6ad4cb4eca
commit 514f935411
5 changed files with 25 additions and 3 deletions

View File

@ -885,6 +885,8 @@ public:
virtual RuntimeDefinition getRuntimeDefinition() const;
virtual bool argumentsMayEscape() const;
virtual void getInitialStackFrameContents(const StackFrameContext *CalleeCtx,
BindingsTy &Bindings) const;

View File

@ -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;
}

View File

@ -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 {

View File

@ -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 <NSCopying, NSCoding> - (void)getValue:(void *)value;
@end @interface NSNumber : NSValue - (char)charValue;
@interface NSValue : NSObject <NSCopying, NSCoding>
+ (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 <NSCopying, NSMutableCopying, NSCoding, NSFastEnumeration> - (NSUInteger)count;

View File

@ -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
}