xref: /aosp_15_r20/external/clang/test/SemaCXX/warn-consumed-analysis.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
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> &param) {
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