1 | // RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s |
2 | |
3 | // # Flexible array member. |
4 | // ## Instance variables only in interface. |
5 | @interface LastIvar { |
6 | char flexible[]; |
7 | } |
8 | @end |
9 | |
10 | @interface NotLastIvar { |
11 | char flexible[]; // expected-error {{flexible array member 'flexible' with type 'char []' is not at the end of class}} |
12 | int last; // expected-note {{next instance variable declaration is here}} |
13 | } |
14 | @end |
15 | |
16 | // ## Instance variables in implementation. |
17 | @interface LastIvarInImpl |
18 | @end |
19 | @implementation LastIvarInImpl { |
20 | char flexible[]; // expected-warning {{field 'flexible' with variable sized type 'char []' is not visible to subclasses and can conflict with their instance variables}} |
21 | } |
22 | @end |
23 | |
24 | @interface NotLastIvarInImpl |
25 | @end |
26 | @implementation NotLastIvarInImpl { |
27 | char flexible[]; // expected-error {{flexible array member 'flexible' with type 'char []' is not at the end of class}} |
28 | // expected-warning@-1 {{field 'flexible' with variable sized type 'char []' is not visible to subclasses and can conflict with their instance variables}} |
29 | int last; // expected-note {{next instance variable declaration is here}} |
30 | } |
31 | @end |
32 | |
33 | @implementation NotLastIvarInImplWithoutInterface { // expected-warning {{cannot find interface declaration for 'NotLastIvarInImplWithoutInterface'}} |
34 | char flexible[]; // expected-error {{flexible array member 'flexible' with type 'char []' is not at the end of class}} |
35 | // expected-warning@-1 {{field 'flexible' with variable sized type 'char []' is not visible to subclasses and can conflict with their instance variables}} |
36 | int last; // expected-note {{next instance variable declaration is here}} |
37 | } |
38 | @end |
39 | |
40 | @interface LastIvarInClass_OtherIvarInImpl { |
41 | char flexible[]; // expected-error {{flexible array member 'flexible' with type 'char []' is not at the end of class}} |
42 | } |
43 | @end |
44 | @implementation LastIvarInClass_OtherIvarInImpl { |
45 | int last; // expected-note {{next instance variable declaration is here}} |
46 | } |
47 | @end |
48 | |
49 | // ## Non-instance variables in implementation. |
50 | @interface LastIvarInClass_UnrelatedVarInImpl { |
51 | char flexible[]; |
52 | } |
53 | @end |
54 | @implementation LastIvarInClass_UnrelatedVarInImpl |
55 | int nonIvar; |
56 | @end |
57 | |
58 | // ## Instance variables in class extension. |
59 | @interface LastIvarInExtension |
60 | @end |
61 | @interface LastIvarInExtension() { |
62 | char flexible[]; // expected-warning {{field 'flexible' with variable sized type 'char []' is not visible to subclasses and can conflict with their instance variables}} |
63 | } |
64 | @end |
65 | |
66 | @interface NotLastIvarInExtension |
67 | @end |
68 | @interface NotLastIvarInExtension() { |
69 | char flexible[]; // expected-error {{flexible array member 'flexible' with type 'char []' is not at the end of class}} |
70 | // expected-warning@-1 {{field 'flexible' with variable sized type 'char []' is not visible to subclasses and can conflict with their instance variables}} |
71 | int last; // expected-note {{next instance variable declaration is here}} |
72 | } |
73 | @end |
74 | |
75 | @interface LastIvarInClass_OtherIvarInExtension { |
76 | char flexible[]; // expected-error {{flexible array member 'flexible' with type 'char []' is not at the end of class}} |
77 | } |
78 | @end |
79 | @interface LastIvarInClass_OtherIvarInExtension() { |
80 | int last; // expected-note {{next instance variable declaration is here}} |
81 | } |
82 | @end |
83 | |
84 | @interface LastIvarInExtension_OtherIvarInExtension |
85 | @end |
86 | @interface LastIvarInExtension_OtherIvarInExtension() { |
87 | int last; // expected-note {{next instance variable declaration is here}} |
88 | } |
89 | @end |
90 | @interface LastIvarInExtension_OtherIvarInExtension() |
91 | // Extension without ivars to test we see through such extensions. |
92 | @end |
93 | @interface LastIvarInExtension_OtherIvarInExtension() { |
94 | char flexible[]; // expected-error {{flexible array member 'flexible' with type 'char []' is not at the end of class}} |
95 | // expected-warning@-1 {{field 'flexible' with variable sized type 'char []' is not visible to subclasses and can conflict with their instance variables}} |
96 | } |
97 | @end |
98 | |
99 | @interface LastIvarInExtension_OtherIvarInImpl |
100 | @end |
101 | @interface LastIvarInExtension_OtherIvarInImpl() { |
102 | char flexible[]; // expected-error {{flexible array member 'flexible' with type 'char []' is not at the end of class}} |
103 | // expected-warning@-1 {{field 'flexible' with variable sized type 'char []' is not visible to subclasses and can conflict with their instance variables}} |
104 | } |
105 | @end |
106 | @implementation LastIvarInExtension_OtherIvarInImpl { |
107 | int last; // expected-note {{next instance variable declaration is here}} |
108 | } |
109 | @end |
110 | |
111 | // ## Instance variables in named categories. |
112 | @interface IvarInNamedCategory |
113 | @end |
114 | @interface IvarInNamedCategory(Category) { |
115 | char flexible[]; // expected-error {{instance variables may not be placed in categories}} |
116 | } |
117 | @end |
118 | |
119 | // ## Synthesized instance variable. |
120 | @interface LastIvarAndProperty { |
121 | char _flexible[]; |
122 | } |
123 | @property char flexible[]; // expected-error {{property cannot have array or function type 'char []'}} |
124 | @end |
125 | |
126 | // ## Synthesize other instance variables. |
127 | @interface LastIvar_ExplicitlyNamedPropertyBackingIvarPreceding { |
128 | int _elementsCount; |
129 | char flexible[]; |
130 | } |
131 | @property int count; |
132 | @end |
133 | @implementation LastIvar_ExplicitlyNamedPropertyBackingIvarPreceding |
134 | @synthesize count = _elementsCount; |
135 | @end |
136 | |
137 | @interface LastIvar_ImplicitlyNamedPropertyBackingIvarPreceding { |
138 | int count; |
139 | char flexible[]; |
140 | } |
141 | @property int count; |
142 | @end |
143 | @implementation LastIvar_ImplicitlyNamedPropertyBackingIvarPreceding |
144 | @synthesize count; |
145 | @end |
146 | |
147 | @interface NotLastIvar_ExplicitlyNamedPropertyBackingIvarLast { |
148 | char flexible[]; // expected-error {{flexible array member 'flexible' with type 'char []' is not at the end of class}} |
149 | } |
150 | @property int count; |
151 | @end |
152 | @implementation NotLastIvar_ExplicitlyNamedPropertyBackingIvarLast |
153 | @synthesize count = _elementsCount; // expected-note {{next synthesized instance variable is here}} |
154 | @end |
155 | |
156 | @interface NotLastIvar_ImplicitlyNamedPropertyBackingIvarLast { |
157 | char flexible[]; // expected-error {{flexible array member 'flexible' with type 'char []' is not at the end of class}} |
158 | } |
159 | @property int count; // expected-note {{next synthesized instance variable is here}} |
160 | @end |
161 | @implementation NotLastIvar_ImplicitlyNamedPropertyBackingIvarLast |
162 | // Test auto-synthesize. |
163 | //@synthesize count; |
164 | @end |
165 | |
166 | |
167 | // # Variable sized types. |
168 | struct Packet { |
169 | unsigned int size; |
170 | char data[]; |
171 | }; |
172 | |
173 | // ## Instance variables only in interface. |
174 | @interface LastStructIvar { |
175 | struct Packet flexible; |
176 | } |
177 | @end |
178 | |
179 | @interface NotLastStructIvar { |
180 | struct Packet flexible; // expected-error {{field 'flexible' with variable sized type 'struct Packet' is not at the end of class}} |
181 | int last; // expected-note {{next instance variable declaration is here}} |
182 | } |
183 | @end |
184 | |
185 | // ## Instance variables in implementation. |
186 | @interface LastStructIvarInImpl |
187 | @end |
188 | @implementation LastStructIvarInImpl { |
189 | struct Packet flexible; // expected-warning {{field 'flexible' with variable sized type 'struct Packet' is not visible to subclasses and can conflict with their instance variables}} |
190 | } |
191 | @end |
192 | |
193 | @interface NotLastStructIvarInImpl |
194 | @end |
195 | @implementation NotLastStructIvarInImpl { |
196 | struct Packet flexible; // expected-error {{field 'flexible' with variable sized type 'struct Packet' is not at the end of class}} |
197 | // expected-warning@-1 {{field 'flexible' with variable sized type 'struct Packet' is not visible to subclasses and can conflict with their instance variables}} |
198 | int last; // expected-note {{next instance variable declaration is here}} |
199 | } |
200 | @end |
201 | |
202 | @interface LastStructIvarInClass_OtherIvarInImpl { |
203 | struct Packet flexible; // expected-error {{field 'flexible' with variable sized type 'struct Packet' is not at the end of class}} |
204 | } |
205 | @end |
206 | @implementation LastStructIvarInClass_OtherIvarInImpl { |
207 | int last; // expected-note {{next instance variable declaration is here}} |
208 | } |
209 | @end |
210 | |
211 | // ## Synthesized instance variable. |
212 | @interface LastSynthesizeStructIvar |
213 | @property int first; |
214 | @property struct Packet flexible; // expected-error {{synthesized property with variable size type 'struct Packet' requires an existing instance variable}} |
215 | @end |
216 | @implementation LastSynthesizeStructIvar |
217 | @end |
218 | |
219 | @interface NotLastSynthesizeStructIvar |
220 | @property struct Packet flexible; // expected-error {{synthesized property with variable size type 'struct Packet' requires an existing instance variable}} |
221 | @property int last; |
222 | @end |
223 | @implementation NotLastSynthesizeStructIvar |
224 | @end |
225 | |
226 | @interface LastStructIvarWithExistingIvarAndSynthesizedProperty { |
227 | struct Packet _flexible; |
228 | } |
229 | @property struct Packet flexible; |
230 | @end |
231 | @implementation LastStructIvarWithExistingIvarAndSynthesizedProperty |
232 | @end |
233 | |
234 | |
235 | // # Subclasses. |
236 | @interface FlexibleArrayMemberBase { |
237 | char flexible[]; // expected-note6 {{'flexible' declared here}} |
238 | } |
239 | @end |
240 | |
241 | @interface NoIvarAdditions : FlexibleArrayMemberBase |
242 | @end |
243 | @implementation NoIvarAdditions |
244 | @end |
245 | |
246 | @interface AddedIvarInInterface : FlexibleArrayMemberBase { |
247 | int last; // expected-warning {{field 'last' can overwrite instance variable 'flexible' with variable sized type 'char []' in superclass 'FlexibleArrayMemberBase'}} |
248 | } |
249 | @end |
250 | |
251 | @interface AddedIvarInImplementation : FlexibleArrayMemberBase |
252 | @end |
253 | @implementation AddedIvarInImplementation { |
254 | int last; // expected-warning {{field 'last' can overwrite instance variable 'flexible' with variable sized type 'char []' in superclass 'FlexibleArrayMemberBase'}} |
255 | } |
256 | @end |
257 | |
258 | @interface AddedIvarInExtension : FlexibleArrayMemberBase |
259 | @end |
260 | @interface AddedIvarInExtension() { |
261 | int last; // expected-warning {{field 'last' can overwrite instance variable 'flexible' with variable sized type 'char []' in superclass 'FlexibleArrayMemberBase'}} |
262 | } |
263 | @end |
264 | |
265 | @interface SynthesizedIvar : FlexibleArrayMemberBase |
266 | @property int count; |
267 | @end |
268 | @implementation SynthesizedIvar |
269 | @synthesize count; // expected-warning {{field 'count' can overwrite instance variable 'flexible' with variable sized type 'char []' in superclass 'FlexibleArrayMemberBase'}} |
270 | @end |
271 | |
272 | @interface WarnInSubclassOnlyOnce : FlexibleArrayMemberBase { |
273 | int last; // expected-warning {{field 'last' can overwrite instance variable 'flexible' with variable sized type 'char []' in superclass 'FlexibleArrayMemberBase'}} |
274 | } |
275 | @end |
276 | @interface WarnInSubclassOnlyOnce() { |
277 | int laster; |
278 | } |
279 | @end |
280 | @implementation WarnInSubclassOnlyOnce { |
281 | int lastest; |
282 | } |
283 | @end |
284 | |
285 | @interface AddedIvarInSubSubClass : NoIvarAdditions { |
286 | int last; // expected-warning {{field 'last' can overwrite instance variable 'flexible' with variable sized type 'char []' in superclass 'FlexibleArrayMemberBase'}} |
287 | } |
288 | @end |
289 | |