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> ¶m) {
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