blob: 0a6aed61862654d5426c55d298d57f32685ea21f [file] [log] [blame]
DeLesley Hutchins9cd5d402013-10-17 22:21:03 +00001// RUN: %clang_cc1 -fsyntax-only -verify -Wconsumed -fcxx-exceptions -std=c++11 %s
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +00002
DeLesley Hutchins66540852013-10-04 21:28:06 +00003// TODO: Switch to using macros for the expected warnings.
4
5#define CALLABLE_WHEN(...) __attribute__ ((callable_when(__VA_ARGS__)))
6#define CONSUMABLE(state) __attribute__ ((consumable(state)))
DeLesley Hutchinsd4f0e192013-10-17 23:23:53 +00007#define PARAM_TYPESTATE(state) __attribute__ ((param_typestate(state)))
DeLesley Hutchins66540852013-10-04 21:28:06 +00008#define RETURN_TYPESTATE(state) __attribute__ ((return_typestate(state)))
DeLesley Hutchinsd4f0e192013-10-17 23:23:53 +00009#define SET_TYPESTATE(state) __attribute__ ((set_typestate(state)))
Chris Wailes0e429f12013-10-29 20:28:41 +000010#define TEST_TYPESTATE(state) __attribute__ ((test_typestate(state)))
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +000011
12typedef decltype(nullptr) nullptr_t;
13
14template <typename T>
David Blaikiea33ab602013-09-06 01:28:43 +000015class CONSUMABLE(unconsumed) ConsumableClass {
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +000016 T var;
17
DeLesley Hutchins627c7f92013-10-11 21:55:33 +000018public:
DeLesley Hutchinsb7dc1f52013-08-29 17:26:57 +000019 ConsumableClass();
DeLesley Hutchins0e8534e2013-09-03 20:11:38 +000020 ConsumableClass(nullptr_t p) RETURN_TYPESTATE(consumed);
21 ConsumableClass(T val) RETURN_TYPESTATE(unconsumed);
David Blaikiea33ab602013-09-06 01:28:43 +000022 ConsumableClass(ConsumableClass<T> &other);
23 ConsumableClass(ConsumableClass<T> &&other);
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +000024
DeLesley Hutchins9e8bd1d2013-08-23 18:40:39 +000025 ConsumableClass<T>& operator=(ConsumableClass<T> &other);
26 ConsumableClass<T>& operator=(ConsumableClass<T> &&other);
DeLesley Hutchinsf30e1942013-10-11 23:03:26 +000027 ConsumableClass<T>& operator=(nullptr_t) SET_TYPESTATE(consumed);
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +000028
29 template <typename U>
DeLesley Hutchins9e8bd1d2013-08-23 18:40:39 +000030 ConsumableClass<T>& operator=(ConsumableClass<U> &other);
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +000031
32 template <typename U>
DeLesley Hutchins9e8bd1d2013-08-23 18:40:39 +000033 ConsumableClass<T>& operator=(ConsumableClass<U> &&other);
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +000034
DeLesley Hutchinsf30e1942013-10-11 23:03:26 +000035 void operator()(int a) SET_TYPESTATE(consumed);
DeLesley Hutchins66540852013-10-04 21:28:06 +000036 void operator*() const CALLABLE_WHEN("unconsumed");
37 void unconsumedCall() const CALLABLE_WHEN("unconsumed");
38 void callableWhenUnknown() const CALLABLE_WHEN("unconsumed", "unknown");
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +000039
Chris Wailes0e429f12013-10-29 20:28:41 +000040 bool isValid() const TEST_TYPESTATE(unconsumed);
41 operator bool() const TEST_TYPESTATE(unconsumed);
42 bool operator!=(nullptr_t) const TEST_TYPESTATE(unconsumed);
43 bool operator==(nullptr_t) const TEST_TYPESTATE(consumed);
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +000044
DeLesley Hutchinsb7dc1f52013-08-29 17:26:57 +000045 void constCall() const;
46 void nonconstCall();
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +000047
DeLesley Hutchinsf30e1942013-10-11 23:03:26 +000048 void consume() SET_TYPESTATE(consumed);
49 void unconsume() SET_TYPESTATE(unconsumed);
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +000050};
51
DeLesley Hutchins627c7f92013-10-11 21:55:33 +000052class CONSUMABLE(unconsumed) DestructorTester {
53public:
Stephen Hines651f13c2014-04-23 16:59:28 -070054 DestructorTester();
DeLesley Hutchins627c7f92013-10-11 21:55:33 +000055 DestructorTester(int);
56
DeLesley Hutchinsc5cdafc2013-10-18 18:36:21 +000057 void operator*() CALLABLE_WHEN("unconsumed");
DeLesley Hutchins627c7f92013-10-11 21:55:33 +000058
59 ~DestructorTester() CALLABLE_WHEN("consumed");
60};
61
DeLesley Hutchins9e8bd1d2013-08-23 18:40:39 +000062void baf0(const ConsumableClass<int> var);
63void baf1(const ConsumableClass<int> &var);
64void baf2(const ConsumableClass<int> *var);
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +000065
DeLesley Hutchinsbe63ab62013-10-18 19:25:18 +000066void baf3(ConsumableClass<int> var);
67void baf4(ConsumableClass<int> &var);
68void baf5(ConsumableClass<int> *var);
69void baf6(ConsumableClass<int> &&var);
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +000070
DeLesley Hutchins0e8534e2013-09-03 20:11:38 +000071ConsumableClass<int> returnsUnconsumed() {
72 return ConsumableClass<int>(); // expected-warning {{return value not in expected state; expected 'unconsumed', observed 'consumed'}}
73}
74
75ConsumableClass<int> returnsConsumed() RETURN_TYPESTATE(consumed);
76ConsumableClass<int> returnsConsumed() {
77 return ConsumableClass<int>();
78}
79
DeLesley Hutchins66540852013-10-04 21:28:06 +000080ConsumableClass<int> returnsUnknown() RETURN_TYPESTATE(unknown);
81
DeLesley Hutchinsb7dc1f52013-08-29 17:26:57 +000082void testInitialization() {
DeLesley Hutchins9e8bd1d2013-08-23 18:40:39 +000083 ConsumableClass<int> var0;
84 ConsumableClass<int> var1 = ConsumableClass<int>();
Stephen Hines651f13c2014-04-23 16:59:28 -070085 ConsumableClass<int> var2(42);
86 ConsumableClass<int> var3(var2); // copy constructor
87 ConsumableClass<int> var4(var0); // copy consumed value
88
DeLesley Hutchins66540852013-10-04 21:28:06 +000089 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
90 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
Stephen Hines651f13c2014-04-23 16:59:28 -070091 *var2;
92 *var3;
93 *var4; // expected-warning {{invalid invocation of method 'operator*' on object 'var4' while it is in the 'consumed' state}}
94
95 var0 = ConsumableClass<int>(42);
96 *var0;
97
98 var0 = var1;
99 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +0000100
101 if (var0.isValid()) {
102 *var0;
DeLesley Hutchinsb7dc1f52013-08-29 17:26:57 +0000103 *var1;
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +0000104
105 } else {
DeLesley Hutchins66540852013-10-04 21:28:06 +0000106 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +0000107 }
108}
109
DeLesley Hutchins627c7f92013-10-11 21:55:33 +0000110void testDestruction() {
Stephen Hines651f13c2014-04-23 16:59:28 -0700111 DestructorTester D0(42), D1(42), D2;
DeLesley Hutchins627c7f92013-10-11 21:55:33 +0000112
113 *D0;
114 *D1;
Stephen Hines651f13c2014-04-23 16:59:28 -0700115 *D2; // expected-warning {{invalid invocation of method 'operator*' on object 'D2' while it is in the 'consumed' state}}
DeLesley Hutchinsc5cdafc2013-10-18 18:36:21 +0000116
DeLesley Hutchins627c7f92013-10-11 21:55:33 +0000117 D0.~DestructorTester(); // expected-warning {{invalid invocation of method '~DestructorTester' on object 'D0' while it is in the 'unconsumed' state}}
118
DeLesley Hutchinsc5cdafc2013-10-18 18:36:21 +0000119 return; // expected-warning {{invalid invocation of method '~DestructorTester' on object 'D0' while it is in the 'unconsumed' state}} \
Stephen Hines651f13c2014-04-23 16:59:28 -0700120 expected-warning {{invalid invocation of method '~DestructorTester' on object 'D1' while it is in the 'unconsumed' state}}
DeLesley Hutchins627c7f92013-10-11 21:55:33 +0000121}
122
DeLesley Hutchins9e8bd1d2013-08-23 18:40:39 +0000123void testTempValue() {
DeLesley Hutchins66540852013-10-04 21:28:06 +0000124 *ConsumableClass<int>(); // expected-warning {{invalid invocation of method 'operator*' on a temporary object while it is in the 'consumed' state}}
DeLesley Hutchins5fdd2072013-08-22 20:44:47 +0000125}
126
DeLesley Hutchinsb7dc1f52013-08-29 17:26:57 +0000127void testSimpleRValueRefs() {
DeLesley Hutchins9e8bd1d2013-08-23 18:40:39 +0000128 ConsumableClass<int> var0;
129 ConsumableClass<int> var1(42);
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +0000130
DeLesley Hutchins66540852013-10-04 21:28:06 +0000131 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +0000132 *var1;
133
DeLesley Hutchins9e8bd1d2013-08-23 18:40:39 +0000134 var0 = static_cast<ConsumableClass<int>&&>(var1);
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +0000135
136 *var0;
DeLesley Hutchins66540852013-10-04 21:28:06 +0000137 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +0000138}
139
DeLesley Hutchinsb7dc1f52013-08-29 17:26:57 +0000140void testIfStmt() {
DeLesley Hutchins9e8bd1d2013-08-23 18:40:39 +0000141 ConsumableClass<int> var;
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +0000142
143 if (var.isValid()) {
DeLesley Hutchinsb7dc1f52013-08-29 17:26:57 +0000144 *var;
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +0000145 } else {
DeLesley Hutchins66540852013-10-04 21:28:06 +0000146 *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}}
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +0000147 }
148
149 if (!var.isValid()) {
DeLesley Hutchins66540852013-10-04 21:28:06 +0000150 *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}}
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +0000151 } else {
152 *var;
153 }
154
155 if (var) {
156 // Empty
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +0000157 } else {
DeLesley Hutchins66540852013-10-04 21:28:06 +0000158 *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}}
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +0000159 }
DeLesley Hutchins5fdd2072013-08-22 20:44:47 +0000160
161 if (var != nullptr) {
162 // Empty
DeLesley Hutchins5fdd2072013-08-22 20:44:47 +0000163 } else {
DeLesley Hutchins66540852013-10-04 21:28:06 +0000164 *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}}
DeLesley Hutchins5fdd2072013-08-22 20:44:47 +0000165 }
DeLesley Hutchins1bf63432013-10-11 22:30:48 +0000166
167 if (var == nullptr) {
168 *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}}
169 } else {
170 // Empty
171 }
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +0000172}
173
DeLesley Hutchins66540852013-10-04 21:28:06 +0000174void testComplexConditionals0() {
DeLesley Hutchinsb7dc1f52013-08-29 17:26:57 +0000175 ConsumableClass<int> var0, var1, var2;
176
177 if (var0 && var1) {
178 *var0;
179 *var1;
180
181 } else {
DeLesley Hutchins66540852013-10-04 21:28:06 +0000182 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
183 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
DeLesley Hutchinsb7dc1f52013-08-29 17:26:57 +0000184 }
185
186 if (var0 || var1) {
187 *var0;
188 *var1;
189
190 } else {
DeLesley Hutchins66540852013-10-04 21:28:06 +0000191 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
192 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
DeLesley Hutchinsb7dc1f52013-08-29 17:26:57 +0000193 }
194
195 if (var0 && !var1) {
196 *var0;
197 *var1;
198
199 } else {
DeLesley Hutchins66540852013-10-04 21:28:06 +0000200 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
201 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
DeLesley Hutchinsb7dc1f52013-08-29 17:26:57 +0000202 }
203
204 if (var0 || !var1) {
DeLesley Hutchins66540852013-10-04 21:28:06 +0000205 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
206 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
DeLesley Hutchinsb7dc1f52013-08-29 17:26:57 +0000207
208 } else {
209 *var0;
210 *var1;
211 }
212
213 if (!var0 && !var1) {
DeLesley Hutchins66540852013-10-04 21:28:06 +0000214 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
215 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
DeLesley Hutchinsb7dc1f52013-08-29 17:26:57 +0000216
217 } else {
218 *var0;
219 *var1;
220 }
221
222 if (!var0 || !var1) {
DeLesley Hutchins66540852013-10-04 21:28:06 +0000223 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
224 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
DeLesley Hutchinsb7dc1f52013-08-29 17:26:57 +0000225
226 } else {
227 *var0;
228 *var1;
229 }
230
231 if (!(var0 && var1)) {
DeLesley Hutchins66540852013-10-04 21:28:06 +0000232 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
233 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
DeLesley Hutchinsb7dc1f52013-08-29 17:26:57 +0000234
235 } else {
236 *var0;
237 *var1;
238 }
239
240 if (!(var0 || var1)) {
DeLesley Hutchins66540852013-10-04 21:28:06 +0000241 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
242 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
DeLesley Hutchinsb7dc1f52013-08-29 17:26:57 +0000243
244 } else {
245 *var0;
246 *var1;
247 }
248
249 if (var0 && var1 && var2) {
250 *var0;
251 *var1;
252 *var2;
253
254 } else {
DeLesley Hutchins66540852013-10-04 21:28:06 +0000255 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
256 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
257 *var2; // expected-warning {{invalid invocation of method 'operator*' on object 'var2' while it is in the 'consumed' state}}
DeLesley Hutchinsb7dc1f52013-08-29 17:26:57 +0000258 }
259
260#if 0
261 // FIXME: Get this test to pass.
262 if (var0 || var1 || var2) {
263 *var0;
264 *var1;
265 *var2;
266
267 } else {
DeLesley Hutchins66540852013-10-04 21:28:06 +0000268 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
269 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
270 *var2; // expected-warning {{invalid invocation of method 'operator*' on object 'var2' while it is in the 'consumed' state}}
271 }
272#endif
273}
274
275void testComplexConditionals1() {
276 ConsumableClass<int> var0, var1, var2;
277
278 // Coerce all variables into the unknown state.
DeLesley Hutchinsbe63ab62013-10-18 19:25:18 +0000279 baf4(var0);
280 baf4(var1);
281 baf4(var2);
DeLesley Hutchins66540852013-10-04 21:28:06 +0000282
283 if (var0 && var1) {
284 *var0;
285 *var1;
286
287 } else {
288 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}}
289 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}}
290 }
291
292 if (var0 || var1) {
293 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}}
294 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}}
295
296 } else {
297 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
298 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
299 }
300
301 if (var0 && !var1) {
302 *var0;
303 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
304
305 } else {
306 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}}
307 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}}
308 }
309
310 if (var0 || !var1) {
311 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}}
312 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}}
313
314 } else {
315 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
316 *var1;
317 }
318
319 if (!var0 && !var1) {
320 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
321 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
322
323 } else {
324 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}}
325 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}}
326 }
327
328 if (!(var0 || var1)) {
329 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
330 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
331
332 } else {
333 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}}
334 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}}
335 }
336
337 if (!var0 || !var1) {
338 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}}
339 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}}
340
341 } else {
342 *var0;
343 *var1;
344 }
345
346 if (!(var0 && var1)) {
347 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}}
348 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}}
349
350 } else {
351 *var0;
352 *var1;
353 }
354
355 if (var0 && var1 && var2) {
356 *var0;
357 *var1;
358 *var2;
359
360 } else {
361 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}}
362 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}}
363 *var2; // expected-warning {{invalid invocation of method 'operator*' on object 'var2' while it is in the 'unknown' state}}
364 }
365
366#if 0
367 // FIXME: Get this test to pass.
368 if (var0 || var1 || var2) {
369 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}}
370 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}}
371 *var2; // expected-warning {{invalid invocation of method 'operator*' on object 'var2' while it is in the 'unknown' state}}
372
373 } else {
374 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
375 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
376 *var2; // expected-warning {{invalid invocation of method 'operator*' on object 'var2' while it is in the 'consumed' state}}
DeLesley Hutchinsb7dc1f52013-08-29 17:26:57 +0000377 }
378#endif
379}
380
381void testStateChangeInBranch() {
382 ConsumableClass<int> var;
383
384 // Make var enter the 'unknown' state.
DeLesley Hutchinsbe63ab62013-10-18 19:25:18 +0000385 baf4(var);
DeLesley Hutchinsb7dc1f52013-08-29 17:26:57 +0000386
387 if (!var) {
388 var = ConsumableClass<int>(42);
389 }
390
391 *var;
392}
393
DeLesley Hutchins42525982013-08-29 22:36:05 +0000394void testFunctionParam(ConsumableClass<int> param) {
395
396 if (param.isValid()) {
397 *param;
398 } else {
David Blaikiea33ab602013-09-06 01:28:43 +0000399 *param;
DeLesley Hutchins42525982013-08-29 22:36:05 +0000400 }
401
402 param = nullptr;
403 *param; // expected-warning {{invocation of method 'operator*' on object 'param' while it is in the 'consumed' state}}
404}
405
DeLesley Hutchinscd0f6d72013-10-17 22:53:04 +0000406void testParamReturnTypestateCallee(bool cond, ConsumableClass<int> &Param RETURN_TYPESTATE(unconsumed)) { // expected-warning {{parameter 'Param' not in expected state when the function returns: expected 'unconsumed', observed 'consumed'}}
407
408 if (cond) {
409 Param.consume();
410 return; // expected-warning {{parameter 'Param' not in expected state when the function returns: expected 'unconsumed', observed 'consumed'}}
411 }
412
413 Param.consume();
414}
415
416void testParamReturnTypestateCaller() {
417 ConsumableClass<int> var;
418
419 testParamReturnTypestateCallee(true, var);
420
421 *var;
422}
423
DeLesley Hutchinsd4f0e192013-10-17 23:23:53 +0000424void testParamTypestateCallee(ConsumableClass<int> Param0 PARAM_TYPESTATE(consumed),
425 ConsumableClass<int> &Param1 PARAM_TYPESTATE(consumed)) {
426
427 *Param0; // expected-warning {{invalid invocation of method 'operator*' on object 'Param0' while it is in the 'consumed' state}}
428 *Param1; // expected-warning {{invalid invocation of method 'operator*' on object 'Param1' while it is in the 'consumed' state}}
429}
430
431void testParamTypestateCaller() {
432 ConsumableClass<int> Var0, Var1(42);
433
434 testParamTypestateCallee(Var0, Var1); // expected-warning {{argument not in expected state; expected 'consumed', observed 'unconsumed'}}
435}
436
Stephen Hines651f13c2014-04-23 16:59:28 -0700437
438void consumeFunc(ConsumableClass<int> P PARAM_TYPESTATE(unconsumed));
439struct ParamTest {
440 static void consumeFuncStatic(ConsumableClass<int> P PARAM_TYPESTATE(unconsumed));
441 void consumeFuncMeth(ConsumableClass<int> P PARAM_TYPESTATE(unconsumed));
442 void operator<<(ConsumableClass<int> P PARAM_TYPESTATE(unconsumed));
443};
444
445void operator>>(ParamTest& pt, ConsumableClass<int> P PARAM_TYPESTATE(unconsumed));
446
447
448void testFunctionParams() {
449 // Make sure we handle the different kinds of functions.
450 ConsumableClass<int> P;
451
452 consumeFunc(P); // expected-warning {{argument not in expected state; expected 'unconsumed', observed 'consumed'}}
453 ParamTest::consumeFuncStatic(P); // expected-warning {{argument not in expected state; expected 'unconsumed', observed 'consumed'}}
454 ParamTest pt;
455 pt.consumeFuncMeth(P); // expected-warning {{argument not in expected state; expected 'unconsumed', observed 'consumed'}}
456 pt << P; // expected-warning {{argument not in expected state; expected 'unconsumed', observed 'consumed'}}
457 pt >> P; // expected-warning {{argument not in expected state; expected 'unconsumed', observed 'consumed'}}
458}
459
DeLesley Hutchinsbe63ab62013-10-18 19:25:18 +0000460void baf3(ConsumableClass<int> var) {
461 *var;
462}
463
464void baf4(ConsumableClass<int> &var) {
465 *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'unknown' state}}
466}
467
468void baf6(ConsumableClass<int> &&var) {
469 *var;
470}
471
DeLesley Hutchinsb7dc1f52013-08-29 17:26:57 +0000472void testCallingConventions() {
DeLesley Hutchins9e8bd1d2013-08-23 18:40:39 +0000473 ConsumableClass<int> var(42);
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +0000474
475 baf0(var);
476 *var;
477
478 baf1(var);
479 *var;
480
481 baf2(&var);
482 *var;
483
DeLesley Hutchinsbe63ab62013-10-18 19:25:18 +0000484 baf4(var);
DeLesley Hutchins66540852013-10-04 21:28:06 +0000485 *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'unknown' state}}
486
487 var = ConsumableClass<int>(42);
DeLesley Hutchinsbe63ab62013-10-18 19:25:18 +0000488 baf5(&var);
DeLesley Hutchins66540852013-10-04 21:28:06 +0000489 *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'unknown' state}}
490
491 var = ConsumableClass<int>(42);
DeLesley Hutchinsbe63ab62013-10-18 19:25:18 +0000492 baf6(static_cast<ConsumableClass<int>&&>(var));
DeLesley Hutchins66540852013-10-04 21:28:06 +0000493 *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}}
494}
495
496void testConstAndNonConstMemberFunctions() {
497 ConsumableClass<int> var(42);
498
499 var.constCall();
500 *var;
501
502 var.nonconstCall();
503 *var;
504}
505
506void testFunctionParam0(ConsumableClass<int> param) {
507 *param;
508}
509
510void testFunctionParam1(ConsumableClass<int> &param) {
511 *param; // expected-warning {{invalid invocation of method 'operator*' on object 'param' while it is in the 'unknown' state}}
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +0000512}
513
DeLesley Hutchins0e8534e2013-09-03 20:11:38 +0000514void testReturnStates() {
515 ConsumableClass<int> var;
516
517 var = returnsUnconsumed();
518 *var;
519
520 var = returnsConsumed();
DeLesley Hutchins66540852013-10-04 21:28:06 +0000521 *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}}
522}
523
524void testCallableWhen() {
525 ConsumableClass<int> var(42);
526
527 *var;
528
DeLesley Hutchinsbe63ab62013-10-18 19:25:18 +0000529 baf4(var);
DeLesley Hutchins66540852013-10-04 21:28:06 +0000530
531 var.callableWhenUnknown();
DeLesley Hutchins0e8534e2013-09-03 20:11:38 +0000532}
533
DeLesley Hutchinsb7dc1f52013-08-29 17:26:57 +0000534void testMoveAsignmentish() {
DeLesley Hutchins9e8bd1d2013-08-23 18:40:39 +0000535 ConsumableClass<int> var0;
536 ConsumableClass<long> var1(42);
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +0000537
DeLesley Hutchins66540852013-10-04 21:28:06 +0000538 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +0000539 *var1;
540
DeLesley Hutchins9e8bd1d2013-08-23 18:40:39 +0000541 var0 = static_cast<ConsumableClass<long>&&>(var1);
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +0000542
543 *var0;
DeLesley Hutchins66540852013-10-04 21:28:06 +0000544 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
DeLesley Hutchinsd324a0b2013-08-29 21:17:25 +0000545
546 var1 = ConsumableClass<long>(42);
547 var1 = nullptr;
DeLesley Hutchins66540852013-10-04 21:28:06 +0000548 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +0000549}
550
DeLesley Hutchinsb7dc1f52013-08-29 17:26:57 +0000551void testConditionalMerge() {
DeLesley Hutchins9e8bd1d2013-08-23 18:40:39 +0000552 ConsumableClass<int> var;
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +0000553
554 if (var.isValid()) {
555 // Empty
556 }
557
DeLesley Hutchins66540852013-10-04 21:28:06 +0000558 *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}}
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +0000559
560 if (var.isValid()) {
561 // Empty
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +0000562 } else {
563 // Empty
564 }
565
DeLesley Hutchins66540852013-10-04 21:28:06 +0000566 *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}}
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +0000567}
568
DeLesley Hutchinsf30e1942013-10-11 23:03:26 +0000569void testSetTypestate() {
DeLesley Hutchins9e8bd1d2013-08-23 18:40:39 +0000570 ConsumableClass<int> var(42);
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +0000571
572 *var;
573
574 var.consume();
575
DeLesley Hutchins66540852013-10-04 21:28:06 +0000576 *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}}
DeLesley Hutchinsf30e1942013-10-11 23:03:26 +0000577
578 var.unconsume();
579
580 *var;
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +0000581}
582
DeLesley Hutchinsf30e1942013-10-11 23:03:26 +0000583void testConsumes0() {
DeLesley Hutchins9e8bd1d2013-08-23 18:40:39 +0000584 ConsumableClass<int> var(nullptr);
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +0000585
DeLesley Hutchins66540852013-10-04 21:28:06 +0000586 *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}}
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +0000587}
588
DeLesley Hutchinsf30e1942013-10-11 23:03:26 +0000589void testConsumes1() {
DeLesley Hutchins9e8bd1d2013-08-23 18:40:39 +0000590 ConsumableClass<int> var(42);
DeLesley Hutchins5fdd2072013-08-22 20:44:47 +0000591
592 var.unconsumedCall();
593 var(6);
594
DeLesley Hutchins66540852013-10-04 21:28:06 +0000595 var.unconsumedCall(); // expected-warning {{invalid invocation of method 'unconsumedCall' on object 'var' while it is in the 'consumed' state}}
DeLesley Hutchins5fdd2072013-08-22 20:44:47 +0000596}
597
DeLesley Hutchins66540852013-10-04 21:28:06 +0000598void testUnreachableBlock() {
DeLesley Hutchinsb7dc1f52013-08-29 17:26:57 +0000599 ConsumableClass<int> var(42);
600
601 if (var) {
602 *var;
603 } else {
604 *var;
605 }
606
607 *var;
608}
609
DeLesley Hutchins73858402013-10-09 18:30:24 +0000610
611void testForLoop1() {
612 ConsumableClass<int> var0, var1(42);
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +0000613
DeLesley Hutchins73858402013-10-09 18:30:24 +0000614 for (int i = 0; i < 10; ++i) { // expected-warning {{state of variable 'var1' must match at the entry and exit of loop}}
615 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
616
617 *var1;
618 var1.consume();
619 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +0000620 }
621
DeLesley Hutchins73858402013-10-09 18:30:24 +0000622 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +0000623}
624
DeLesley Hutchins73858402013-10-09 18:30:24 +0000625void testWhileLoop1() {
626 int i = 10;
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +0000627
DeLesley Hutchins73858402013-10-09 18:30:24 +0000628 ConsumableClass<int> var0, var1(42);
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +0000629
DeLesley Hutchins52f717e2013-10-17 18:19:31 +0000630 while (i-- > 0) { // expected-warning {{state of variable 'var1' must match at the entry and exit of loop}}
DeLesley Hutchins73858402013-10-09 18:30:24 +0000631 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
632
633 *var1;
634 var1.consume();
DeLesley Hutchins52f717e2013-10-17 18:19:31 +0000635 *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +0000636 }
637
DeLesley Hutchins73858402013-10-09 18:30:24 +0000638 *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
DeLesley Hutchinsdf7bef02013-08-12 21:20:55 +0000639}
DeLesley Hutchins52f717e2013-10-17 18:19:31 +0000640
Pirama Arumuga Nainar33337ca2015-05-06 11:48:57 -0700641// Tests if state information is correctly discarded for certain shapes of CFGs.
642void testSwitchGOTO(void) {
643 int a;
644
645 LABEL0:
646 switch (a)
647 case 0:
648 goto LABEL0;
649
650 goto LABEL0;
651}
652
Chris Wailesec00b0f2013-11-07 18:35:18 +0000653typedef const int*& IntegerPointerReference;
654void testIsRValueRefishAndCanonicalType(IntegerPointerReference a) {}
DeLesley Hutchins52f717e2013-10-17 18:19:31 +0000655
656namespace ContinueICETest {
657
658bool cond1();
659bool cond2();
660
661static void foo1() {
662 while (cond1()) {
663 if (cond2())
664 continue;
665 }
666}
667
668static void foo2() {
669 while (true) {
670 if (false)
671 continue;
672 }
673}
674
DeLesley Hutchins9cd5d402013-10-17 22:21:03 +0000675class runtime_error
676{
677public:
678 virtual ~runtime_error();
679};
680
681void read(bool sf) {
682 while (sf) {
683 if(sf) throw runtime_error();
684 }
685}
686
DeLesley Hutchins52f717e2013-10-17 18:19:31 +0000687} // end namespace ContinueICETest
688
DeLesley Hutchins13be0322013-10-18 23:11:49 +0000689
Stephen Hines651f13c2014-04-23 16:59:28 -0700690namespace StatusUseCaseTests {
DeLesley Hutchins13be0322013-10-18 23:11:49 +0000691
Stephen Hines651f13c2014-04-23 16:59:28 -0700692class CONSUMABLE(unconsumed)
693 __attribute__((consumable_auto_cast_state))
694 __attribute__((consumable_set_state_on_read))
695 Status {
DeLesley Hutchins13be0322013-10-18 23:11:49 +0000696 int code;
697
698public:
Stephen Hines651f13c2014-04-23 16:59:28 -0700699 static Status OK;
700
DeLesley Hutchins13be0322013-10-18 23:11:49 +0000701 Status() RETURN_TYPESTATE(consumed);
702 Status(int c) RETURN_TYPESTATE(unconsumed);
703
704 Status(const Status &other);
DeLesley Hutchins4c3e0bc2013-11-16 00:22:43 +0000705 Status(Status &&other);
DeLesley Hutchins13be0322013-10-18 23:11:49 +0000706
707 Status& operator=(const Status &other) CALLABLE_WHEN("unknown", "consumed");
DeLesley Hutchins4c3e0bc2013-11-16 00:22:43 +0000708 Status& operator=(Status &&other) CALLABLE_WHEN("unknown", "consumed");
DeLesley Hutchins13be0322013-10-18 23:11:49 +0000709
Stephen Hines651f13c2014-04-23 16:59:28 -0700710 bool operator==(const Status &other) const SET_TYPESTATE(consumed);
711
DeLesley Hutchins13be0322013-10-18 23:11:49 +0000712 bool check() const SET_TYPESTATE(consumed);
713 void ignore() const SET_TYPESTATE(consumed);
714 // Status& markAsChecked() { return *this; }
715
716 void clear() CALLABLE_WHEN("unknown", "consumed") SET_TYPESTATE(consumed);
717
718 ~Status() CALLABLE_WHEN("unknown", "consumed");
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700719
720 operator bool() const; // Will not consume the object.
DeLesley Hutchins13be0322013-10-18 23:11:49 +0000721};
722
723
724bool cond();
725Status doSomething();
DeLesley Hutchins4c3e0bc2013-11-16 00:22:43 +0000726void handleStatus(const Status& s RETURN_TYPESTATE(consumed));
Stephen Hines651f13c2014-04-23 16:59:28 -0700727void handleStatusRef(Status& s);
728void handleStatusPtr(Status* s);
729void handleStatusUnmarked(const Status& s);
730
731void log(const char* msg);
732void fail() __attribute__((noreturn));
733void checkStat(const Status& s);
734
DeLesley Hutchins13be0322013-10-18 23:11:49 +0000735
DeLesley Hutchins4c3e0bc2013-11-16 00:22:43 +0000736void testSimpleTemporaries0() {
737 doSomething(); // expected-warning {{invalid invocation of method '~Status' on a temporary object while it is in the 'unconsumed' state}}
738}
DeLesley Hutchins13be0322013-10-18 23:11:49 +0000739
DeLesley Hutchins4c3e0bc2013-11-16 00:22:43 +0000740void testSimpleTemporaries1() {
741 doSomething().ignore();
742}
DeLesley Hutchins13be0322013-10-18 23:11:49 +0000743
DeLesley Hutchins4c3e0bc2013-11-16 00:22:43 +0000744void testSimpleTemporaries2() {
745 handleStatus(doSomething());
746}
747
748void testSimpleTemporaries3() {
749 Status s = doSomething();
750} // expected-warning {{invalid invocation of method '~Status' on object 's' while it is in the 'unconsumed' state}}
751
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700752void testTemporariesWithControlFlow(bool a) {
753 bool b = false || doSomething(); // expected-warning {{invalid invocation of method '~Status' on a temporary object while it is in the 'unconsumed' state}}
754}
755
Stephen Hines651f13c2014-04-23 16:59:28 -0700756Status testSimpleTemporariesReturn0() {
757 return doSomething();
758}
759
760Status testSimpleTemporariesReturn1() {
761 Status s = doSomething();
762 return s;
763}
764
DeLesley Hutchins4c3e0bc2013-11-16 00:22:43 +0000765void testSimpleTemporaries4() {
766 Status s = doSomething();
767 s.check();
768}
769
770void testSimpleTemporaries5() {
771 Status s = doSomething();
772 s.clear(); // expected-warning {{invalid invocation of method 'clear' on object 's' while it is in the 'unconsumed' state}}
773}
774
775void testSimpleTemporaries6() {
Stephen Hines651f13c2014-04-23 16:59:28 -0700776 Status s1 = doSomething();
777 handleStatus(s1);
778
779 Status s2 = doSomething();
780 handleStatusRef(s2);
781
782 Status s3 = doSomething();
783 handleStatusPtr(&s3);
784
785 Status s4 = doSomething();
786 handleStatusUnmarked(s4);
DeLesley Hutchins4c3e0bc2013-11-16 00:22:43 +0000787}
788
789void testSimpleTemporaries7() {
790 Status s;
791 s = doSomething();
792} // expected-warning {{invalid invocation of method '~Status' on object 's' while it is in the 'unconsumed' state}}
793
794void testTemporariesWithConditionals0() {
795 int a;
796
797 Status s = doSomething();
798 if (cond()) a = 0;
799 else a = 1;
800} // expected-warning {{invalid invocation of method '~Status' on object 's' while it is in the 'unconsumed' state}}
801
802void testTemporariesWithConditionals1() {
803 int a;
804
805 Status s = doSomething();
806 if (cond()) a = 0;
807 else a = 1;
808 s.ignore();
809}
810
811void testTemporariesWithConditionals2() {
812 int a;
813
814 Status s = doSomething();
815 s.ignore();
816 if (cond()) a = 0;
817 else a = 1;
818}
819
820void testTemporariesWithConditionals3() {
821 Status s = doSomething();
DeLesley Hutchins13be0322013-10-18 23:11:49 +0000822 if (cond()) {
DeLesley Hutchins4c3e0bc2013-11-16 00:22:43 +0000823 s.check();
DeLesley Hutchins13be0322013-10-18 23:11:49 +0000824 }
825}
826
DeLesley Hutchins4c3e0bc2013-11-16 00:22:43 +0000827void testTemporariesAndConstructors0() {
Stephen Hines651f13c2014-04-23 16:59:28 -0700828 Status s(doSomething()); // Test the copy constructor.
DeLesley Hutchins4c3e0bc2013-11-16 00:22:43 +0000829 s.check();
830}
831
Stephen Hines651f13c2014-04-23 16:59:28 -0700832void testTemporariesAndConstructors1F() {
833 Status s1 = doSomething(); // Test the copy constructor.
834 Status s2 = s1;
835} // expected-warning {{invalid invocation of method '~Status' on object 's2' while it is in the 'unconsumed' state}}
DeLesley Hutchins4c3e0bc2013-11-16 00:22:43 +0000836
Stephen Hines651f13c2014-04-23 16:59:28 -0700837void testTemporariesAndConstructors1S() {
838 Status s1 = doSomething(); // Test the copy constructor.
839 Status s2(s1);
DeLesley Hutchins4c3e0bc2013-11-16 00:22:43 +0000840 s2.check();
841}
842
Stephen Hines651f13c2014-04-23 16:59:28 -0700843void testTemporariesAndConstructors2F() {
844 // Test the move constructor.
845 Status s1 = doSomething();
846 Status s2 = static_cast<Status&&>(s1);
847} // expected-warning {{invalid invocation of method '~Status' on object 's2' while it is in the 'unconsumed' state}}
848
849void testTemporariesAndConstructors2S() {
850 // Test the move constructor.
851 Status s1 = doSomething();
852 Status s2 = static_cast<Status&&>(s1);
853 s2.check();
854}
855
856void testTemporariesAndOperators0F() {
DeLesley Hutchins4c3e0bc2013-11-16 00:22:43 +0000857 // Test the assignment operator.
Stephen Hines651f13c2014-04-23 16:59:28 -0700858 Status s1 = doSomething();
859 Status s2;
860 s2 = s1;
861} // expected-warning {{invalid invocation of method '~Status' on object 's2' while it is in the 'unconsumed' state}}
862
863void testTemporariesAndOperators0S() {
864 // Test the assignment operator.
DeLesley Hutchins4c3e0bc2013-11-16 00:22:43 +0000865 Status s1 = doSomething();
866 Status s2;
867 s2 = s1;
868 s2.check();
Stephen Hines651f13c2014-04-23 16:59:28 -0700869}
DeLesley Hutchins4c3e0bc2013-11-16 00:22:43 +0000870
Stephen Hines651f13c2014-04-23 16:59:28 -0700871void testTemporariesAndOperators1F() {
DeLesley Hutchins4c3e0bc2013-11-16 00:22:43 +0000872 // Test the move assignment operator.
Stephen Hines651f13c2014-04-23 16:59:28 -0700873 Status s1 = doSomething();
874 Status s2;
875 s2 = static_cast<Status&&>(s1);
876} // expected-warning {{invalid invocation of method '~Status' on object 's2' while it is in the 'unconsumed' state}}
877
878void testTemporariesAndOperators1S() {
879 // Test the move assignment operator.
DeLesley Hutchins4c3e0bc2013-11-16 00:22:43 +0000880 Status s1 = doSomething();
881 Status s2;
882 s2 = static_cast<Status&&>(s1);
883 s2.check();
884}
885
886void testTemporariesAndOperators2() {
887 Status s1 = doSomething();
888 Status s2 = doSomething();
889 s1 = s2; // expected-warning {{invalid invocation of method 'operator=' on object 's1' while it is in the 'unconsumed' state}}
890 s1.check();
891 s2.check();
892}
893
Stephen Hines651f13c2014-04-23 16:59:28 -0700894Status testReturnAutocast() {
895 Status s = doSomething();
896 s.check(); // consume s
897 return s; // should autocast back to unconsumed
898}
899
900
901namespace TestParens {
902
903void test3() {
904 checkStat((doSomething()));
905}
906
907void test4() {
908 Status s = (doSomething());
909 s.check();
910}
911
912void test5() {
913 (doSomething()).check();
914}
915
916void test6() {
917 if ((doSomething()) == Status::OK)
918 return;
919}
920
921} // end namespace TestParens
922
DeLesley Hutchins13be0322013-10-18 23:11:49 +0000923} // end namespace InitializerAssertionFailTest
924
Stephen Hines651f13c2014-04-23 16:59:28 -0700925
926namespace std {
927 void move();
928 template<class T>
929 void move(T&&);
930
931 namespace __1 {
932 void move();
933 template<class T>
934 void move(T&&);
935 }
936}
937
938namespace PR18260 {
939 class X {
940 public:
941 void move();
942 } x;
943
944 void test() {
945 x.move();
946 std::move();
947 std::move(x);
948 std::__1::move();
949 std::__1::move(x);
950 }
951} // end namespace PR18260
952