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