1 // RUN: %clang_cc1 -fsyntax-only -verify -Wconsumed -fcxx-exceptions -std=c++11 %s
2
3 // 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)))
7 #define PARAM_TYPESTATE(state) __attribute__ ((param_typestate(state)))
8 #define RETURN_TYPESTATE(state) __attribute__ ((return_typestate(state)))
9 #define SET_TYPESTATE(state) __attribute__ ((set_typestate(state)))
10 #define TEST_TYPESTATE(state) __attribute__ ((test_typestate(state)))
11
12 typedef decltype(nullptr) nullptr_t;
13
14 template <typename T>
CONSUMABLE(unconsumed)15 class CONSUMABLE(unconsumed) ConsumableClass {
16 T var;
17
18 public:
19 ConsumableClass();
20 ConsumableClass(nullptr_t p) RETURN_TYPESTATE(consumed);
21 ConsumableClass(T val) RETURN_TYPESTATE(unconsumed);
22 ConsumableClass(ConsumableClass<T> &other);
23 ConsumableClass(ConsumableClass<T> &&other);
24
25 ConsumableClass<T>& operator=(ConsumableClass<T> &other);
26 ConsumableClass<T>& operator=(ConsumableClass<T> &&other);
27 ConsumableClass<T>& operator=(nullptr_t) SET_TYPESTATE(consumed);
28
29 template <typename U>
30 ConsumableClass<T>& operator=(ConsumableClass<U> &other);
31
32 template <typename U>
33 ConsumableClass<T>& operator=(ConsumableClass<U> &&other);
34
35 void operator()(int a) SET_TYPESTATE(consumed);
36 void operator*() const CALLABLE_WHEN("unconsumed");
37 void unconsumedCall() const CALLABLE_WHEN("unconsumed");
38 void callableWhenUnknown() const CALLABLE_WHEN("unconsumed", "unknown");
39
40 bool isValid() const TEST_TYPESTATE(unconsumed);
41 operator bool() const TEST_TYPESTATE(unconsumed);
42 bool operator!=(nullptr_t) const TEST_TYPESTATE(unconsumed);
43 bool operator==(nullptr_t) const TEST_TYPESTATE(consumed);
44
45 void constCall() const;
46 void nonconstCall();
47
48 void consume() SET_TYPESTATE(consumed);
49 void unconsume() SET_TYPESTATE(unconsumed);
50 };
51
52 class CONSUMABLE(unconsumed) DestructorTester {
53 public:
54 DestructorTester();
55 DestructorTester(int);
56 DestructorTester(nullptr_t) RETURN_TYPESTATE(unconsumed);
57 DestructorTester(DestructorTester &&);
58
59 void operator*() CALLABLE_WHEN("unconsumed");
60
61 ~DestructorTester() CALLABLE_WHEN("consumed");
62
63 };
64
65 void dtByVal(DestructorTester);
66 void dtByValMarkUnconsumed(DestructorTester RETURN_TYPESTATE(unconsumed));
67
68 void baf0(const ConsumableClass<int> var);
69 void baf1(const ConsumableClass<int> &var);
70 void baf2(const ConsumableClass<int> *var);
71
72 void baf3(ConsumableClass<int> var);
73 void baf4(ConsumableClass<int> &var);
74 void baf5(ConsumableClass<int> *var);
75 void baf6(ConsumableClass<int> &&var);
76
77 ConsumableClass<int> returnsUnconsumed() {
78 return ConsumableClass<int>(); // expected-warning {{return value not in expected state; expected 'unconsumed', observed 'consumed'}}
79 }
80
81 ConsumableClass<int> returnsConsumed() RETURN_TYPESTATE(consumed);
82 ConsumableClass<int> returnsConsumed() {
83 return ConsumableClass<int>();
84 }
85
86 ConsumableClass<int> returnsUnknown() RETURN_TYPESTATE(unknown);
87
88 void testInitialization() {
89 ConsumableClass<int> var0;
90 ConsumableClass<int> var1 = ConsumableClass<int>();
91 ConsumableClass<int> var2(42);
92 ConsumableClass<int> var3(var2); // copy constructor
93 ConsumableClass<int> var4(var0); // copy consumed value
94
95 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
96 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
97 *var2;
98 *var3;
99 *var4; // expected-warning {{invalid invocation of method 'operator*' on object 'var4' while it is in the 'consumed' state}}
100
101 var0 = ConsumableClass<int>(42);
102 *var0;
103
104 var0 = var1;
105 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
106
107 if (var0.isValid()) {
108 *var0;
109 *var1;
110
111 } else {
112 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
113 }
114 }
115
116 void testDestruction() {
117 DestructorTester D0(42), D1(42), D2;
118
119 *D0;
120 *D1;
121 *D2; // expected-warning {{invalid invocation of method 'operator*' on object 'D2' while it is in the 'consumed' state}}
122
123 D0.~DestructorTester(); // expected-warning {{invalid invocation of method '~DestructorTester' on object 'D0' while it is in the 'unconsumed' state}}
124
125 return; // expected-warning {{invalid invocation of method '~DestructorTester' on object 'D0' while it is in the 'unconsumed' state}} \
126 expected-warning {{invalid invocation of method '~DestructorTester' on object 'D1' while it is in the 'unconsumed' state}}
127 }
128
129 void testDestructionByVal() {
130 {
131 // both the var and the temporary are consumed:
132 DestructorTester D0(nullptr);
133 dtByVal((DestructorTester &&)D0);
134 }
135 {
136 // the var is consumed but the temporary isn't:
137 DestructorTester D1(nullptr);
138 dtByValMarkUnconsumed((DestructorTester &&)D1); // expected-warning {{invalid invocation of method '~DestructorTester' on a temporary object while it is in the 'unconsumed' state}}
139 }
140 }
141
142 void testTempValue() {
143 *ConsumableClass<int>(); // expected-warning {{invalid invocation of method 'operator*' on a temporary object while it is in the 'consumed' state}}
144 }
145
146 void testSimpleRValueRefs() {
147 ConsumableClass<int> var0;
148 ConsumableClass<int> var1(42);
149
150 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
151 *var1;
152
153 var0 = static_cast<ConsumableClass<int>&&>(var1);
154
155 *var0;
156 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
157 }
158
159 void testIfStmt() {
160 ConsumableClass<int> var;
161
162 if (var.isValid()) {
163 *var;
164 } else {
165 *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}}
166 }
167
168 if (!var.isValid()) {
169 *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}}
170 } else {
171 *var;
172 }
173
174 if (var) {
175 // Empty
176 } else {
177 *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}}
178 }
179
180 if (var != nullptr) {
181 // Empty
182 } else {
183 *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}}
184 }
185
186 if (var == nullptr) {
187 *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}}
188 } else {
189 // Empty
190 }
191 }
192
193 void testComplexConditionals0() {
194 ConsumableClass<int> var0, var1, var2;
195
196 if (var0 && var1) {
197 *var0;
198 *var1;
199
200 } else {
201 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
202 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
203 }
204
205 if (var0 || var1) {
206 *var0;
207 *var1;
208
209 } else {
210 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
211 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
212 }
213
214 if (var0 && !var1) {
215 *var0;
216 *var1;
217
218 } else {
219 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
220 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
221 }
222
223 if (var0 || !var1) {
224 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
225 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
226
227 } else {
228 *var0;
229 *var1;
230 }
231
232 if (!var0 && !var1) {
233 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
234 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
235
236 } else {
237 *var0;
238 *var1;
239 }
240
241 if (!var0 || !var1) {
242 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
243 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
244
245 } else {
246 *var0;
247 *var1;
248 }
249
250 if (!(var0 && var1)) {
251 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
252 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
253
254 } else {
255 *var0;
256 *var1;
257 }
258
259 if (!(var0 || var1)) {
260 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
261 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
262
263 } else {
264 *var0;
265 *var1;
266 }
267
268 if (var0 && var1 && var2) {
269 *var0;
270 *var1;
271 *var2;
272
273 } else {
274 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
275 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
276 *var2; // expected-warning {{invalid invocation of method 'operator*' on object 'var2' while it is in the 'consumed' state}}
277 }
278
279 #if 0
280 // FIXME: Get this test to pass.
281 if (var0 || var1 || var2) {
282 *var0;
283 *var1;
284 *var2;
285
286 } else {
287 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
288 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
289 *var2; // expected-warning {{invalid invocation of method 'operator*' on object 'var2' while it is in the 'consumed' state}}
290 }
291 #endif
292 }
293
294 void testComplexConditionals1() {
295 ConsumableClass<int> var0, var1, var2;
296
297 // Coerce all variables into the unknown state.
298 baf4(var0);
299 baf4(var1);
300 baf4(var2);
301
302 if (var0 && var1) {
303 *var0;
304 *var1;
305
306 } else {
307 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}}
308 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}}
309 }
310
311 if (var0 || var1) {
312 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}}
313 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}}
314
315 } else {
316 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
317 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
318 }
319
320 if (var0 && !var1) {
321 *var0;
322 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
323
324 } else {
325 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}}
326 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}}
327 }
328
329 if (var0 || !var1) {
330 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}}
331 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}}
332
333 } else {
334 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
335 *var1;
336 }
337
338 if (!var0 && !var1) {
339 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
340 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
341
342 } else {
343 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}}
344 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}}
345 }
346
347 if (!(var0 || var1)) {
348 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
349 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
350
351 } else {
352 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}}
353 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}}
354 }
355
356 if (!var0 || !var1) {
357 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}}
358 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}}
359
360 } else {
361 *var0;
362 *var1;
363 }
364
365 if (!(var0 && var1)) {
366 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}}
367 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}}
368
369 } else {
370 *var0;
371 *var1;
372 }
373
374 if (var0 && var1 && var2) {
375 *var0;
376 *var1;
377 *var2;
378
379 } else {
380 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}}
381 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}}
382 *var2; // expected-warning {{invalid invocation of method 'operator*' on object 'var2' while it is in the 'unknown' state}}
383 }
384
385 #if 0
386 // FIXME: Get this test to pass.
387 if (var0 || var1 || var2) {
388 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}}
389 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}}
390 *var2; // expected-warning {{invalid invocation of method 'operator*' on object 'var2' while it is in the 'unknown' state}}
391
392 } else {
393 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
394 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
395 *var2; // expected-warning {{invalid invocation of method 'operator*' on object 'var2' while it is in the 'consumed' state}}
396 }
397 #endif
398 }
399
400 void testStateChangeInBranch() {
401 ConsumableClass<int> var;
402
403 // Make var enter the 'unknown' state.
404 baf4(var);
405
406 if (!var) {
407 var = ConsumableClass<int>(42);
408 }
409
410 *var;
411 }
412
413 void testFunctionParam(ConsumableClass<int> param) {
414
415 if (param.isValid()) {
416 *param;
417 } else {
418 *param;
419 }
420
421 param = nullptr;
422 *param; // expected-warning {{invocation of method 'operator*' on object 'param' while it is in the 'consumed' state}}
423 }
424
425 void 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'}}
426
427 if (cond) {
428 Param.consume();
429 return; // expected-warning {{parameter 'Param' not in expected state when the function returns: expected 'unconsumed', observed 'consumed'}}
430 }
431
432 Param.consume();
433 }
434
435 void testRvalueRefParamReturnTypestateCallee(ConsumableClass<int> &&Param RETURN_TYPESTATE(unconsumed)) {
436 Param.unconsume();
437 }
438
439 void testParamReturnTypestateCaller() {
440 ConsumableClass<int> var;
441
442 testParamReturnTypestateCallee(true, var);
443 testRvalueRefParamReturnTypestateCallee((ConsumableClass<int> &&)var);
444
445 *var;
446 }
447
448 void testParamTypestateCallee(ConsumableClass<int> Param0 PARAM_TYPESTATE(consumed),
449 ConsumableClass<int> &Param1 PARAM_TYPESTATE(consumed)) {
450
451 *Param0; // expected-warning {{invalid invocation of method 'operator*' on object 'Param0' while it is in the 'consumed' state}}
452 *Param1; // expected-warning {{invalid invocation of method 'operator*' on object 'Param1' while it is in the 'consumed' state}}
453 }
454
455 void testParamTypestateCaller() {
456 ConsumableClass<int> Var0, Var1(42);
457
458 testParamTypestateCallee(Var0, Var1); // expected-warning {{argument not in expected state; expected 'consumed', observed 'unconsumed'}}
459 }
460
461
462 void consumeFunc(ConsumableClass<int> P PARAM_TYPESTATE(unconsumed));
463 struct ParamTest {
464 static void consumeFuncStatic(ConsumableClass<int> P PARAM_TYPESTATE(unconsumed));
465 void consumeFuncMeth(ConsumableClass<int> P PARAM_TYPESTATE(unconsumed));
466 void operator<<(ConsumableClass<int> P PARAM_TYPESTATE(unconsumed));
467 };
468
469 void operator>>(ParamTest& pt, ConsumableClass<int> P PARAM_TYPESTATE(unconsumed));
470
471
472 void testFunctionParams() {
473 // Make sure we handle the different kinds of functions.
474 ConsumableClass<int> P;
475
476 consumeFunc(P); // expected-warning {{argument not in expected state; expected 'unconsumed', observed 'consumed'}}
477 ParamTest::consumeFuncStatic(P); // expected-warning {{argument not in expected state; expected 'unconsumed', observed 'consumed'}}
478 ParamTest pt;
479 pt.consumeFuncMeth(P); // expected-warning {{argument not in expected state; expected 'unconsumed', observed 'consumed'}}
480 pt << P; // expected-warning {{argument not in expected state; expected 'unconsumed', observed 'consumed'}}
481 pt >> P; // expected-warning {{argument not in expected state; expected 'unconsumed', observed 'consumed'}}
482 }
483
484 void baf3(ConsumableClass<int> var) {
485 *var;
486 }
487
488 void baf4(ConsumableClass<int> &var) {
489 *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'unknown' state}}
490 }
491
492 void baf6(ConsumableClass<int> &&var) {
493 *var;
494 }
495
496 void testCallingConventions() {
497 ConsumableClass<int> var(42);
498
499 baf0(var);
500 *var;
501
502 baf1(var);
503 *var;
504
505 baf2(&var);
506 *var;
507
508 baf3(var);
509 *var;
510
511 baf4(var);
512 *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'unknown' state}}
513
514 var = ConsumableClass<int>(42);
515 baf5(&var);
516 *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'unknown' state}}
517
518 var = ConsumableClass<int>(42);
519 baf6(static_cast<ConsumableClass<int>&&>(var));
520 *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}}
521 }
522
523 void testConstAndNonConstMemberFunctions() {
524 ConsumableClass<int> var(42);
525
526 var.constCall();
527 *var;
528
529 var.nonconstCall();
530 *var;
531 }
532
533 void testFunctionParam0(ConsumableClass<int> param) {
534 *param;
535 }
536
537 void testFunctionParam1(ConsumableClass<int> ¶m) {
538 *param; // expected-warning {{invalid invocation of method 'operator*' on object 'param' while it is in the 'unknown' state}}
539 }
540
541 void testReturnStates() {
542 ConsumableClass<int> var;
543
544 var = returnsUnconsumed();
545 *var;
546
547 var = returnsConsumed();
548 *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}}
549 }
550
551 void testCallableWhen() {
552 ConsumableClass<int> var(42);
553
554 *var;
555
556 baf4(var);
557
558 var.callableWhenUnknown();
559 }
560
561 void testMoveAsignmentish() {
562 ConsumableClass<int> var0;
563 ConsumableClass<long> var1(42);
564
565 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
566 *var1;
567
568 var0 = static_cast<ConsumableClass<long>&&>(var1);
569
570 *var0;
571 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
572
573 var1 = ConsumableClass<long>(42);
574 var1 = nullptr;
575 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
576 }
577
578 void testConditionalMerge() {
579 ConsumableClass<int> var;
580
581 if (var.isValid()) {
582 // Empty
583 }
584
585 *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}}
586
587 if (var.isValid()) {
588 // Empty
589 } else {
590 // Empty
591 }
592
593 *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}}
594 }
595
596 void testSetTypestate() {
597 ConsumableClass<int> var(42);
598
599 *var;
600
601 var.consume();
602
603 *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}}
604
605 var.unconsume();
606
607 *var;
608 }
609
610 void testConsumes0() {
611 ConsumableClass<int> var(nullptr);
612
613 *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}}
614 }
615
616 void testConsumes1() {
617 ConsumableClass<int> var(42);
618
619 var.unconsumedCall();
620 var(6);
621
622 var.unconsumedCall(); // expected-warning {{invalid invocation of method 'unconsumedCall' on object 'var' while it is in the 'consumed' state}}
623 }
624
625 void testUnreachableBlock() {
626 ConsumableClass<int> var(42);
627
628 if (var) {
629 *var;
630 } else {
631 *var;
632 }
633
634 *var;
635 }
636
637
638 void testForLoop1() {
639 ConsumableClass<int> var0, var1(42);
640
641 for (int i = 0; i < 10; ++i) { // expected-warning {{state of variable 'var1' must match at the entry and exit of loop}}
642 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
643
644 *var1;
645 var1.consume();
646 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
647 }
648
649 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
650 }
651
652 void testWhileLoop1() {
653 int i = 10;
654
655 ConsumableClass<int> var0, var1(42);
656
657 while (i-- > 0) { // expected-warning {{state of variable 'var1' must match at the entry and exit of loop}}
658 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
659
660 *var1;
661 var1.consume();
662 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
663 }
664
665 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
666 }
667
668 // Tests if state information is correctly discarded for certain shapes of CFGs.
669 void testSwitchGOTO(void) {
670 int a;
671
672 LABEL0:
673 switch (a)
674 case 0:
675 goto LABEL0;
676
677 goto LABEL0;
678 }
679
680 typedef const int*& IntegerPointerReference;
681 void testIsRValueRefishAndCanonicalType(IntegerPointerReference a) {}
682
683 namespace ContinueICETest {
684
685 bool cond1();
686 bool cond2();
687
688 static void foo1() {
689 while (cond1()) {
690 if (cond2())
691 continue;
692 }
693 }
694
695 static void foo2() {
696 while (true) {
697 if (false)
698 continue;
699 }
700 }
701
702 class runtime_error
703 {
704 public:
705 virtual ~runtime_error();
706 };
707
708 void read(bool sf) {
709 while (sf) {
710 if(sf) throw runtime_error();
711 }
712 }
713
714 } // end namespace ContinueICETest
715
716
717 namespace StatusUseCaseTests {
718
719 class CONSUMABLE(unconsumed)
720 __attribute__((consumable_auto_cast_state))
721 __attribute__((consumable_set_state_on_read))
722 Status {
723 int code;
724
725 public:
726 static Status OK;
727
728 Status() RETURN_TYPESTATE(consumed);
729 Status(int c) RETURN_TYPESTATE(unconsumed);
730
731 Status(const Status &other);
732 Status(Status &&other);
733
734 Status& operator=(const Status &other) CALLABLE_WHEN("unknown", "consumed");
735 Status& operator=(Status &&other) CALLABLE_WHEN("unknown", "consumed");
736
737 bool operator==(const Status &other) const SET_TYPESTATE(consumed);
738
739 bool check() const SET_TYPESTATE(consumed);
740 void ignore() const SET_TYPESTATE(consumed);
741 // Status& markAsChecked() { return *this; }
742
743 void clear() CALLABLE_WHEN("unknown", "consumed") SET_TYPESTATE(consumed);
744
745 ~Status() CALLABLE_WHEN("unknown", "consumed");
746
747 operator bool() const; // Will not consume the object.
748 };
749
750
751 bool cond();
752 Status doSomething();
753 void handleStatus(const Status& s RETURN_TYPESTATE(consumed));
754 void handleStatusRef(Status& s);
755 void handleStatusPtr(Status* s);
756 void handleStatusUnmarked(const Status& s);
757
758 void log(const char* msg);
759 void fail() __attribute__((noreturn));
760 void checkStat(const Status& s);
761
762
763 void testSimpleTemporaries0() {
764 doSomething(); // expected-warning {{invalid invocation of method '~Status' on a temporary object while it is in the 'unconsumed' state}}
765 }
766
767 void testSimpleTemporaries1() {
768 doSomething().ignore();
769 }
770
771 void testSimpleTemporaries2() {
772 handleStatus(doSomething());
773 }
774
775 void testSimpleTemporaries3() {
776 Status s = doSomething();
777 } // expected-warning {{invalid invocation of method '~Status' on object 's' while it is in the 'unconsumed' state}}
778
779 void testTemporariesWithControlFlow(bool a) {
780 bool b = false || doSomething(); // expected-warning {{invalid invocation of method '~Status' on a temporary object while it is in the 'unconsumed' state}}
781 }
782
783 Status testSimpleTemporariesReturn0() {
784 return doSomething();
785 }
786
787 Status testSimpleTemporariesReturn1() {
788 Status s = doSomething();
789 return s;
790 }
791
792 void testSimpleTemporaries4() {
793 Status s = doSomething();
794 s.check();
795 }
796
797 void testSimpleTemporaries5() {
798 Status s = doSomething();
799 s.clear(); // expected-warning {{invalid invocation of method 'clear' on object 's' while it is in the 'unconsumed' state}}
800 }
801
802 void testSimpleTemporaries6() {
803 Status s1 = doSomething();
804 handleStatus(s1);
805
806 Status s2 = doSomething();
807 handleStatusRef(s2);
808
809 Status s3 = doSomething();
810 handleStatusPtr(&s3);
811
812 Status s4 = doSomething();
813 handleStatusUnmarked(s4);
814 }
815
816 void testSimpleTemporaries7() {
817 Status s;
818 s = doSomething();
819 } // expected-warning {{invalid invocation of method '~Status' on object 's' while it is in the 'unconsumed' state}}
820
821 void testTemporariesWithConditionals0() {
822 int a;
823
824 Status s = doSomething();
825 if (cond()) a = 0;
826 else a = 1;
827 } // expected-warning {{invalid invocation of method '~Status' on object 's' while it is in the 'unconsumed' state}}
828
829 void testTemporariesWithConditionals1() {
830 int a;
831
832 Status s = doSomething();
833 if (cond()) a = 0;
834 else a = 1;
835 s.ignore();
836 }
837
838 void testTemporariesWithConditionals2() {
839 int a;
840
841 Status s = doSomething();
842 s.ignore();
843 if (cond()) a = 0;
844 else a = 1;
845 }
846
847 void testTemporariesWithConditionals3() {
848 Status s = doSomething();
849 if (cond()) {
850 s.check();
851 }
852 }
853
854 void testTemporariesAndConstructors0() {
855 Status s(doSomething()); // Test the copy constructor.
856 s.check();
857 }
858
859 void testTemporariesAndConstructors1F() {
860 Status s1 = doSomething(); // Test the copy constructor.
861 Status s2 = s1;
862 } // expected-warning {{invalid invocation of method '~Status' on object 's2' while it is in the 'unconsumed' state}}
863
864 void testTemporariesAndConstructors1S() {
865 Status s1 = doSomething(); // Test the copy constructor.
866 Status s2(s1);
867 s2.check();
868 }
869
870 void testTemporariesAndConstructors2F() {
871 // Test the move constructor.
872 Status s1 = doSomething();
873 Status s2 = static_cast<Status&&>(s1);
874 } // expected-warning {{invalid invocation of method '~Status' on object 's2' while it is in the 'unconsumed' state}}
875
876 void testTemporariesAndConstructors2S() {
877 // Test the move constructor.
878 Status s1 = doSomething();
879 Status s2 = static_cast<Status&&>(s1);
880 s2.check();
881 }
882
883 void testTemporariesAndOperators0F() {
884 // Test the assignment operator.
885 Status s1 = doSomething();
886 Status s2;
887 s2 = s1;
888 } // expected-warning {{invalid invocation of method '~Status' on object 's2' while it is in the 'unconsumed' state}}
889
890 void testTemporariesAndOperators0S() {
891 // Test the assignment operator.
892 Status s1 = doSomething();
893 Status s2;
894 s2 = s1;
895 s2.check();
896 }
897
898 void testTemporariesAndOperators1F() {
899 // Test the move assignment operator.
900 Status s1 = doSomething();
901 Status s2;
902 s2 = static_cast<Status&&>(s1);
903 } // expected-warning {{invalid invocation of method '~Status' on object 's2' while it is in the 'unconsumed' state}}
904
905 void testTemporariesAndOperators1S() {
906 // Test the move assignment operator.
907 Status s1 = doSomething();
908 Status s2;
909 s2 = static_cast<Status&&>(s1);
910 s2.check();
911 }
912
913 void testTemporariesAndOperators2() {
914 Status s1 = doSomething();
915 Status s2 = doSomething();
916 s1 = s2; // expected-warning {{invalid invocation of method 'operator=' on object 's1' while it is in the 'unconsumed' state}}
917 s1.check();
918 s2.check();
919 }
920
921 Status testReturnAutocast() {
922 Status s = doSomething();
923 s.check(); // consume s
924 return s; // should autocast back to unconsumed
925 }
926
927
928 namespace TestParens {
929
930 void test3() {
931 checkStat((doSomething()));
932 }
933
934 void test4() {
935 Status s = (doSomething());
936 s.check();
937 }
938
939 void test5() {
940 (doSomething()).check();
941 }
942
943 void test6() {
944 if ((doSomething()) == Status::OK)
945 return;
946 }
947
948 } // end namespace TestParens
949
950 } // end namespace InitializerAssertionFailTest
951
952
953 namespace std {
954 void move();
955 template<class T>
956 void move(T&&);
957
958 namespace __1 {
959 void move();
960 template<class T>
961 void move(T&&);
962 }
963 }
964
965 namespace PR18260 {
966 class X {
967 public:
968 void move();
969 } x;
970
971 void test() {
972 x.move();
973 std::move();
974 std::move(x);
975 std::__1::move();
976 std::__1::move(x);
977 }
978 } // end namespace PR18260
979
980