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