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>
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() RETURN_TYPESTATE(unconsumed);
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 
86   var0 = ConsumableClass<int>();
87 
88   *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}}
90 
91   if (var0.isValid()) {
92     *var0;
93     *var1;
94 
95   } else {
96     *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
97   }
98 }
99 
100 void testDestruction() {
101   DestructorTester D0(42), D1(42);
102 
103   *D0;
104   *D1;
105 
106   DestructorTester D2;
107   *D2;
108 
109   D0.~DestructorTester(); // expected-warning {{invalid invocation of method '~DestructorTester' on object 'D0' while it is in the 'unconsumed' state}}
110 
111   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}}
114 }
115 
116 void testTempValue() {
117   *ConsumableClass<int>(); // expected-warning {{invalid invocation of method 'operator*' on a temporary object while it is in the 'consumed' state}}
118 }
119 
120 void testSimpleRValueRefs() {
121   ConsumableClass<int> var0;
122   ConsumableClass<int> var1(42);
123 
124   *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
125   *var1;
126 
127   var0 = static_cast<ConsumableClass<int>&&>(var1);
128 
129   *var0;
130   *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
131 }
132 
133 void testIfStmt() {
134   ConsumableClass<int> var;
135 
136   if (var.isValid()) {
137     *var;
138   } else {
139     *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}}
140   }
141 
142   if (!var.isValid()) {
143     *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}}
144   } else {
145     *var;
146   }
147 
148   if (var) {
149     // Empty
150   } else {
151     *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}}
152   }
153 
154   if (var != nullptr) {
155     // Empty
156   } else {
157     *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}}
158   }
159 
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   }
165 }
166 
167 void testComplexConditionals0() {
168   ConsumableClass<int> var0, var1, var2;
169 
170   if (var0 && var1) {
171     *var0;
172     *var1;
173 
174   } else {
175     *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}}
177   }
178 
179   if (var0 || var1) {
180     *var0;
181     *var1;
182 
183   } else {
184     *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}}
186   }
187 
188   if (var0 && !var1) {
189     *var0;
190     *var1;
191 
192   } else {
193     *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}}
195   }
196 
197   if (var0 || !var1) {
198     *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}}
200 
201   } else {
202     *var0;
203     *var1;
204   }
205 
206   if (!var0 && !var1) {
207     *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}}
209 
210   } else {
211     *var0;
212     *var1;
213   }
214 
215   if (!var0 || !var1) {
216     *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}}
218 
219   } else {
220     *var0;
221     *var1;
222   }
223 
224   if (!(var0 && var1)) {
225     *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}}
227 
228   } else {
229     *var0;
230     *var1;
231   }
232 
233   if (!(var0 || var1)) {
234     *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}}
236 
237   } else {
238     *var0;
239     *var1;
240   }
241 
242   if (var0 && var1 && var2) {
243     *var0;
244     *var1;
245     *var2;
246 
247   } else {
248     *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}}
251   }
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 {
261     *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 
268 void testComplexConditionals1() {
269   ConsumableClass<int> var0, var1, var2;
270 
271   // Coerce all variables into the unknown state.
272   baf4(var0);
273   baf4(var1);
274   baf4(var2);
275 
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}}
370   }
371 #endif
372 }
373 
374 void testStateChangeInBranch() {
375   ConsumableClass<int> var;
376 
377   // Make var enter the 'unknown' state.
378   baf4(var);
379 
380   if (!var) {
381     var = ConsumableClass<int>(42);
382   }
383 
384   *var;
385 }
386 
387 void testFunctionParam(ConsumableClass<int> param) {
388 
389   if (param.isValid()) {
390     *param;
391   } else {
392     *param;
393   }
394 
395   param = nullptr;
396   *param; // expected-warning {{invocation of method 'operator*' on object 'param' while it is in the 'consumed' state}}
397 }
398 
399 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'}}
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 
409 void testParamReturnTypestateCaller() {
410   ConsumableClass<int> var;
411 
412   testParamReturnTypestateCallee(true, var);
413 
414   *var;
415 }
416 
417 void 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 
424 void 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 
430 void baf3(ConsumableClass<int> var) {
431   *var;
432 }
433 
434 void 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 
438 void baf6(ConsumableClass<int> &&var) {
439   *var;
440 }
441 
442 void testCallingConventions() {
443   ConsumableClass<int> var(42);
444 
445   baf0(var);
446   *var;
447 
448   baf1(var);
449   *var;
450 
451   baf2(&var);
452   *var;
453 
454   baf4(var);
455   *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'unknown' state}}
456 
457   var = ConsumableClass<int>(42);
458   baf5(&var);
459   *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'unknown' state}}
460 
461   var = ConsumableClass<int>(42);
462   baf6(static_cast<ConsumableClass<int>&&>(var));
463   *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}}
464 }
465 
466 void testConstAndNonConstMemberFunctions() {
467   ConsumableClass<int> var(42);
468 
469   var.constCall();
470   *var;
471 
472   var.nonconstCall();
473   *var;
474 }
475 
476 void testFunctionParam0(ConsumableClass<int> param) {
477   *param;
478 }
479 
480 void testFunctionParam1(ConsumableClass<int> &param) {
481   *param; // expected-warning {{invalid invocation of method 'operator*' on object 'param' while it is in the 'unknown' state}}
482 }
483 
484 void testReturnStates() {
485   ConsumableClass<int> var;
486 
487   var = returnsUnconsumed();
488   *var;
489 
490   var = returnsConsumed();
491   *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}}
492 }
493 
494 void testCallableWhen() {
495   ConsumableClass<int> var(42);
496 
497   *var;
498 
499   baf4(var);
500 
501   var.callableWhenUnknown();
502 }
503 
504 void testMoveAsignmentish() {
505   ConsumableClass<int>  var0;
506   ConsumableClass<long> var1(42);
507 
508   *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
509   *var1;
510 
511   var0 = static_cast<ConsumableClass<long>&&>(var1);
512 
513   *var0;
514   *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
515 
516   var1 = ConsumableClass<long>(42);
517   var1 = nullptr;
518   *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
519 }
520 
521 void testConditionalMerge() {
522   ConsumableClass<int> var;
523 
524   if (var.isValid()) {
525     // Empty
526   }
527 
528   *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}}
529 
530   if (var.isValid()) {
531     // Empty
532   } else {
533     // Empty
534   }
535 
536   *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}}
537 }
538 
539 void testSetTypestate() {
540   ConsumableClass<int> var(42);
541 
542   *var;
543 
544   var.consume();
545 
546   *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}}
547 
548   var.unconsume();
549 
550   *var;
551 }
552 
553 void testConsumes0() {
554   ConsumableClass<int> var(nullptr);
555 
556   *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}}
557 }
558 
559 void testConsumes1() {
560   ConsumableClass<int> var(42);
561 
562   var.unconsumedCall();
563   var(6);
564 
565   var.unconsumedCall(); // expected-warning {{invalid invocation of method 'unconsumedCall' on object 'var' while it is in the 'consumed' state}}
566 }
567 
568 void testUnreachableBlock() {
569   ConsumableClass<int> var(42);
570 
571   if (var) {
572     *var;
573   } else {
574     *var;
575   }
576 
577   *var;
578 }
579 
580 
581 void testForLoop1() {
582   ConsumableClass<int> var0, var1(42);
583 
584   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}}
590   }
591 
592   *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
593 }
594 
595 void testWhileLoop1() {
596   int i = 10;
597 
598   ConsumableClass<int> var0, var1(42);
599 
600   while (i-- > 0) { // expected-warning {{state of variable 'var1' must match at the entry and exit of loop}}
601     *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
602 
603     *var1;
604     var1.consume();
605     *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
606   }
607 
608   *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
609 }
610 
611 typedef const int*& IntegerPointerReference;
612 void testIsRValueRefishAndCanonicalType(IntegerPointerReference a) {}
613 
614 namespace ContinueICETest {
615 
616 bool cond1();
617 bool cond2();
618 
619 static void foo1() {
620   while (cond1()) {
621     if (cond2())
622       continue;
623   }
624 }
625 
626 static void foo2() {
627   while (true) {
628     if (false)
629       continue;
630   }
631 }
632 
633 class runtime_error
634 {
635 public:
636   virtual ~runtime_error();
637 };
638 
639 void read(bool sf) {
640     while (sf) {
641         if(sf) throw runtime_error();
642     }
643 }
644 
645 } // end namespace ContinueICETest
646 
647 
648 namespace InitializerAssertionFailTest {
649 
650 class CONSUMABLE(unconsumed) Status {
651   int code;
652 
653 public:
654   Status() RETURN_TYPESTATE(consumed);
655   Status(int c) RETURN_TYPESTATE(unconsumed);
656 
657   Status(const Status &other);
658   Status(Status &&other);
659 
660   Status& operator=(const Status &other) CALLABLE_WHEN("unknown", "consumed");
661   Status& operator=(Status &&other) CALLABLE_WHEN("unknown", "consumed");
662 
663   bool check()  const SET_TYPESTATE(consumed);
664   void ignore() const SET_TYPESTATE(consumed);
665   // Status& markAsChecked() { return *this; }
666 
667   void clear() CALLABLE_WHEN("unknown", "consumed") SET_TYPESTATE(consumed);
668 
669   ~Status() CALLABLE_WHEN("unknown", "consumed");
670 };
671 
672 
673 bool   cond();
674 Status doSomething();
675 void   handleStatus(const Status& s RETURN_TYPESTATE(consumed));
676 void   handleStatusPtr(const Status* s);
677 
678 void testSimpleTemporaries0() {
679   doSomething(); // expected-warning {{invalid invocation of method '~Status' on a temporary object while it is in the 'unconsumed' state}}
680 }
681 
682 void testSimpleTemporaries1() {
683   doSomething().ignore();
684 }
685 
686 void testSimpleTemporaries2() {
687   handleStatus(doSomething());
688 }
689 
690 void testSimpleTemporaries3() {
691   Status s = doSomething();
692 }  // expected-warning {{invalid invocation of method '~Status' on object 's' while it is in the 'unconsumed' state}}
693 
694 void testSimpleTemporaries4() {
695   Status s = doSomething();
696   s.check();
697 }
698 
699 void testSimpleTemporaries5() {
700   Status s = doSomething();
701   s.clear(); // expected-warning {{invalid invocation of method 'clear' on object 's' while it is in the 'unconsumed' state}}
702 }
703 
704 void testSimpleTemporaries6() {
705   Status s = doSomething();
706   handleStatus(s);
707 }
708 
709 void testSimpleTemporaries7() {
710   Status s;
711   s = doSomething();
712 }  // expected-warning {{invalid invocation of method '~Status' on object 's' while it is in the 'unconsumed' state}}
713 
714 void testTemporariesWithConditionals0() {
715   int a;
716 
717   Status s = doSomething();
718   if (cond()) a = 0;
719   else        a = 1;
720 } // expected-warning {{invalid invocation of method '~Status' on object 's' while it is in the 'unconsumed' state}}
721 
722 void testTemporariesWithConditionals1() {
723   int a;
724 
725   Status s = doSomething();
726   if (cond()) a = 0;
727   else        a = 1;
728   s.ignore();
729 }
730 
731 void testTemporariesWithConditionals2() {
732   int a;
733 
734   Status s = doSomething();
735   s.ignore();
736   if (cond()) a = 0;
737   else        a = 1;
738 }
739 
740 void testTemporariesWithConditionals3() {
741   Status s = doSomething();
742   if (cond()) {
743     s.check();
744   }
745 }
746 
747 void testTemporariesAndConstructors0() {
748   Status s(doSomething());
749   s.check();
750 }
751 
752 void testTemporariesAndConstructors1() {
753   // Test the copy constructor.
754 
755   Status s1 = doSomething();
756   Status s2(s1);
757   s2.check();
758 }  // expected-warning {{invalid invocation of method '~Status' on object 's1' while it is in the 'unconsumed' state}}
759 
760 void testTemporariesAndConstructors2() {
761   // Test the move constructor.
762 
763   Status s1 = doSomething();
764   Status s2(static_cast<Status&&>(s1));
765   s2.check();
766 }
767 
768 void testTemporariesAndOperators0() {
769   // Test the assignment operator.
770 
771   Status s1 = doSomething();
772   Status s2;
773   s2 = s1;
774   s2.check();
775 } // expected-warning {{invalid invocation of method '~Status' on object 's1' while it is in the 'unconsumed' state}}
776 
777 void testTemporariesAndOperators1() {
778   // Test the move assignment operator.
779 
780   Status s1 = doSomething();
781   Status s2;
782   s2 = static_cast<Status&&>(s1);
783   s2.check();
784 }
785 
786 void testTemporariesAndOperators2() {
787   Status s1 = doSomething();
788   Status s2 = doSomething();
789   s1 = s2; // expected-warning {{invalid invocation of method 'operator=' on object 's1' while it is in the 'unconsumed' state}}
790   s1.check();
791   s2.check();
792 }
793 
794 } // end namespace InitializerAssertionFailTest
795 
796