diff --git a/clang/lib/StaticAnalyzer/Core/ObjCMessage.cpp b/clang/lib/StaticAnalyzer/Core/ObjCMessage.cpp index 994e6fbe622c..4dc000f7bdf3 100644 --- a/clang/lib/StaticAnalyzer/Core/ObjCMessage.cpp +++ b/clang/lib/StaticAnalyzer/Core/ObjCMessage.cpp @@ -94,7 +94,9 @@ bool CallOrObjCMessage::isCallbackArg(unsigned Idx, const Type *T) const { return false; // If a parameter is a block or a callback, assume it can modify pointer. - if (T->isBlockPointerType() || T->isFunctionPointerType()) + if (T->isBlockPointerType() || + T->isFunctionPointerType() || + T->isObjCSelType()) return true; // Check if a callback is passed inside a struct (for both, struct passed by diff --git a/clang/test/Analysis/retain-release.m b/clang/test/Analysis/retain-release.m index 5422b8bb0fac..a27fdac27fb1 100644 --- a/clang/test/Analysis/retain-release.m +++ b/clang/test/Analysis/retain-release.m @@ -222,8 +222,10 @@ typedef struct CGLayer *CGLayerRef; @end @protocol NSValidatedUserInterfaceItem - (SEL)action; @end @protocol NSUserInterfaceValidations - (BOOL)validateUserInterfaceItem:(id )anItem; @end @class NSDate, NSDictionary, NSError, NSException, NSNotification; +@class NSTextField, NSPanel, NSArray, NSWindow, NSImage, NSButton, NSError; @interface NSApplication : NSResponder { } +- (void)beginSheet:(NSWindow *)sheet modalForWindow:(NSWindow *)docWindow modalDelegate:(id)modalDelegate didEndSelector:(SEL)didEndSelector contextInfo:(void *)contextInfo; @end enum { NSTerminateCancel = 0, NSTerminateNow = 1, NSTerminateLater = 2 }; typedef NSUInteger NSApplicationTerminateReply; @@ -231,7 +233,7 @@ typedef NSUInteger NSApplicationTerminateReply; @end @class NSAttributedString, NSEvent, NSFont, NSFormatter, NSImage, NSMenu, NSText, NSView, NSTextView; @interface NSCell : NSObject { } -@end @class NSTextField, NSPanel, NSArray, NSWindow, NSImage, NSButton, NSError; +@end typedef struct { } CVTimeStamp; @@ -1712,6 +1714,32 @@ int IOClose(void *context); } @end +// Object escapes through a selector callback: radar://11398514 +extern id NSApp; +@interface MySheetController +- (id)inputS; +- (void)showDoSomethingSheetAction:(id)action; +- (void)sheetDidEnd:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo; +@end + +@implementation MySheetController +- (id)inputS { + return 0; +} +- (void)showDoSomethingSheetAction:(id)action { + id inputS = [[self inputS] retain]; + [NSApp beginSheet:0 + modalForWindow:0 + modalDelegate:0 + didEndSelector:@selector(sheetDidEnd:returnCode:contextInfo:) + contextInfo:(void *)inputS]; // no - warning +} +- (void)sheetDidEnd:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo { + + id contextObject = (id)contextInfo; + [contextObject release]; +} +@end //===----------------------------------------------------------------------===// // Test returning allocated memory in a struct. //