1// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s
2
3/*
4  Conditions for warning:
5  1. the property is atomic
6  2. the current @implementation contains an @synthesize for the property
7  3. the current @implementation contains a hand-written setter XOR getter
8  4. the property is read-write
9
10  Cases marked WARN should warn one the following:
11  warning: Atomic property 'x' has a synthesized setter and a
12  manually-implemented getter, which may break atomicity.
13  warning: Atomic property 'x' has a synthesized getter and a
14  manually-implemented setter, which may break atomicity.
15
16  Cases not marked WARN only satisfy the indicated subset
17  of the conditions required to warn.
18
19  There should be 8 warnings.
20*/
21
22@interface Foo
23{
24    /* 12 4 */    int GetSet;
25    /* WARN */    int Get;
26    /* WARN */    int Set;
27    /* 12 4 */    int None;
28    /*  2 4 */    int GetSet_Nonatomic;
29    /*  234 */    int Get_Nonatomic;
30    /*  234 */    int Set_Nonatomic;
31    /*  2 4 */    int None_Nonatomic;
32
33    /* 12   */    int GetSet_ReadOnly;
34    /* 123  */    int Get_ReadOnly;
35    /* 123  */    int Set_ReadOnly;
36    /* 12   */    int None_ReadOnly;
37    /*  2   */    int GetSet_Nonatomic_ReadOnly;
38    /*  23  */    int Get_Nonatomic_ReadOnly;
39    /*  23  */    int Set_Nonatomic_ReadOnly;
40    /*  2   */    int None_Nonatomic_ReadOnly;
41
42    /* 12 4 */    int GetSet_ReadWriteInExt;
43    /* WARN */    int Get_ReadWriteInExt;
44    /* WARN */    int Set_ReadWriteInExt;
45    /* 12 4 */    int None_ReadWriteInExt;
46    /*  2 4 */    int GetSet_Nonatomic_ReadWriteInExt;
47    /*  234 */    int Get_Nonatomic_ReadWriteInExt;
48    /*  234 */    int Set_Nonatomic_ReadWriteInExt;
49    /*  2 4 */    int None_Nonatomic_ReadWriteInExt;
50
51
52    /* 12 4 */    int GetSet_LateSynthesize;
53    /* WARN */    int Get_LateSynthesize;
54    /* WARN */    int Set_LateSynthesize;
55    /* 12 4 */    int None_LateSynthesize;
56    /*  2 4 */    int GetSet_Nonatomic_LateSynthesize;
57    /*  234 */    int Get_Nonatomic_LateSynthesize;
58    /*  234 */    int Set_Nonatomic_LateSynthesize;
59    /*  2 4 */    int None_Nonatomic_LateSynthesize;
60
61    /* 12   */    int GetSet_ReadOnly_LateSynthesize;
62    /* 123  */    int Get_ReadOnly_LateSynthesize;
63    /* 123  */    int Set_ReadOnly_LateSynthesize;
64    /* 12   */    int None_ReadOnly_LateSynthesize;
65    /*  2   */    int GetSet_Nonatomic_ReadOnly_LateSynthesize;
66    /*  23  */    int Get_Nonatomic_ReadOnly_LateSynthesize;
67    /*  23  */    int Set_Nonatomic_ReadOnly_LateSynthesize;
68    /*  2   */    int None_Nonatomic_ReadOnly_LateSynthesize;
69
70    /* 12 4 */    int GetSet_ReadWriteInExt_LateSynthesize;
71    /* WARN */    int Get_ReadWriteInExt_LateSynthesize;
72    /* WARN */    int Set_ReadWriteInExt_LateSynthesize;
73    /* 12 4 */    int None_ReadWriteInExt_LateSynthesize;
74    /*  2 4 */    int GetSet_Nonatomic_ReadWriteInExt_LateSynthesize;
75    /*  234 */    int Get_Nonatomic_ReadWriteInExt_LateSynthesize;
76    /*  234 */    int Set_Nonatomic_ReadWriteInExt_LateSynthesize;
77    /*  2 4 */    int None_Nonatomic_ReadWriteInExt_LateSynthesize;
78
79
80    /* 1  4 */    int GetSet_NoSynthesize;
81    /* 1 34 */    int Get_NoSynthesize;
82    /* 1 34 */    int Set_NoSynthesize;
83    /* 1  4 */    int None_NoSynthesize;
84    /*    4 */    int GetSet_Nonatomic_NoSynthesize;
85    /*   34 */    int Get_Nonatomic_NoSynthesize;
86    /*   34 */    int Set_Nonatomic_NoSynthesize;
87    /*    4 */    int None_Nonatomic_NoSynthesize;
88
89    /* 1    */    int GetSet_ReadOnly_NoSynthesize;
90    /* 1 3  */    int Get_ReadOnly_NoSynthesize;
91    /* 1 3  */    int Set_ReadOnly_NoSynthesize;
92    /* 1    */    int None_ReadOnly_NoSynthesize;
93    /*      */    int GetSet_Nonatomic_ReadOnly_NoSynthesize;
94    /*   3  */    int Get_Nonatomic_ReadOnly_NoSynthesize;
95    /*   3  */    int Set_Nonatomic_ReadOnly_NoSynthesize;
96    /*      */    int None_Nonatomic_ReadOnly_NoSynthesize;
97
98    /* 1  4 */    int GetSet_ReadWriteInExt_NoSynthesize;
99    /* 1 34 */    int Get_ReadWriteInExt_NoSynthesize;
100    /* 1 34 */    int Set_ReadWriteInExt_NoSynthesize;
101    /* 1  4 */    int None_ReadWriteInExt_NoSynthesize;
102    /*    4 */    int GetSet_Nonatomic_ReadWriteInExt_NoSynthesize;
103    /*   34 */    int Get_Nonatomic_ReadWriteInExt_NoSynthesize;
104    /*   34 */    int Set_Nonatomic_ReadWriteInExt_NoSynthesize;
105    /*    4 */    int None_Nonatomic_ReadWriteInExt_NoSynthesize;
106}
107
108// read-write - might warn
109@property int GetSet;
110@property int Get;	// expected-note {{property declared here}} \
111                        // expected-note {{setter and getter must both be synthesized}}
112@property int Set;	// expected-note {{property declared here}} \
113                        // expected-note {{setter and getter must both be synthesized}}
114@property int None;
115@property(nonatomic) int GetSet_Nonatomic;
116@property(nonatomic) int Get_Nonatomic;
117@property(nonatomic) int Set_Nonatomic;
118@property(nonatomic) int None_Nonatomic;
119
120// read-only - must not warn
121@property(readonly) int GetSet_ReadOnly;
122@property(readonly) int Get_ReadOnly;
123@property(readonly) int Set_ReadOnly;
124@property(readonly) int None_ReadOnly;
125@property(nonatomic,readonly) int GetSet_Nonatomic_ReadOnly;
126@property(nonatomic,readonly) int Get_Nonatomic_ReadOnly;
127@property(nonatomic,readonly) int Set_Nonatomic_ReadOnly;
128@property(nonatomic,readonly) int None_Nonatomic_ReadOnly;
129
130// read-only in class, read-write in class extension - might warn
131@property(readonly) int GetSet_ReadWriteInExt;
132@property(readonly) int Get_ReadWriteInExt;
133@property(readonly) int Set_ReadWriteInExt;
134@property(readonly) int None_ReadWriteInExt;
135@property(nonatomic,readonly) int GetSet_Nonatomic_ReadWriteInExt;
136@property(nonatomic,readonly) int Get_Nonatomic_ReadWriteInExt;
137@property(nonatomic,readonly) int Set_Nonatomic_ReadWriteInExt;
138@property(nonatomic,readonly) int None_Nonatomic_ReadWriteInExt;
139
140
141// same as above, but @synthesize follows the hand-written methods - might warn
142@property int GetSet_LateSynthesize;
143@property int Get_LateSynthesize;	// expected-note {{property declared here}} \
144                                        // expected-note {{setter and getter must both be synthesized}}
145@property int Set_LateSynthesize;	// expected-note {{property declared here}} \
146                                        // expected-note {{setter and getter must both be synthesized}}
147@property int None_LateSynthesize;
148@property(nonatomic) int GetSet_Nonatomic_LateSynthesize;
149@property(nonatomic) int Get_Nonatomic_LateSynthesize;
150@property(nonatomic) int Set_Nonatomic_LateSynthesize;
151@property(nonatomic) int None_Nonatomic_LateSynthesize;
152
153@property(readonly) int GetSet_ReadOnly_LateSynthesize;
154@property(readonly) int Get_ReadOnly_LateSynthesize;
155@property(readonly) int Set_ReadOnly_LateSynthesize;
156@property(readonly) int None_ReadOnly_LateSynthesize;
157@property(nonatomic,readonly) int GetSet_Nonatomic_ReadOnly_LateSynthesize;
158@property(nonatomic,readonly) int Get_Nonatomic_ReadOnly_LateSynthesize;
159@property(nonatomic,readonly) int Set_Nonatomic_ReadOnly_LateSynthesize;
160@property(nonatomic,readonly) int None_Nonatomic_ReadOnly_LateSynthesize;
161
162@property(readonly) int GetSet_ReadWriteInExt_LateSynthesize;
163@property(readonly) int Get_ReadWriteInExt_LateSynthesize;
164@property(readonly) int Set_ReadWriteInExt_LateSynthesize;
165@property(readonly) int None_ReadWriteInExt_LateSynthesize;
166@property(nonatomic,readonly) int GetSet_Nonatomic_ReadWriteInExt_LateSynthesize;
167@property(nonatomic,readonly) int Get_Nonatomic_ReadWriteInExt_LateSynthesize;
168@property(nonatomic,readonly) int Set_Nonatomic_ReadWriteInExt_LateSynthesize;
169@property(nonatomic,readonly) int None_Nonatomic_ReadWriteInExt_LateSynthesize;
170
171
172// same as above, but with no @synthesize - must not warn
173@property int GetSet_NoSynthesize;
174@property int Get_NoSynthesize;
175@property int Set_NoSynthesize;
176@property int None_NoSynthesize;
177@property(nonatomic) int GetSet_Nonatomic_NoSynthesize;
178@property(nonatomic) int Get_Nonatomic_NoSynthesize;
179@property(nonatomic) int Set_Nonatomic_NoSynthesize;
180@property(nonatomic) int None_Nonatomic_NoSynthesize;
181
182@property(readonly) int GetSet_ReadOnly_NoSynthesize;
183@property(readonly) int Get_ReadOnly_NoSynthesize;
184@property(readonly) int Set_ReadOnly_NoSynthesize;
185@property(readonly) int None_ReadOnly_NoSynthesize;
186@property(nonatomic,readonly) int GetSet_Nonatomic_ReadOnly_NoSynthesize;
187@property(nonatomic,readonly) int Get_Nonatomic_ReadOnly_NoSynthesize;
188@property(nonatomic,readonly) int Set_Nonatomic_ReadOnly_NoSynthesize;
189@property(nonatomic,readonly) int None_Nonatomic_ReadOnly_NoSynthesize;
190
191@property(readonly) int GetSet_ReadWriteInExt_NoSynthesize;
192@property(readonly) int Get_ReadWriteInExt_NoSynthesize;
193@property(readonly) int Set_ReadWriteInExt_NoSynthesize;
194@property(readonly) int None_ReadWriteInExt_NoSynthesize;
195@property(nonatomic,readonly) int GetSet_Nonatomic_ReadWriteInExt_NoSynthesize;
196@property(nonatomic,readonly) int Get_Nonatomic_ReadWriteInExt_NoSynthesize;
197@property(nonatomic,readonly) int Set_Nonatomic_ReadWriteInExt_NoSynthesize;
198@property(nonatomic,readonly) int None_Nonatomic_ReadWriteInExt_NoSynthesize;
199
200@end
201
202
203@interface Foo ()
204
205@property(readwrite) int GetSet_ReadWriteInExt;
206@property(readwrite) int Get_ReadWriteInExt; // expected-note {{property declared here}} \
207                                             // expected-note {{setter and getter must both be synthesized}}
208@property(readwrite) int Set_ReadWriteInExt; // expected-note {{property declared here}} \
209                                             // expected-note {{setter and getter must both be synthesized}}
210@property(readwrite) int None_ReadWriteInExt;
211@property(nonatomic,readwrite) int GetSet_Nonatomic_ReadWriteInExt;
212@property(nonatomic,readwrite) int Get_Nonatomic_ReadWriteInExt;
213@property(nonatomic,readwrite) int Set_Nonatomic_ReadWriteInExt;
214@property(nonatomic,readwrite) int None_Nonatomic_ReadWriteInExt;
215
216@property(readwrite) int GetSet_ReadWriteInExt_LateSynthesize;
217@property(readwrite) int Get_ReadWriteInExt_LateSynthesize;  // expected-note {{property declared here}} \
218                                                             // expected-note {{setter and getter must both be synthesized}}
219@property(readwrite) int Set_ReadWriteInExt_LateSynthesize; // expected-note {{property declared here}} \
220                                                            // expected-note {{setter and getter must both be synthesized}}
221@property(readwrite) int None_ReadWriteInExt_LateSynthesize;
222@property(nonatomic,readwrite) int GetSet_Nonatomic_ReadWriteInExt_LateSynthesize;
223@property(nonatomic,readwrite) int Get_Nonatomic_ReadWriteInExt_LateSynthesize;
224@property(nonatomic,readwrite) int Set_Nonatomic_ReadWriteInExt_LateSynthesize;
225@property(nonatomic,readwrite) int None_Nonatomic_ReadWriteInExt_LateSynthesize;
226
227@property(readwrite) int GetSet_ReadWriteInExt_NoSynthesize;
228@property(readwrite) int Get_ReadWriteInExt_NoSynthesize;
229@property(readwrite) int Set_ReadWriteInExt_NoSynthesize;
230@property(readwrite) int None_ReadWriteInExt_NoSynthesize;
231@property(nonatomic,readwrite) int GetSet_Nonatomic_ReadWriteInExt_NoSynthesize;
232@property(nonatomic,readwrite) int Get_Nonatomic_ReadWriteInExt_NoSynthesize;
233@property(nonatomic,readwrite) int Set_Nonatomic_ReadWriteInExt_NoSynthesize;
234@property(nonatomic,readwrite) int None_Nonatomic_ReadWriteInExt_NoSynthesize;
235
236@end
237
238@implementation Foo
239
240@synthesize GetSet, Get, Set, None, GetSet_Nonatomic, Get_Nonatomic, Set_Nonatomic, None_Nonatomic;
241@synthesize GetSet_ReadOnly, Get_ReadOnly, Set_ReadOnly, None_ReadOnly, GetSet_Nonatomic_ReadOnly, Get_Nonatomic_ReadOnly, Set_Nonatomic_ReadOnly, None_Nonatomic_ReadOnly;
242@synthesize GetSet_ReadWriteInExt, Get_ReadWriteInExt, Set_ReadWriteInExt, None_ReadWriteInExt, GetSet_Nonatomic_ReadWriteInExt, Get_Nonatomic_ReadWriteInExt, Set_Nonatomic_ReadWriteInExt, None_Nonatomic_ReadWriteInExt;
243
244#define GET(x) \
245    -(int) x { return self->x; }
246#define SET(x) \
247    -(void) set##x:(int)value { self->x = value; }
248
249GET(GetSet)
250SET(GetSet)
251GET(Get) // expected-warning {{writable atomic property 'Get' cannot pair a synthesized setter with a user defined getter}}
252SET(Set) // expected-warning {{writable atomic property 'Set' cannot pair a synthesized getter with a user defined setter}}
253GET(GetSet_Nonatomic)
254SET(GetSet_Nonatomic)
255GET(Get_Nonatomic)
256SET(Set_Nonatomic)
257
258GET(GetSet_ReadOnly)
259SET(GetSet_ReadOnly)
260GET(Get_ReadOnly)
261SET(Set_ReadOnly)
262GET(GetSet_Nonatomic_ReadOnly)
263SET(GetSet_Nonatomic_ReadOnly)
264GET(Get_Nonatomic_ReadOnly)
265SET(Set_Nonatomic_ReadOnly)
266
267GET(GetSet_ReadWriteInExt)
268SET(GetSet_ReadWriteInExt)
269GET(Get_ReadWriteInExt) // expected-warning {{writable atomic property 'Get_ReadWriteInExt' cannot pair a synthesized setter with a user defined getter}}
270SET(Set_ReadWriteInExt) // expected-warning {{writable atomic property 'Set_ReadWriteInExt' cannot pair a synthesized getter with a user defined setter}}
271GET(GetSet_Nonatomic_ReadWriteInExt)
272SET(GetSet_Nonatomic_ReadWriteInExt)
273GET(Get_Nonatomic_ReadWriteInExt)
274SET(Set_Nonatomic_ReadWriteInExt)
275
276
277GET(GetSet_LateSynthesize)
278SET(GetSet_LateSynthesize)
279GET(Get_LateSynthesize) // expected-warning {{writable atomic property 'Get_LateSynthesize' cannot pair a synthesized setter with a user defined getter}}
280SET(Set_LateSynthesize) // expected-warning {{writable atomic property 'Set_LateSynthesize' cannot pair a synthesized getter with a user defined setter}}
281GET(GetSet_Nonatomic_LateSynthesize)
282SET(GetSet_Nonatomic_LateSynthesize)
283GET(Get_Nonatomic_LateSynthesize)
284SET(Set_Nonatomic_LateSynthesize)
285
286GET(GetSet_ReadOnly_LateSynthesize)
287SET(GetSet_ReadOnly_LateSynthesize)
288GET(Get_ReadOnly_LateSynthesize)
289SET(Set_ReadOnly_LateSynthesize)
290GET(GetSet_Nonatomic_ReadOnly_LateSynthesize)
291SET(GetSet_Nonatomic_ReadOnly_LateSynthesize)
292GET(Get_Nonatomic_ReadOnly_LateSynthesize)
293SET(Set_Nonatomic_ReadOnly_LateSynthesize)
294
295GET(GetSet_ReadWriteInExt_LateSynthesize)
296SET(GetSet_ReadWriteInExt_LateSynthesize)
297GET(Get_ReadWriteInExt_LateSynthesize) // expected-warning {{writable atomic property 'Get_ReadWriteInExt_LateSynthesize' cannot pair a synthesized setter with a user defined getter}}
298SET(Set_ReadWriteInExt_LateSynthesize) // expected-warning {{writable atomic property 'Set_ReadWriteInExt_LateSynthesize' cannot pair a synthesized getter with a user defined setter}}
299GET(GetSet_Nonatomic_ReadWriteInExt_LateSynthesize)
300SET(GetSet_Nonatomic_ReadWriteInExt_LateSynthesize)
301GET(Get_Nonatomic_ReadWriteInExt_LateSynthesize)
302SET(Set_Nonatomic_ReadWriteInExt_LateSynthesize)
303
304
305GET(GetSet_NoSynthesize)
306SET(GetSet_NoSynthesize)
307GET(Get_NoSynthesize)
308SET(Set_NoSynthesize)
309GET(GetSet_Nonatomic_NoSynthesize)
310SET(GetSet_Nonatomic_NoSynthesize)
311GET(Get_Nonatomic_NoSynthesize)
312SET(Set_Nonatomic_NoSynthesize)
313
314GET(GetSet_ReadOnly_NoSynthesize)
315SET(GetSet_ReadOnly_NoSynthesize)
316GET(Get_ReadOnly_NoSynthesize)
317SET(Set_ReadOnly_NoSynthesize)
318GET(GetSet_Nonatomic_ReadOnly_NoSynthesize)
319SET(GetSet_Nonatomic_ReadOnly_NoSynthesize)
320GET(Get_Nonatomic_ReadOnly_NoSynthesize)
321SET(Set_Nonatomic_ReadOnly_NoSynthesize)
322
323GET(GetSet_ReadWriteInExt_NoSynthesize)
324SET(GetSet_ReadWriteInExt_NoSynthesize)
325GET(Get_ReadWriteInExt_NoSynthesize)
326SET(Set_ReadWriteInExt_NoSynthesize)
327GET(GetSet_Nonatomic_ReadWriteInExt_NoSynthesize)
328SET(GetSet_Nonatomic_ReadWriteInExt_NoSynthesize)
329GET(Get_Nonatomic_ReadWriteInExt_NoSynthesize)
330SET(Set_Nonatomic_ReadWriteInExt_NoSynthesize)
331
332
333// late synthesize - follows getter/setter implementations
334
335@synthesize GetSet_LateSynthesize, Get_LateSynthesize, Set_LateSynthesize, None_LateSynthesize, GetSet_Nonatomic_LateSynthesize, Get_Nonatomic_LateSynthesize, Set_Nonatomic_LateSynthesize, None_Nonatomic_LateSynthesize;
336@synthesize GetSet_ReadOnly_LateSynthesize, Get_ReadOnly_LateSynthesize, Set_ReadOnly_LateSynthesize, None_ReadOnly_LateSynthesize, GetSet_Nonatomic_ReadOnly_LateSynthesize, Get_Nonatomic_ReadOnly_LateSynthesize, Set_Nonatomic_ReadOnly_LateSynthesize, None_Nonatomic_ReadOnly_LateSynthesize;
337@synthesize GetSet_ReadWriteInExt_LateSynthesize, Get_ReadWriteInExt_LateSynthesize, Set_ReadWriteInExt_LateSynthesize, None_ReadWriteInExt_LateSynthesize, GetSet_Nonatomic_ReadWriteInExt_LateSynthesize, Get_Nonatomic_ReadWriteInExt_LateSynthesize, Set_Nonatomic_ReadWriteInExt_LateSynthesize, None_Nonatomic_ReadWriteInExt_LateSynthesize;
338
339// no synthesize - use dynamic instead
340
341@dynamic GetSet_NoSynthesize, Get_NoSynthesize, Set_NoSynthesize, None_NoSynthesize, GetSet_Nonatomic_NoSynthesize, Get_Nonatomic_NoSynthesize, Set_Nonatomic_NoSynthesize, None_Nonatomic_NoSynthesize;
342@dynamic GetSet_ReadOnly_NoSynthesize, Get_ReadOnly_NoSynthesize, Set_ReadOnly_NoSynthesize, None_ReadOnly_NoSynthesize, GetSet_Nonatomic_ReadOnly_NoSynthesize, Get_Nonatomic_ReadOnly_NoSynthesize, Set_Nonatomic_ReadOnly_NoSynthesize, None_Nonatomic_ReadOnly_NoSynthesize;
343@dynamic GetSet_ReadWriteInExt_NoSynthesize, Get_ReadWriteInExt_NoSynthesize, Set_ReadWriteInExt_NoSynthesize, None_ReadWriteInExt_NoSynthesize, GetSet_Nonatomic_ReadWriteInExt_NoSynthesize, Get_Nonatomic_ReadWriteInExt_NoSynthesize, Set_Nonatomic_ReadWriteInExt_NoSynthesize, None_Nonatomic_ReadWriteInExt_NoSynthesize;
344
345@end
346
347/*
348// the following method should cause a warning along the lines of
349// :warning: Atomic property 'x' cannot pair a synthesized setter/getter with a manually implemented setter/getter
350- (void) setX: (int) aValue
351{
352    x = aValue;
353}
354
355// no warning 'cause this is nonatomic
356- (void) setY: (int) aValue
357{
358    y = aValue;
359}
360
361// the following method should cause a warning along the lines of
362// :warning: Atomic property 'x' cannot pair a synthesized setter/getter with a manually implemented setter/getter
363- (int) j
364{
365    return j;
366}
367
368// no warning 'cause this is nonatomic
369- (int) k
370{
371    return k;
372}
373@end
374*/
375int main (int argc, const char * argv[]) {
376    return 0;
377}
378