blob: 14deae58f946c3223aeef25a42465a3a72b17ce1 [file] [log] [blame]
DeLesley Hutchins9cd5d402013-10-17 22:21:03 +00001// RUN: %clang_cc1 -fsyntax-only -verify -Wconsumed -fcxx-exceptions -std=c++11 %s
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +00002
DeLesley Hutchins66540852013-10-04 21:28:06 +00003// TODO: Switch to using macros for the expected warnings.
4
5#define CALLABLE_WHEN(...) __attribute__ ((callable_when(__VA_ARGS__)))
6#define CONSUMABLE(state) __attribute__ ((consumable(state)))
DeLesley Hutchinsd4f0e192013-10-17 23:23:53 +00007#define PARAM_TYPESTATE(state) __attribute__ ((param_typestate(state)))
DeLesley Hutchins66540852013-10-04 21:28:06 +00008#define RETURN_TYPESTATE(state) __attribute__ ((return_typestate(state)))
DeLesley Hutchinsd4f0e192013-10-17 23:23:53 +00009#define SET_TYPESTATE(state) __attribute__ ((set_typestate(state)))
DeLesley Hutchins1bf63432013-10-11 22:30:48 +000010#define TESTS_TYPESTATE(state) __attribute__ ((tests_typestate(state)))
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +000011
12typedef decltype(nullptr) nullptr_t;
13
14template <typename T>
David Blaikiea33ab602013-09-06 01:28:43 +000015class CONSUMABLE(unconsumed) ConsumableClass {
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +000016 T var;
17
DeLesley Hutchins627c7f92013-10-11 21:55:33 +000018public:
DeLesley Hutchinsb7dc1f52013-08-29 17:26:57 +000019 ConsumableClass();
DeLesley Hutchins0e8534e2013-09-03 20:11:38 +000020 ConsumableClass(nullptr_t p) RETURN_TYPESTATE(consumed);
21 ConsumableClass(T val) RETURN_TYPESTATE(unconsumed);
David Blaikiea33ab602013-09-06 01:28:43 +000022 ConsumableClass(ConsumableClass<T> &other);
23 ConsumableClass(ConsumableClass<T> &&other);
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +000024
DeLesley Hutchins9e8bd1d2013-08-23 18:40:39 +000025 ConsumableClass<T>& operator=(ConsumableClass<T> &other);
26 ConsumableClass<T>& operator=(ConsumableClass<T> &&other);
DeLesley Hutchinsf30e1942013-10-11 23:03:26 +000027 ConsumableClass<T>& operator=(nullptr_t) SET_TYPESTATE(consumed);
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +000028
29 template <typename U>
DeLesley Hutchins9e8bd1d2013-08-23 18:40:39 +000030 ConsumableClass<T>& operator=(ConsumableClass<U> &other);
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +000031
32 template <typename U>
DeLesley Hutchins9e8bd1d2013-08-23 18:40:39 +000033 ConsumableClass<T>& operator=(ConsumableClass<U> &&other);
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +000034
DeLesley Hutchinsf30e1942013-10-11 23:03:26 +000035 void operator()(int a) SET_TYPESTATE(consumed);
DeLesley Hutchins66540852013-10-04 21:28:06 +000036 void operator*() const CALLABLE_WHEN("unconsumed");
37 void unconsumedCall() const CALLABLE_WHEN("unconsumed");
38 void callableWhenUnknown() const CALLABLE_WHEN("unconsumed", "unknown");
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +000039
DeLesley Hutchins1bf63432013-10-11 22:30:48 +000040 bool isValid() const TESTS_TYPESTATE(unconsumed);
41 operator bool() const TESTS_TYPESTATE(unconsumed);
42 bool operator!=(nullptr_t) const TESTS_TYPESTATE(unconsumed);
43 bool operator==(nullptr_t) const TESTS_TYPESTATE(consumed);
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +000044
DeLesley Hutchinsb7dc1f52013-08-29 17:26:57 +000045 void constCall() const;
46 void nonconstCall();
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +000047
DeLesley Hutchinsf30e1942013-10-11 23:03:26 +000048 void consume() SET_TYPESTATE(consumed);
49 void unconsume() SET_TYPESTATE(unconsumed);
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +000050};
51
DeLesley Hutchins627c7f92013-10-11 21:55:33 +000052class CONSUMABLE(unconsumed) DestructorTester {
53public:
DeLesley Hutchinsc5cdafc2013-10-18 18:36:21 +000054 DestructorTester() RETURN_TYPESTATE(unconsumed);
DeLesley Hutchins627c7f92013-10-11 21:55:33 +000055 DestructorTester(int);
56
DeLesley Hutchinsc5cdafc2013-10-18 18:36:21 +000057 void operator*() CALLABLE_WHEN("unconsumed");
DeLesley Hutchins627c7f92013-10-11 21:55:33 +000058
59 ~DestructorTester() CALLABLE_WHEN("consumed");
60};
61
DeLesley Hutchins9e8bd1d2013-08-23 18:40:39 +000062void baf0(const ConsumableClass<int> var);
63void baf1(const ConsumableClass<int> &var);
64void baf2(const ConsumableClass<int> *var);
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +000065
DeLesley Hutchinsbe63ab62013-10-18 19:25:18 +000066void baf3(ConsumableClass<int> var);
67void baf4(ConsumableClass<int> &var);
68void baf5(ConsumableClass<int> *var);
69void baf6(ConsumableClass<int> &&var);
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +000070
DeLesley Hutchins0e8534e2013-09-03 20:11:38 +000071ConsumableClass<int> returnsUnconsumed() {
72 return ConsumableClass<int>(); // expected-warning {{return value not in expected state; expected 'unconsumed', observed 'consumed'}}
73}
74
75ConsumableClass<int> returnsConsumed() RETURN_TYPESTATE(consumed);
76ConsumableClass<int> returnsConsumed() {
77 return ConsumableClass<int>();
78}
79
DeLesley Hutchins66540852013-10-04 21:28:06 +000080ConsumableClass<int> returnsUnknown() RETURN_TYPESTATE(unknown);
81
DeLesley Hutchinsb7dc1f52013-08-29 17:26:57 +000082void testInitialization() {
DeLesley Hutchins9e8bd1d2013-08-23 18:40:39 +000083 ConsumableClass<int> var0;
84 ConsumableClass<int> var1 = ConsumableClass<int>();
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +000085
DeLesley Hutchins9e8bd1d2013-08-23 18:40:39 +000086 var0 = ConsumableClass<int>();
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +000087
DeLesley Hutchins66540852013-10-04 21:28:06 +000088 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
89 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +000090
91 if (var0.isValid()) {
92 *var0;
DeLesley Hutchinsb7dc1f52013-08-29 17:26:57 +000093 *var1;
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +000094
95 } else {
DeLesley Hutchins66540852013-10-04 21:28:06 +000096 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +000097 }
98}
99
DeLesley Hutchins627c7f92013-10-11 21:55:33 +0000100void testDestruction() {
101 DestructorTester D0(42), D1(42);
102
103 *D0;
104 *D1;
105
DeLesley Hutchinsc5cdafc2013-10-18 18:36:21 +0000106 DestructorTester D2;
107 *D2;
108
DeLesley Hutchins627c7f92013-10-11 21:55:33 +0000109 D0.~DestructorTester(); // expected-warning {{invalid invocation of method '~DestructorTester' on object 'D0' while it is in the 'unconsumed' state}}
110
DeLesley Hutchinsc5cdafc2013-10-18 18:36:21 +0000111 return; // expected-warning {{invalid invocation of method '~DestructorTester' on object 'D0' while it is in the 'unconsumed' state}} \
112 expected-warning {{invalid invocation of method '~DestructorTester' on object 'D1' while it is in the 'unconsumed' state}} \
113 expected-warning {{invalid invocation of method '~DestructorTester' on object 'D2' while it is in the 'unconsumed' state}}
DeLesley Hutchins627c7f92013-10-11 21:55:33 +0000114}
115
DeLesley Hutchins9e8bd1d2013-08-23 18:40:39 +0000116void testTempValue() {
DeLesley Hutchins66540852013-10-04 21:28:06 +0000117 *ConsumableClass<int>(); // expected-warning {{invalid invocation of method 'operator*' on a temporary object while it is in the 'consumed' state}}
DeLesley Hutchins5fdd2072013-08-22 20:44:47 +0000118}
119
DeLesley Hutchinsb7dc1f52013-08-29 17:26:57 +0000120void testSimpleRValueRefs() {
DeLesley Hutchins9e8bd1d2013-08-23 18:40:39 +0000121 ConsumableClass<int> var0;
122 ConsumableClass<int> var1(42);
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +0000123
DeLesley Hutchins66540852013-10-04 21:28:06 +0000124 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +0000125 *var1;
126
DeLesley Hutchins9e8bd1d2013-08-23 18:40:39 +0000127 var0 = static_cast<ConsumableClass<int>&&>(var1);
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +0000128
129 *var0;
DeLesley Hutchins66540852013-10-04 21:28:06 +0000130 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +0000131}
132
DeLesley Hutchinsb7dc1f52013-08-29 17:26:57 +0000133void testIfStmt() {
DeLesley Hutchins9e8bd1d2013-08-23 18:40:39 +0000134 ConsumableClass<int> var;
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +0000135
136 if (var.isValid()) {
DeLesley Hutchinsb7dc1f52013-08-29 17:26:57 +0000137 *var;
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +0000138 } else {
DeLesley Hutchins66540852013-10-04 21:28:06 +0000139 *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}}
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +0000140 }
141
142 if (!var.isValid()) {
DeLesley Hutchins66540852013-10-04 21:28:06 +0000143 *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}}
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +0000144 } else {
145 *var;
146 }
147
148 if (var) {
149 // Empty
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +0000150 } else {
DeLesley Hutchins66540852013-10-04 21:28:06 +0000151 *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}}
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +0000152 }
DeLesley Hutchins5fdd2072013-08-22 20:44:47 +0000153
154 if (var != nullptr) {
155 // Empty
DeLesley Hutchins5fdd2072013-08-22 20:44:47 +0000156 } else {
DeLesley Hutchins66540852013-10-04 21:28:06 +0000157 *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}}
DeLesley Hutchins5fdd2072013-08-22 20:44:47 +0000158 }
DeLesley Hutchins1bf63432013-10-11 22:30:48 +0000159
160 if (var == nullptr) {
161 *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}}
162 } else {
163 // Empty
164 }
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +0000165}
166
DeLesley Hutchins66540852013-10-04 21:28:06 +0000167void testComplexConditionals0() {
DeLesley Hutchinsb7dc1f52013-08-29 17:26:57 +0000168 ConsumableClass<int> var0, var1, var2;
169
170 if (var0 && var1) {
171 *var0;
172 *var1;
173
174 } else {
DeLesley Hutchins66540852013-10-04 21:28:06 +0000175 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
176 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
DeLesley Hutchinsb7dc1f52013-08-29 17:26:57 +0000177 }
178
179 if (var0 || var1) {
180 *var0;
181 *var1;
182
183 } else {
DeLesley Hutchins66540852013-10-04 21:28:06 +0000184 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
185 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
DeLesley Hutchinsb7dc1f52013-08-29 17:26:57 +0000186 }
187
188 if (var0 && !var1) {
189 *var0;
190 *var1;
191
192 } else {
DeLesley Hutchins66540852013-10-04 21:28:06 +0000193 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
194 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
DeLesley Hutchinsb7dc1f52013-08-29 17:26:57 +0000195 }
196
197 if (var0 || !var1) {
DeLesley Hutchins66540852013-10-04 21:28:06 +0000198 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
199 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
DeLesley Hutchinsb7dc1f52013-08-29 17:26:57 +0000200
201 } else {
202 *var0;
203 *var1;
204 }
205
206 if (!var0 && !var1) {
DeLesley Hutchins66540852013-10-04 21:28:06 +0000207 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
208 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
DeLesley Hutchinsb7dc1f52013-08-29 17:26:57 +0000209
210 } else {
211 *var0;
212 *var1;
213 }
214
215 if (!var0 || !var1) {
DeLesley Hutchins66540852013-10-04 21:28:06 +0000216 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
217 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
DeLesley Hutchinsb7dc1f52013-08-29 17:26:57 +0000218
219 } else {
220 *var0;
221 *var1;
222 }
223
224 if (!(var0 && var1)) {
DeLesley Hutchins66540852013-10-04 21:28:06 +0000225 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
226 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
DeLesley Hutchinsb7dc1f52013-08-29 17:26:57 +0000227
228 } else {
229 *var0;
230 *var1;
231 }
232
233 if (!(var0 || var1)) {
DeLesley Hutchins66540852013-10-04 21:28:06 +0000234 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
235 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
DeLesley Hutchinsb7dc1f52013-08-29 17:26:57 +0000236
237 } else {
238 *var0;
239 *var1;
240 }
241
242 if (var0 && var1 && var2) {
243 *var0;
244 *var1;
245 *var2;
246
247 } else {
DeLesley Hutchins66540852013-10-04 21:28:06 +0000248 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
249 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
250 *var2; // expected-warning {{invalid invocation of method 'operator*' on object 'var2' while it is in the 'consumed' state}}
DeLesley Hutchinsb7dc1f52013-08-29 17:26:57 +0000251 }
252
253#if 0
254 // FIXME: Get this test to pass.
255 if (var0 || var1 || var2) {
256 *var0;
257 *var1;
258 *var2;
259
260 } else {
DeLesley Hutchins66540852013-10-04 21:28:06 +0000261 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
262 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
263 *var2; // expected-warning {{invalid invocation of method 'operator*' on object 'var2' while it is in the 'consumed' state}}
264 }
265#endif
266}
267
268void testComplexConditionals1() {
269 ConsumableClass<int> var0, var1, var2;
270
271 // Coerce all variables into the unknown state.
DeLesley Hutchinsbe63ab62013-10-18 19:25:18 +0000272 baf4(var0);
273 baf4(var1);
274 baf4(var2);
DeLesley Hutchins66540852013-10-04 21:28:06 +0000275
276 if (var0 && var1) {
277 *var0;
278 *var1;
279
280 } else {
281 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}}
282 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}}
283 }
284
285 if (var0 || var1) {
286 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}}
287 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}}
288
289 } else {
290 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
291 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
292 }
293
294 if (var0 && !var1) {
295 *var0;
296 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
297
298 } else {
299 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}}
300 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}}
301 }
302
303 if (var0 || !var1) {
304 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}}
305 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}}
306
307 } else {
308 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
309 *var1;
310 }
311
312 if (!var0 && !var1) {
313 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
314 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
315
316 } else {
317 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}}
318 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}}
319 }
320
321 if (!(var0 || var1)) {
322 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
323 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
324
325 } else {
326 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}}
327 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}}
328 }
329
330 if (!var0 || !var1) {
331 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}}
332 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}}
333
334 } else {
335 *var0;
336 *var1;
337 }
338
339 if (!(var0 && var1)) {
340 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}}
341 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}}
342
343 } else {
344 *var0;
345 *var1;
346 }
347
348 if (var0 && var1 && var2) {
349 *var0;
350 *var1;
351 *var2;
352
353 } else {
354 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}}
355 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}}
356 *var2; // expected-warning {{invalid invocation of method 'operator*' on object 'var2' while it is in the 'unknown' state}}
357 }
358
359#if 0
360 // FIXME: Get this test to pass.
361 if (var0 || var1 || var2) {
362 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}}
363 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}}
364 *var2; // expected-warning {{invalid invocation of method 'operator*' on object 'var2' while it is in the 'unknown' state}}
365
366 } else {
367 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
368 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
369 *var2; // expected-warning {{invalid invocation of method 'operator*' on object 'var2' while it is in the 'consumed' state}}
DeLesley Hutchinsb7dc1f52013-08-29 17:26:57 +0000370 }
371#endif
372}
373
374void testStateChangeInBranch() {
375 ConsumableClass<int> var;
376
377 // Make var enter the 'unknown' state.
DeLesley Hutchinsbe63ab62013-10-18 19:25:18 +0000378 baf4(var);
DeLesley Hutchinsb7dc1f52013-08-29 17:26:57 +0000379
380 if (!var) {
381 var = ConsumableClass<int>(42);
382 }
383
384 *var;
385}
386
DeLesley Hutchins42525982013-08-29 22:36:05 +0000387void testFunctionParam(ConsumableClass<int> param) {
388
389 if (param.isValid()) {
390 *param;
391 } else {
David Blaikiea33ab602013-09-06 01:28:43 +0000392 *param;
DeLesley Hutchins42525982013-08-29 22:36:05 +0000393 }
394
395 param = nullptr;
396 *param; // expected-warning {{invocation of method 'operator*' on object 'param' while it is in the 'consumed' state}}
397}
398
DeLesley Hutchinscd0f6d72013-10-17 22:53:04 +0000399void testParamReturnTypestateCallee(bool cond, ConsumableClass<int> &Param RETURN_TYPESTATE(unconsumed)) { // expected-warning {{parameter 'Param' not in expected state when the function returns: expected 'unconsumed', observed 'consumed'}}
400
401 if (cond) {
402 Param.consume();
403 return; // expected-warning {{parameter 'Param' not in expected state when the function returns: expected 'unconsumed', observed 'consumed'}}
404 }
405
406 Param.consume();
407}
408
409void testParamReturnTypestateCaller() {
410 ConsumableClass<int> var;
411
412 testParamReturnTypestateCallee(true, var);
413
414 *var;
415}
416
DeLesley Hutchinsd4f0e192013-10-17 23:23:53 +0000417void testParamTypestateCallee(ConsumableClass<int> Param0 PARAM_TYPESTATE(consumed),
418 ConsumableClass<int> &Param1 PARAM_TYPESTATE(consumed)) {
419
420 *Param0; // expected-warning {{invalid invocation of method 'operator*' on object 'Param0' while it is in the 'consumed' state}}
421 *Param1; // expected-warning {{invalid invocation of method 'operator*' on object 'Param1' while it is in the 'consumed' state}}
422}
423
424void testParamTypestateCaller() {
425 ConsumableClass<int> Var0, Var1(42);
426
427 testParamTypestateCallee(Var0, Var1); // expected-warning {{argument not in expected state; expected 'consumed', observed 'unconsumed'}}
428}
429
DeLesley Hutchinsbe63ab62013-10-18 19:25:18 +0000430void baf3(ConsumableClass<int> var) {
431 *var;
432}
433
434void baf4(ConsumableClass<int> &var) {
435 *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'unknown' state}}
436}
437
438void baf6(ConsumableClass<int> &&var) {
439 *var;
440}
441
DeLesley Hutchinsb7dc1f52013-08-29 17:26:57 +0000442void testCallingConventions() {
DeLesley Hutchins9e8bd1d2013-08-23 18:40:39 +0000443 ConsumableClass<int> var(42);
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +0000444
445 baf0(var);
446 *var;
447
448 baf1(var);
449 *var;
450
451 baf2(&var);
452 *var;
453
DeLesley Hutchinsbe63ab62013-10-18 19:25:18 +0000454 baf4(var);
DeLesley Hutchins66540852013-10-04 21:28:06 +0000455 *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'unknown' state}}
456
457 var = ConsumableClass<int>(42);
DeLesley Hutchinsbe63ab62013-10-18 19:25:18 +0000458 baf5(&var);
DeLesley Hutchins66540852013-10-04 21:28:06 +0000459 *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'unknown' state}}
460
461 var = ConsumableClass<int>(42);
DeLesley Hutchinsbe63ab62013-10-18 19:25:18 +0000462 baf6(static_cast<ConsumableClass<int>&&>(var));
DeLesley Hutchins66540852013-10-04 21:28:06 +0000463 *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}}
464}
465
466void testConstAndNonConstMemberFunctions() {
467 ConsumableClass<int> var(42);
468
469 var.constCall();
470 *var;
471
472 var.nonconstCall();
473 *var;
474}
475
476void testFunctionParam0(ConsumableClass<int> param) {
477 *param;
478}
479
480void testFunctionParam1(ConsumableClass<int> &param) {
481 *param; // expected-warning {{invalid invocation of method 'operator*' on object 'param' while it is in the 'unknown' state}}
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +0000482}
483
DeLesley Hutchins0e8534e2013-09-03 20:11:38 +0000484void testReturnStates() {
485 ConsumableClass<int> var;
486
487 var = returnsUnconsumed();
488 *var;
489
490 var = returnsConsumed();
DeLesley Hutchins66540852013-10-04 21:28:06 +0000491 *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}}
492}
493
494void testCallableWhen() {
495 ConsumableClass<int> var(42);
496
497 *var;
498
DeLesley Hutchinsbe63ab62013-10-18 19:25:18 +0000499 baf4(var);
DeLesley Hutchins66540852013-10-04 21:28:06 +0000500
501 var.callableWhenUnknown();
DeLesley Hutchins0e8534e2013-09-03 20:11:38 +0000502}
503
DeLesley Hutchinsb7dc1f52013-08-29 17:26:57 +0000504void testMoveAsignmentish() {
DeLesley Hutchins9e8bd1d2013-08-23 18:40:39 +0000505 ConsumableClass<int> var0;
506 ConsumableClass<long> var1(42);
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +0000507
DeLesley Hutchins66540852013-10-04 21:28:06 +0000508 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +0000509 *var1;
510
DeLesley Hutchins9e8bd1d2013-08-23 18:40:39 +0000511 var0 = static_cast<ConsumableClass<long>&&>(var1);
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +0000512
513 *var0;
DeLesley Hutchins66540852013-10-04 21:28:06 +0000514 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
DeLesley Hutchinsd324a0b2013-08-29 21:17:25 +0000515
516 var1 = ConsumableClass<long>(42);
517 var1 = nullptr;
DeLesley Hutchins66540852013-10-04 21:28:06 +0000518 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +0000519}
520
DeLesley Hutchinsb7dc1f52013-08-29 17:26:57 +0000521void testConditionalMerge() {
DeLesley Hutchins9e8bd1d2013-08-23 18:40:39 +0000522 ConsumableClass<int> var;
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +0000523
524 if (var.isValid()) {
525 // Empty
526 }
527
DeLesley Hutchins66540852013-10-04 21:28:06 +0000528 *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}}
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +0000529
530 if (var.isValid()) {
531 // Empty
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +0000532 } else {
533 // Empty
534 }
535
DeLesley Hutchins66540852013-10-04 21:28:06 +0000536 *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}}
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +0000537}
538
DeLesley Hutchinsf30e1942013-10-11 23:03:26 +0000539void testSetTypestate() {
DeLesley Hutchins9e8bd1d2013-08-23 18:40:39 +0000540 ConsumableClass<int> var(42);
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +0000541
542 *var;
543
544 var.consume();
545
DeLesley Hutchins66540852013-10-04 21:28:06 +0000546 *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}}
DeLesley Hutchinsf30e1942013-10-11 23:03:26 +0000547
548 var.unconsume();
549
550 *var;
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +0000551}
552
DeLesley Hutchinsf30e1942013-10-11 23:03:26 +0000553void testConsumes0() {
DeLesley Hutchins9e8bd1d2013-08-23 18:40:39 +0000554 ConsumableClass<int> var(nullptr);
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +0000555
DeLesley Hutchins66540852013-10-04 21:28:06 +0000556 *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}}
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +0000557}
558
DeLesley Hutchinsf30e1942013-10-11 23:03:26 +0000559void testConsumes1() {
DeLesley Hutchins9e8bd1d2013-08-23 18:40:39 +0000560 ConsumableClass<int> var(42);
DeLesley Hutchins5fdd2072013-08-22 20:44:47 +0000561
562 var.unconsumedCall();
563 var(6);
564
DeLesley Hutchins66540852013-10-04 21:28:06 +0000565 var.unconsumedCall(); // expected-warning {{invalid invocation of method 'unconsumedCall' on object 'var' while it is in the 'consumed' state}}
DeLesley Hutchins5fdd2072013-08-22 20:44:47 +0000566}
567
DeLesley Hutchins66540852013-10-04 21:28:06 +0000568void testUnreachableBlock() {
DeLesley Hutchinsb7dc1f52013-08-29 17:26:57 +0000569 ConsumableClass<int> var(42);
570
571 if (var) {
572 *var;
573 } else {
574 *var;
575 }
576
577 *var;
578}
579
DeLesley Hutchins73858402013-10-09 18:30:24 +0000580
581void testForLoop1() {
582 ConsumableClass<int> var0, var1(42);
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +0000583
DeLesley Hutchins73858402013-10-09 18:30:24 +0000584 for (int i = 0; i < 10; ++i) { // expected-warning {{state of variable 'var1' must match at the entry and exit of loop}}
585 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
586
587 *var1;
588 var1.consume();
589 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +0000590 }
591
DeLesley Hutchins73858402013-10-09 18:30:24 +0000592 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +0000593}
594
DeLesley Hutchins73858402013-10-09 18:30:24 +0000595void testWhileLoop1() {
596 int i = 10;
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +0000597
DeLesley Hutchins73858402013-10-09 18:30:24 +0000598 ConsumableClass<int> var0, var1(42);
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +0000599
DeLesley Hutchins52f717e2013-10-17 18:19:31 +0000600 while (i-- > 0) { // expected-warning {{state of variable 'var1' must match at the entry and exit of loop}}
DeLesley Hutchins73858402013-10-09 18:30:24 +0000601 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
602
603 *var1;
604 var1.consume();
DeLesley Hutchins52f717e2013-10-17 18:19:31 +0000605 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +0000606 }
607
DeLesley Hutchins73858402013-10-09 18:30:24 +0000608 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +0000609}
DeLesley Hutchins52f717e2013-10-17 18:19:31 +0000610
611
612namespace ContinueICETest {
613
614bool cond1();
615bool cond2();
616
617static void foo1() {
618 while (cond1()) {
619 if (cond2())
620 continue;
621 }
622}
623
624static void foo2() {
625 while (true) {
626 if (false)
627 continue;
628 }
629}
630
DeLesley Hutchins9cd5d402013-10-17 22:21:03 +0000631class runtime_error
632{
633public:
634 virtual ~runtime_error();
635};
636
637void read(bool sf) {
638 while (sf) {
639 if(sf) throw runtime_error();
640 }
641}
642
DeLesley Hutchins52f717e2013-10-17 18:19:31 +0000643} // end namespace ContinueICETest
644