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