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
12typedef decltype(nullptr) nullptr_t;
13
14template <typename T>
15class CONSUMABLE(unconsumed) ConsumableClass {
16  T var;
17
18public:
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
52class CONSUMABLE(unconsumed) DestructorTester {
53public:
54  DestructorTester();
55  DestructorTester(int);
56
57  void operator*() CALLABLE_WHEN("unconsumed");
58
59  ~DestructorTester() CALLABLE_WHEN("consumed");
60};
61
62void baf0(const ConsumableClass<int>  var);
63void baf1(const ConsumableClass<int> &var);
64void baf2(const ConsumableClass<int> *var);
65
66void baf3(ConsumableClass<int>   var);
67void baf4(ConsumableClass<int>  &var);
68void baf5(ConsumableClass<int>  *var);
69void baf6(ConsumableClass<int> &&var);
70
71ConsumableClass<int> returnsUnconsumed() {
72  return ConsumableClass<int>(); // expected-warning {{return value not in expected state; expected 'unconsumed', observed 'consumed'}}
73}
74
75ConsumableClass<int> returnsConsumed() RETURN_TYPESTATE(consumed);
76ConsumableClass<int> returnsConsumed() {
77  return ConsumableClass<int>();
78}
79
80ConsumableClass<int> returnsUnknown() RETURN_TYPESTATE(unknown);
81
82void 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
110void 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
123void testTempValue() {
124  *ConsumableClass<int>(); // expected-warning {{invalid invocation of method 'operator*' on a temporary object while it is in the 'consumed' state}}
125}
126
127void 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
140void 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
174void 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
275void 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
381void 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
394void 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
406void 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
416void testParamReturnTypestateCaller() {
417  ConsumableClass<int> var;
418
419  testParamReturnTypestateCallee(true, var);
420
421  *var;
422}
423
424void 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
431void 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
438void consumeFunc(ConsumableClass<int> P PARAM_TYPESTATE(unconsumed));
439struct 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
445void operator>>(ParamTest& pt, ConsumableClass<int> P PARAM_TYPESTATE(unconsumed));
446
447
448void 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
460void baf3(ConsumableClass<int> var) {
461  *var;
462}
463
464void 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
468void baf6(ConsumableClass<int> &&var) {
469  *var;
470}
471
472void 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
496void testConstAndNonConstMemberFunctions() {
497  ConsumableClass<int> var(42);
498
499  var.constCall();
500  *var;
501
502  var.nonconstCall();
503  *var;
504}
505
506void testFunctionParam0(ConsumableClass<int> param) {
507  *param;
508}
509
510void 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
514void 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
524void testCallableWhen() {
525  ConsumableClass<int> var(42);
526
527  *var;
528
529  baf4(var);
530
531  var.callableWhenUnknown();
532}
533
534void 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
551void 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
569void 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
583void 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
589void 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
598void testUnreachableBlock() {
599  ConsumableClass<int> var(42);
600
601  if (var) {
602    *var;
603  } else {
604    *var;
605  }
606
607  *var;
608}
609
610
611void 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
625void 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
641typedef const int*& IntegerPointerReference;
642void testIsRValueRefishAndCanonicalType(IntegerPointerReference a) {}
643
644namespace ContinueICETest {
645
646bool cond1();
647bool cond2();
648
649static void foo1() {
650  while (cond1()) {
651    if (cond2())
652      continue;
653  }
654}
655
656static void foo2() {
657  while (true) {
658    if (false)
659      continue;
660  }
661}
662
663class runtime_error
664{
665public:
666  virtual ~runtime_error();
667};
668
669void read(bool sf) {
670    while (sf) {
671        if(sf) throw runtime_error();
672    }
673}
674
675} // end namespace ContinueICETest
676
677
678namespace StatusUseCaseTests {
679
680class CONSUMABLE(unconsumed)
681      __attribute__((consumable_auto_cast_state))
682      __attribute__((consumable_set_state_on_read))
683    Status {
684  int code;
685
686public:
687  static Status OK;
688
689  Status() RETURN_TYPESTATE(consumed);
690  Status(int c) RETURN_TYPESTATE(unconsumed);
691
692  Status(const Status &other);
693  Status(Status &&other);
694
695  Status& operator=(const Status &other) CALLABLE_WHEN("unknown", "consumed");
696  Status& operator=(Status &&other) CALLABLE_WHEN("unknown", "consumed");
697
698  bool operator==(const Status &other) const SET_TYPESTATE(consumed);
699
700  bool check()  const SET_TYPESTATE(consumed);
701  void ignore() const SET_TYPESTATE(consumed);
702  // Status& markAsChecked() { return *this; }
703
704  void clear() CALLABLE_WHEN("unknown", "consumed") SET_TYPESTATE(consumed);
705
706  ~Status() CALLABLE_WHEN("unknown", "consumed");
707
708  operator bool() const; // Will not consume the object.
709};
710
711
712bool   cond();
713Status doSomething();
714void   handleStatus(const Status& s RETURN_TYPESTATE(consumed));
715void   handleStatusRef(Status& s);
716void   handleStatusPtr(Status* s);
717void   handleStatusUnmarked(const Status& s);
718
719void   log(const char* msg);
720void   fail() __attribute__((noreturn));
721void   checkStat(const Status& s);
722
723
724void testSimpleTemporaries0() {
725  doSomething(); // expected-warning {{invalid invocation of method '~Status' on a temporary object while it is in the 'unconsumed' state}}
726}
727
728void testSimpleTemporaries1() {
729  doSomething().ignore();
730}
731
732void testSimpleTemporaries2() {
733  handleStatus(doSomething());
734}
735
736void testSimpleTemporaries3() {
737  Status s = doSomething();
738}  // expected-warning {{invalid invocation of method '~Status' on object 's' while it is in the 'unconsumed' state}}
739
740void testTemporariesWithControlFlow(bool a) {
741  bool b = false || doSomething(); // expected-warning {{invalid invocation of method '~Status' on a temporary object while it is in the 'unconsumed' state}}
742}
743
744Status testSimpleTemporariesReturn0() {
745  return doSomething();
746}
747
748Status testSimpleTemporariesReturn1() {
749  Status s = doSomething();
750  return s;
751}
752
753void testSimpleTemporaries4() {
754  Status s = doSomething();
755  s.check();
756}
757
758void testSimpleTemporaries5() {
759  Status s = doSomething();
760  s.clear(); // expected-warning {{invalid invocation of method 'clear' on object 's' while it is in the 'unconsumed' state}}
761}
762
763void testSimpleTemporaries6() {
764  Status s1 = doSomething();
765  handleStatus(s1);
766
767  Status s2 = doSomething();
768  handleStatusRef(s2);
769
770  Status s3 = doSomething();
771  handleStatusPtr(&s3);
772
773  Status s4 = doSomething();
774  handleStatusUnmarked(s4);
775}
776
777void testSimpleTemporaries7() {
778  Status s;
779  s = doSomething();
780}  // expected-warning {{invalid invocation of method '~Status' on object 's' while it is in the 'unconsumed' state}}
781
782void testTemporariesWithConditionals0() {
783  int a;
784
785  Status s = doSomething();
786  if (cond()) a = 0;
787  else        a = 1;
788} // expected-warning {{invalid invocation of method '~Status' on object 's' while it is in the 'unconsumed' state}}
789
790void testTemporariesWithConditionals1() {
791  int a;
792
793  Status s = doSomething();
794  if (cond()) a = 0;
795  else        a = 1;
796  s.ignore();
797}
798
799void testTemporariesWithConditionals2() {
800  int a;
801
802  Status s = doSomething();
803  s.ignore();
804  if (cond()) a = 0;
805  else        a = 1;
806}
807
808void testTemporariesWithConditionals3() {
809  Status s = doSomething();
810  if (cond()) {
811    s.check();
812  }
813}
814
815void testTemporariesAndConstructors0() {
816  Status s(doSomething());    // Test the copy constructor.
817  s.check();
818}
819
820void testTemporariesAndConstructors1F() {
821  Status s1 = doSomething();  // Test the copy constructor.
822  Status s2 = s1;
823} // expected-warning {{invalid invocation of method '~Status' on object 's2' while it is in the 'unconsumed' state}}
824
825void testTemporariesAndConstructors1S() {
826  Status s1 = doSomething();  // Test the copy constructor.
827  Status s2(s1);
828  s2.check();
829}
830
831void testTemporariesAndConstructors2F() {
832  // Test the move constructor.
833  Status s1 = doSomething();
834  Status s2 = static_cast<Status&&>(s1);
835} // expected-warning {{invalid invocation of method '~Status' on object 's2' while it is in the 'unconsumed' state}}
836
837void testTemporariesAndConstructors2S() {
838  // Test the move constructor.
839  Status s1 = doSomething();
840  Status s2 = static_cast<Status&&>(s1);
841  s2.check();
842}
843
844void testTemporariesAndOperators0F() {
845  // Test the assignment operator.
846  Status s1 = doSomething();
847  Status s2;
848  s2 = s1;
849} // expected-warning {{invalid invocation of method '~Status' on object 's2' while it is in the 'unconsumed' state}}
850
851void testTemporariesAndOperators0S() {
852  // Test the assignment operator.
853  Status s1 = doSomething();
854  Status s2;
855  s2 = s1;
856  s2.check();
857}
858
859void testTemporariesAndOperators1F() {
860  // Test the move assignment operator.
861  Status s1 = doSomething();
862  Status s2;
863  s2 = static_cast<Status&&>(s1);
864} // expected-warning {{invalid invocation of method '~Status' on object 's2' while it is in the 'unconsumed' state}}
865
866void testTemporariesAndOperators1S() {
867  // Test the move assignment operator.
868  Status s1 = doSomething();
869  Status s2;
870  s2 = static_cast<Status&&>(s1);
871  s2.check();
872}
873
874void testTemporariesAndOperators2() {
875  Status s1 = doSomething();
876  Status s2 = doSomething();
877  s1 = s2; // expected-warning {{invalid invocation of method 'operator=' on object 's1' while it is in the 'unconsumed' state}}
878  s1.check();
879  s2.check();
880}
881
882Status testReturnAutocast() {
883  Status s = doSomething();
884  s.check();  // consume s
885  return s;   // should autocast back to unconsumed
886}
887
888
889namespace TestParens {
890
891void test3() {
892  checkStat((doSomething()));
893}
894
895void test4() {
896  Status s = (doSomething());
897  s.check();
898}
899
900void test5() {
901  (doSomething()).check();
902}
903
904void test6() {
905  if ((doSomething()) == Status::OK)
906    return;
907}
908
909} // end namespace TestParens
910
911} // end namespace InitializerAssertionFailTest
912
913
914namespace std {
915  void move();
916  template<class T>
917  void move(T&&);
918
919  namespace __1 {
920    void move();
921    template<class T>
922    void move(T&&);
923  }
924}
925
926namespace PR18260 {
927  class X {
928    public:
929      void move();
930  } x;
931
932  void test() {
933    x.move();
934    std::move();
935    std::move(x);
936    std::__1::move();
937    std::__1::move(x);
938  }
939} // end namespace PR18260
940
941