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 | |
21 | typedef struct { int x; int y; int width; int height; } Rectangle; |
22 | |
23 | struct Struct { Rectangle r; }; |
24 | |
25 | typedef 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 | |
40 | typedef __attribute__((__ext_vector_type__(3))) float float3; |
41 | typedef 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 | |
57 | void 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 | |