xref: /llvm-project/clang/test/SemaObjC/arc-property-decl-attrs.m (revision 0f1c1be1968076d6f96f8a7bcc4a15cf195ecd97)
1// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fobjc-runtime-has-weak -fsyntax-only -fobjc-arc -verify %s
2
3@interface Foo {
4@public
5    id __unsafe_unretained x;
6    id __weak y;
7    id __autoreleasing z; // expected-error {{instance variables cannot have __autoreleasing ownership}}
8}
9@property(strong) id x;
10@property(strong) id y;
11@property(strong) id z;
12@end
13
14@interface Bar {
15@public
16    id __unsafe_unretained x;
17    id __weak y;
18    id __autoreleasing z; // expected-error {{instance variables cannot have __autoreleasing ownership}}
19}
20@property(retain) id x;
21@property(retain) id y;
22@property(retain) id z;
23@end
24
25@interface Bas {
26@public
27    id __unsafe_unretained x;
28    id __weak y;
29    id __autoreleasing z; // expected-error {{instance variables cannot have __autoreleasing ownership}}
30}
31@property(copy) id x;
32@property(copy) id y;
33@property(copy) id z;
34@end
35
36// Errors should start about here :-)
37
38@interface Bat
39@property(strong) __unsafe_unretained id x; // expected-error {{strong property 'x' may not also be declared __unsafe_unretained}}
40@property(strong) __weak id y; // expected-error {{strong property 'y' may not also be declared __weak}}
41@property(strong) __autoreleasing id z; // expected-error {{strong property 'z' may not also be declared __autoreleasing}}
42@end
43
44@interface Bau
45@property(retain) __unsafe_unretained id x; // expected-error {{strong property 'x' may not also be declared __unsafe_unretained}}
46@property(retain) __weak id y; // expected-error {{strong property 'y' may not also be declared __weak}}
47@property(retain) __autoreleasing id z; // expected-error {{strong property 'z' may not also be declared __autoreleasing}}
48@end
49
50@interface Bav
51@property(copy) __unsafe_unretained id x; // expected-error {{strong property 'x' may not also be declared __unsafe_unretained}}
52@property(copy) __weak id y; // expected-error {{strong property 'y' may not also be declared __weak}}
53@property(copy) __autoreleasing id z; // expected-error {{strong property 'z' may not also be declared __autoreleasing}}
54@end
55
56@interface Bingo
57@property(assign) __unsafe_unretained id x;
58@property(assign) __weak id y; // expected-error {{unsafe_unretained property 'y' may not also be declared __weak}}
59@property(assign) __autoreleasing id z; // expected-error {{unsafe_unretained property 'z' may not also be declared __autoreleasing}}
60@end
61
62@interface Batman
63@property(unsafe_unretained) __unsafe_unretained id x;
64@property(unsafe_unretained) __weak id y; // expected-error {{unsafe_unretained property 'y' may not also be declared __weak}}
65@property(unsafe_unretained) __autoreleasing id z; // expected-error {{unsafe_unretained property 'z' may not also be declared __autoreleasing}}
66@end
67
68@interface Super
69@property (readonly, retain) id foo;
70@property (readonly, weak) id fee;
71@property (readonly, strong) id frr;
72@end
73
74@interface Bugg : Super
75@property (readwrite) id foo;
76@property (readwrite) id fee;
77@property (readwrite) id frr;
78@end
79
80@interface NSObject @end
81
82#pragma clang assume_nonnull begin
83@interface I: NSObject
84@property(nonatomic, weak) id delegate; // Do not warn, nullable is inferred.
85@property(nonatomic, weak, readonly) id ROdelegate; // Do not warn, nullable is inferred.
86@property(nonatomic, weak, nonnull) id NonNulldelete; // expected-error {{property attributes 'nonnull' and 'weak' are mutually exclusive}}
87@property(nonatomic, weak, nullable) id Nullabledelete; // do not warn
88
89// strong cases.
90@property(nonatomic, strong) id stdelegate; // Do not warn
91@property(nonatomic, readonly) id stROdelegate; // Do not warn
92@property(nonatomic, strong, nonnull) id stNonNulldelete; // Do not warn
93@property(nonatomic, nullable) id stNullabledelete; // do not warn
94@end
95#pragma clang assume_nonnull end
96
97@interface J: NSObject
98@property(nonatomic, weak) id ddd;   // Do not warn, nullable is inferred.
99@property(nonatomic, weak, nonnull) id delegate; // expected-error {{property attributes 'nonnull' and 'weak' are mutually exclusive}}
100@property(nonatomic, weak, nonnull, readonly) id ROdelegate; // expected-error {{property attributes 'nonnull' and 'weak' are mutually exclusive}}
101@end
102
103@protocol P
104@property(readonly, retain) id prop;
105@end
106
107__attribute__((objc_root_class))
108@interface I2<P>
109@end
110
111@interface I2()
112@property (readwrite) id prop;
113@end
114
115@implementation I2
116@synthesize prop;
117@end
118
119// Verify that the all of the property declarations in inherited protocols are
120// compatible when synthesing a property from a protocol.
121
122@protocol CopyVsAssign1
123@property (copy, nonatomic,  readonly) id prop; // expected-error {{property with attribute 'copy' was selected for synthesis}}
124@end
125@protocol CopyVsAssign2
126@property (assign, nonatomic, readonly) id prop; // expected-note {{it could also be property without attribute 'copy' declared here}}
127@end
128
129@interface CopyVsAssign: Foo <CopyVsAssign1, CopyVsAssign2>
130@end
131@implementation CopyVsAssign
132@synthesize prop; // expected-note {{property synthesized here}}
133@end
134
135@protocol RetainVsNonRetain1
136@property (readonly) id prop; // expected-error {{property without attribute 'retain (or strong)' was selected for synthesis}}
137@end
138@protocol RetainVsNonRetain2
139@property (retain, readonly) id prop; // expected-note {{it could also be property with attribute 'retain (or strong)' declared here}}
140@end
141
142@interface RetainVsNonRetain: Foo <RetainVsNonRetain1, RetainVsNonRetain2>
143@end
144@implementation RetainVsNonRetain
145@synthesize prop; // expected-note {{property synthesized here}}
146@end
147
148@protocol AtomicVsNonatomic1
149@property (copy, nonatomic, readonly) id prop; // expected-error {{property without attribute 'atomic' was selected for synthesis}}
150@end
151@protocol AtomicVsNonatomic2
152@property (copy, atomic, readonly) id prop; // expected-note {{it could also be property with attribute 'atomic' declared here}}
153@end
154
155@interface AtomicVsNonAtomic: Foo <AtomicVsNonatomic1, AtomicVsNonatomic2>
156@end
157@implementation AtomicVsNonAtomic
158@synthesize prop; // expected-note {{property synthesized here}}
159@end
160
161@protocol Getter1
162@property (copy, readonly) id prop; // expected-error {{property with getter 'prop' was selected for synthesis}}
163@end
164@protocol Getter2
165@property (copy, getter=x, readonly) id prop; // expected-note {{it could also be property with getter 'x' declared here}}
166@end
167
168@interface GetterVsGetter: Foo <Getter1, Getter2>
169@end
170@implementation GetterVsGetter
171@synthesize prop; // expected-note {{property synthesized here}}
172@end
173
174@protocol Setter1
175@property (copy, readonly) id prop;
176@end
177@protocol Setter2
178@property (copy, setter=setp:, readwrite) id prop; // expected-error {{property with setter 'setp:' was selected for synthesis}}
179@end
180@protocol Setter3
181@property (copy, readwrite) id prop; // expected-note {{it could also be property with setter 'setProp:' declared here}}
182@end
183
184@interface SetterVsSetter: Foo <Setter1, Setter2, Setter3>
185@end
186@implementation SetterVsSetter
187@synthesize prop; // expected-note {{property synthesized here}}
188@end
189
190@protocol TypeVsAttribute1
191@property (assign, atomic, readonly) int prop; // expected-error {{property of type 'int' was selected for synthesis}}
192@end
193@protocol TypeVsAttribute2
194@property (assign, atomic, readonly) id prop; // expected-note {{it could also be property of type 'id' declared here}}
195@end
196@protocol TypeVsAttribute3
197@property (copy, readonly) id prop; // expected-note {{it could also be property with attribute 'copy' declared here}}
198@end
199
200@interface TypeVsAttribute: Foo <TypeVsAttribute1, TypeVsAttribute2, TypeVsAttribute3>
201@end
202@implementation TypeVsAttribute
203@synthesize prop; // expected-note {{property synthesized here}}
204@end
205
206@protocol TypeVsSetter1
207@property (assign, nonatomic, readonly) int prop; // expected-note {{it could also be property of type 'int' declared here}}
208@end
209@protocol TypeVsSetter2
210@property (assign, nonatomic, readonly) id prop; // ok
211@end
212@protocol TypeVsSetter3
213@property (assign, nonatomic, readwrite) id prop; // expected-error {{property of type 'id' was selected for synthesis}}
214@end
215
216@interface TypeVsSetter: Foo <TypeVsSetter1, TypeVsSetter2, TypeVsSetter3>
217@end
218@implementation TypeVsSetter
219@synthesize prop; // expected-note {{property synthesized here}}
220@end
221
222@protocol AutoStrongProp
223
224@property (nonatomic, readonly) NSObject *prop;
225
226@end
227
228@protocol AutoStrongProp_Internal <AutoStrongProp>
229
230// This property gets the 'strong' attribute automatically.
231@property (nonatomic, readwrite) NSObject *prop;
232
233@end
234
235@interface SynthesizeWithImplicitStrongNoError : NSObject <AutoStrongProp>
236@end
237
238@interface SynthesizeWithImplicitStrongNoError () <AutoStrongProp_Internal>
239
240@end
241
242@implementation SynthesizeWithImplicitStrongNoError
243
244// no error, 'strong' is implicit in the 'readwrite' property.
245@synthesize prop = _prop;
246
247@end
248
249// Allow strong readwrite property and a readonly one.
250@protocol StrongCollision
251
252@property(strong) NSObject *p;
253@property(copy) NSObject *p2;
254
255// expected-error@+1 {{property with attribute 'retain (or strong)' was selected for synthesis}}
256@property(strong, readwrite) NSObject *collision;
257
258@end
259
260@protocol ReadonlyCollision
261
262@property(readonly) NSObject *p;
263@property(readonly) NSObject *p2;
264
265// expected-note@+1 {{it could also be property without attribute 'retain (or strong)' declared here}}
266@property(readonly, weak) NSObject *collision;
267
268@end
269
270@interface StrongReadonlyCollision : NSObject <StrongCollision, ReadonlyCollision>
271@end
272
273@implementation StrongReadonlyCollision
274
275// no error
276@synthesize p = _p;
277@synthesize p2 = _p2;
278
279@synthesize collision = _collision; // expected-note {{property synthesized here}}
280
281@end
282
283// This used to crash because we'd temporarly store the weak attribute on the
284// declaration specifier, then deallocate it when clearing the declarator.
285id i1, __weak i2, i3;
286