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