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> &param) {
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