1// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fsyntax-only -fobjc-arc -verify %s 2// rdar://12056271 3 4@class Thread; 5 6__attribute__((objc_root_class)) 7@interface NSObject 8 9- (id)performSelector:(SEL)sel; 10- (void)performSelectorInBackground:(SEL)sel withObject:(id)arg; 11- (void)performSelectorOnMainThread:(SEL)sel; 12 13- (void)performSelectorOnMainThread:(SEL)aSelector 14 onThread:(Thread *)thread 15 withObject:(id)arg 16 waitUntilDone:(int)wait 17 modes:(id *)array; 18 19@end 20 21typedef struct { int x; int y; int width; int height; } Rectangle; 22 23struct Struct { Rectangle r; }; 24 25typedef union { int x; float f; } Union; 26 27@interface Base : NSObject 28 29- (struct Struct)returnsStruct2; // expected-note {{method 'returnsStruct2' that returns 'struct Struct' declared here}} 30- (Union)returnsId; 31 32@end 33 34@protocol IP 35 36- (Union)returnsUnion; // expected-note 2 {{method 'returnsUnion' that returns 'Union' declared here}} 37 38@end 39 40typedef __attribute__((__ext_vector_type__(3))) float float3; 41typedef int int4 __attribute__ ((vector_size (16))); 42 43@interface I : Base<IP> 44 45- (Rectangle)returnsStruct; // expected-note 4 {{method 'returnsStruct' that returns 'Rectangle' declared here}} 46- (id)returnsId; // shadows base 'returnsId' 47- (int)returnsInt; 48- (I *)returnPtr; 49- (float3)returnsExtVector; // expected-note {{method 'returnsExtVector' that returns 'float3' (vector of 3 'float' values) declared here}} 50- (int4)returnsVector; // expected-note {{method 'returnsVector' that returns 'int4' (vector of 4 'int' values) declared here}} 51 52+ (Rectangle)returnsStructClass; // expected-note 2 {{method 'returnsStructClass' that returns 'Rectangle' declared here}} 53+ (void)returnsUnion; // Not really 54 55@end 56 57void foo(I *i) { 58 [i performSelector: @selector(returnsStruct)]; // expected-warning {{'performSelector:' is incompatible with selectors that return a struct type}} 59 [i performSelectorInBackground: @selector(returnsStruct) withObject:0]; // expected-warning {{'performSelectorInBackground:withObject:' is incompatible with selectors that return a struct type}} 60 [i performSelector: ((@selector(returnsUnion)))]; // expected-warning {{'performSelector:' is incompatible with selectors that return a union type}} 61 [i performSelectorOnMainThread: @selector(returnsStruct2)]; // expected-warning {{'performSelectorOnMainThread:' is incompatible with selectors that return a struct type}} 62 [I performSelector: (@selector(returnsStructClass))]; // expected-warning {{'performSelector:' is incompatible with selectors that return a struct type}} 63 64 [i performSelector: @selector(returnsId)]; 65 [i performSelector: @selector(returnsInt)]; 66 [i performSelector: @selector(returnsPtr)]; 67 [I performSelector: @selector(returnsUnion)]; // No warning expected 68 69 id obj = i; 70 [obj performSelector: @selector(returnsId)]; 71 [obj performSelector: @selector(returnsStruct)]; 72} 73 74@interface SubClass: I 75 76@end 77 78@interface SubClass () 79- (struct Struct)returnsSubStructExt; // expected-note {{method 'returnsSubStructExt' that returns 'struct Struct' declared here}} expected-note {{method 'returnsSubStructExt' declared here}} 80@end 81 82@implementation SubClass // expected-warning {{method definition for 'returnsSubStructExt' not found}} 83 84- (struct Struct)returnsSubStructImpl { // expected-note {{method 'returnsSubStructImpl' that returns 'struct Struct' declared here}} 85 struct Struct Result; 86 return Result; 87} 88 89- (void)checkPrivateCalls { 90 [self performSelector: @selector(returnsSubStructExt)]; // expected-warning {{'performSelector:' is incompatible with selectors that return a struct type}} 91 [self performSelector: @selector(returnsSubStructImpl)]; // expected-warning {{'performSelector:' is incompatible with selectors that return a struct type}} 92} 93 94- (void)checkSuperCalls { 95 [super performSelector: @selector(returnsStruct)]; // expected-warning {{'performSelector:' is incompatible with selectors that return a struct type}} 96 [super performSelectorInBackground: @selector(returnsUnion) withObject: self]; // expected-warning {{'performSelectorInBackground:withObject:' is incompatible with selectors that return a union type}} 97 [super performSelector: @selector(returnsId)]; 98} 99 100+ (struct Struct)returnsSubStructClassImpl { // expected-note {{method 'returnsSubStructClassImpl' that returns 'struct Struct' declared here}} 101 struct Struct Result; 102 return Result; 103} 104 105+ (void)checkClassPrivateCalls { 106 [self performSelector: @selector(returnsSubStructClassImpl)]; // expected-warning {{'performSelector:' is incompatible with selectors that return a struct type}} 107} 108 109+ (void)checkClassSuperCalls { 110 [super performSelector: @selector(returnsStructClass)]; // expected-warning {{'performSelector:' is incompatible with selectors that return a struct type}} 111 [super performSelector: @selector(returnsUnion)]; // No warning expected 112} 113 114@end 115 116@implementation I (LongPerformSelectors) 117 118- (void)checkLongCallsFromCategory { 119 [self performSelectorOnMainThread: @selector(returnsStruct) onThread:0 withObject:self waitUntilDone:1 modes:0]; // expected-warning {{'performSelectorOnMainThread:onThread:withObject:waitUntilDone:modes:' is incompatible with selectors that return a struct type}} 120} 121 122- (void)checkVectorReturn { 123 [self performSelector: @selector(returnsExtVector)]; // expected-warning {{'performSelector:' is incompatible with selectors that return a vector type}} 124 [self performSelector: @selector(returnsVector)]; // expected-warning {{'performSelector:' is incompatible with selectors that return a vector type}} 125} 126 127@end 128