1 // RUN: %clang_cc1 -fsyntax-only -verify=cxx11 -std=c++11 -Wno-unused -Wno-uninitialized \
2 // RUN:            -Wunsequenced -Wno-c++17-extensions -Wno-c++14-extensions %s
3 // RUN: %clang_cc1 -fsyntax-only -verify=cxx17 -std=c++17 -Wno-unused -Wno-uninitialized \
4 // RUN:            -Wunsequenced -Wno-c++17-extensions -Wno-c++14-extensions %s
5 
6 int f(int, int = 0);
7 int g1();
8 int g2(int);
9 
10 struct A {
11   int x, y;
12 };
13 struct S {
14   S(int, int);
15   int n;
16 };
17 
18 // TODO: Implement the C++17 sequencing rules.
test()19 void test() {
20   int a;
21   int xs[10];
22   ++a = 0; // ok
23   a + ++a; // cxx11-warning {{unsequenced modification and access to 'a'}}
24            // cxx17-warning@-1 {{unsequenced modification and access to 'a'}}
25   a = ++a; // ok
26   a + a++; // cxx11-warning {{unsequenced modification and access to 'a'}}
27            // cxx17-warning@-1 {{unsequenced modification and access to 'a'}}
28   a = a++; // cxx11-warning {{multiple unsequenced modifications to 'a'}}
29   ++ ++a; // ok
30   (a++, a++); // ok
31   ++a + ++a; // cxx11-warning {{multiple unsequenced modifications to 'a'}}
32              // cxx17-warning@-1 {{multiple unsequenced modifications to 'a'}}
33   a++ + a++; // cxx11-warning {{multiple unsequenced modifications to 'a'}}
34              // cxx17-warning@-1 {{multiple unsequenced modifications to 'a'}}
35   (a++, a) = 0; // ok, increment is sequenced before value computation of LHS
36   a = xs[++a]; // ok
37   a = xs[a++]; // cxx11-warning {{multiple unsequenced modifications to 'a'}}
38   (a ? xs[0] : xs[1]) = ++a; // cxx11-warning {{unsequenced modification and access to 'a'}}
39   a = (++a, ++a); // ok
40   a = (a++, ++a); // ok
41   a = (a++, a++); // cxx11-warning {{multiple unsequenced modifications to 'a'}}
42   f(a, a); // ok
43   f(a = 0, a); // cxx11-warning {{unsequenced modification and access to 'a'}}
44                // cxx17-warning@-1 {{unsequenced modification and access to 'a'}}
45   f(a, a += 0); // cxx11-warning {{unsequenced modification and access to 'a'}}
46                 // cxx17-warning@-1 {{unsequenced modification and access to 'a'}}
47   f(a = 0, a = 0); // cxx11-warning {{multiple unsequenced modifications to 'a'}}
48                    // cxx17-warning@-1 {{multiple unsequenced modifications to 'a'}}
49   a = f(++a); // ok
50   a = f(a++); // ok
51   a = f(++a, a++); // cxx11-warning {{multiple unsequenced modifications to 'a'}}
52                    // cxx17-warning@-1 {{multiple unsequenced modifications to 'a'}}
53 
54   // Compound assignment "A OP= B" is equivalent to "A = A OP B" except that A
55   // is evaluated only once.
56   (++a, a) = 1; // ok
57   (++a, a) += 1; // ok
58   a = ++a; // ok
59   a += ++a; // cxx11-warning {{unsequenced modification and access to 'a'}}
60 
61   A agg1 = { a++, a++ }; // ok
62   A agg2 = { a++ + a, a++ }; // cxx11-warning {{unsequenced modification and access to 'a'}}
63                              // cxx17-warning@-1 {{unsequenced modification and access to 'a'}}
64 
65   S str1(a++, a++); // cxx11-warning {{multiple unsequenced modifications to 'a'}}
66                     // cxx17-warning@-1 {{multiple unsequenced modifications to 'a'}}
67   S str2 = { a++, a++ }; // ok
68   S str3 = { a++ + a, a++ }; // cxx11-warning {{unsequenced modification and access to 'a'}}
69                              // cxx17-warning@-1 {{unsequenced modification and access to 'a'}}
70 
71   struct Z { A a; S s; } z = { { ++a, ++a }, { ++a, ++a } }; // ok
72   a = S { ++a, a++ }.n; // ok
73   A { ++a, a++ }.x; // ok
74   a = A { ++a, a++ }.x; // cxx11-warning {{multiple unsequenced modifications to 'a'}}
75   A { ++a, a++ }.x + A { ++a, a++ }.y; // cxx11-warning {{multiple unsequenced modifications to 'a'}}
76                                        // cxx17-warning@-1 {{multiple unsequenced modifications to 'a'}}
77 
78   (xs[2] && (a = 0)) + a; // cxx11-warning {{unsequenced modification and access to 'a'}}
79                           // cxx17-warning@-1 {{unsequenced modification and access to 'a'}}
80   (0 && (a = 0)) + a; // ok
81   (1 && (a = 0)) + a; // cxx11-warning {{unsequenced modification and access to 'a'}}
82                       // cxx17-warning@-1 {{unsequenced modification and access to 'a'}}
83 
84   (xs[3] || (a = 0)) + a; // cxx11-warning {{unsequenced modification and access to 'a'}}
85                           // cxx17-warning@-1 {{unsequenced modification and access to 'a'}}
86   (0 || (a = 0)) + a; // cxx11-warning {{unsequenced modification and access to 'a'}}
87                       // cxx17-warning@-1 {{unsequenced modification and access to 'a'}}
88   (1 || (a = 0)) + a; // ok
89 
90   (xs[4] ? a : ++a) + a; // cxx11-warning {{unsequenced modification and access to 'a'}}
91                          // cxx17-warning@-1 {{unsequenced modification and access to 'a'}}
92   (0 ? a : ++a) + a; // cxx11-warning {{unsequenced modification and access to 'a'}}
93                      // cxx17-warning@-1 {{unsequenced modification and access to 'a'}}
94   (1 ? a : ++a) + a; // ok
95   (0 ? a : a++) + a; // cxx11-warning {{unsequenced modification and access to 'a'}}
96                      // cxx17-warning@-1 {{unsequenced modification and access to 'a'}}
97   (1 ? a : a++) + a; // ok
98   (xs[5] ? ++a : ++a) + a; // cxx11-warning {{unsequenced modification and access to 'a'}}
99                            // cxx17-warning@-1 {{unsequenced modification and access to 'a'}}
100 
101   (++a, xs[6] ? ++a : 0) + a; // cxx11-warning {{unsequenced modification and access to 'a'}}
102                               // cxx17-warning@-1 {{unsequenced modification and access to 'a'}}
103 
104   // Here, the read of the fourth 'a' might happen before or after the write to
105   // the second 'a'.
106   a += (a++, a) + a; // cxx11-warning {{unsequenced modification and access to 'a'}}
107                      // cxx17-warning@-1 {{unsequenced modification and access to 'a'}}
108 
109   a = a++ && a; // ok
110 
111   A *q = &agg1;
112   (q = &agg2)->y = q->x; // cxx11-warning {{unsequenced modification and access to 'q'}}
113 
114   // This has undefined behavior if a == 0; otherwise, the side-effect of the
115   // increment is sequenced before the value computation of 'f(a, a)', which is
116   // sequenced before the value computation of the '&&', which is sequenced
117   // before the assignment. We treat the sequencing in '&&' as being
118   // unconditional.
119   a = a++ && f(a, a);
120 
121   // This has undefined behavior if a != 0.
122   (a && a++) + a; // cxx11-warning {{unsequenced modification and access to 'a'}}
123                   // cxx17-warning@-1 {{unsequenced modification and access to 'a'}}
124 
125   // FIXME: Don't warn here.
126   (xs[7] && ++a) * (!xs[7] && ++a); // cxx11-warning {{multiple unsequenced modifications to 'a'}}
127                                     // cxx17-warning@-1 {{multiple unsequenced modifications to 'a'}}
128 
129   xs[0] = (a = 1, a); // ok
130   (a -= 128) &= 128; // ok
131   ++a += 1; // ok
132 
133   xs[8] ? ++a + a++ : 0; // cxx11-warning {{multiple unsequenced modifications to 'a'}}
134                          // cxx17-warning@-1 {{multiple unsequenced modifications to 'a'}}
135   xs[8] ? 0 : ++a + a++; // cxx11-warning {{multiple unsequenced modifications to 'a'}}
136                          // cxx17-warning@-1 {{multiple unsequenced modifications to 'a'}}
137   xs[8] ? ++a : a++; // no-warning
138   xs[8] ? a+=1 : a+= 2; // no-warning
139   (xs[8] ? a+=1 : a+= 2) = a; // cxx11-warning {{unsequenced modification and access to 'a'}}
140   (xs[8] ? a+=1 : a) = a; // cxx11-warning {{unsequenced modification and access to 'a'}}
141   (xs[8] ? a : a+= 2) = a; // cxx11-warning {{unsequenced modification and access to 'a'}}
142   a = (xs[8] ? a+=1 : a+= 2); // no-warning
143   a += (xs[8] ? a+=1 : a+= 2); // cxx11-warning {{unsequenced modification and access to 'a'}}
144 
145   (false ? a+=1 : a) = a; // no-warning
146   (true ? a+=1 : a) = a; // cxx11-warning {{unsequenced modification and access to 'a'}}
147   (false ? a : a+=2) = a; // cxx11-warning {{unsequenced modification and access to 'a'}}
148   (true ? a : a+=2) = a; // no-warning
149 
150   xs[8] && (++a + a++); // cxx11-warning {{multiple unsequenced modifications to 'a'}}
151                         // cxx17-warning@-1 {{multiple unsequenced modifications to 'a'}}
152   xs[8] || (++a + a++); // cxx11-warning {{multiple unsequenced modifications to 'a'}}
153                         // cxx17-warning@-1 {{multiple unsequenced modifications to 'a'}}
154 
155   ((a++, false) || (a++, false)); // no-warning PR39779
156   ((a++, true) && (a++, true)); // no-warning PR39779
157 
158   int i,j;
159   (i = g1(), false) || (j = g2(i)); // no-warning PR22197
160   (i = g1(), true) && (j = g2(i)); // no-warning PR22197
161 
162   (a++, false) || (a++, false) || (a++, false) || (a++, false); // no-warning
163   (a++, true) || (a++, true) || (a++, true) || (a++, true); // no-warning
164   a = ((a++, false) || (a++, false) || (a++, false) || (a++, false)); // no-warning
165   a = ((a++, true) && (a++, true) && (a++, true) && (a++, true)); // no-warning
166   a = ((a++, false) || (a++, false) || (a++, false) || a++); // cxx11-warning {{multiple unsequenced modifications to 'a'}}
167   a = ((a++, true) && (a++, true) && (a++, true) && a++); // cxx11-warning {{multiple unsequenced modifications to 'a'}}
168   a = ((a++, false) || (a++, false) || (a++, false) || (a + a, false)); // no-warning
169   a = ((a++, true) && (a++, true) && (a++, true) && (a + a, true)); // no-warning
170 
171   a = (false && a++); // no-warning
172   a = (true && a++); // cxx11-warning {{multiple unsequenced modifications to 'a'}}
173   a = (true && ++a); // no-warning
174   a = (true || a++); // no-warning
175   a = (false || a++); // cxx11-warning {{multiple unsequenced modifications to 'a'}}
176   a = (false || ++a); // no-warning
177 
178   (a++) | (a++); // cxx11-warning {{multiple unsequenced modifications to 'a'}}
179                  // cxx17-warning@-1 {{multiple unsequenced modifications to 'a'}}
180   (a++) & (a++); // cxx11-warning {{multiple unsequenced modifications to 'a'}}
181                  // cxx17-warning@-1 {{multiple unsequenced modifications to 'a'}}
182   (a++) ^ (a++); // cxx11-warning {{multiple unsequenced modifications to 'a'}}
183                  // cxx17-warning@-1 {{multiple unsequenced modifications to 'a'}}
184 
185   (__builtin_classify_type(++a) ? 1 : 0) + ++a; // ok
186   (__builtin_constant_p(++a) ? 1 : 0) + ++a; // ok
187   (__builtin_object_size(&(++a, a), 0) ? 1 : 0) + ++a; // ok
188   (__builtin_expect(++a, 0) ? 1 : 0) + ++a; // cxx11-warning {{multiple unsequenced modifications to 'a'}}
189                                             // cxx17-warning@-1 {{multiple unsequenced modifications to 'a'}}
190 
191 
192   int *p = xs;
193   a = *(a++, p); // no-warning
194   p[(long long unsigned)(p = 0)]; // cxx11-warning {{unsequenced modification and access to 'p'}}
195   (i++, xs)[i++]; // cxx11-warning {{multiple unsequenced modifications to 'i'}}
196   (++i, xs)[++i]; // cxx11-warning {{multiple unsequenced modifications to 'i'}}
197   (i, xs)[++i + ++i]; // cxx11-warning {{multiple unsequenced modifications to 'i'}}
198                       // cxx17-warning@-1 {{multiple unsequenced modifications to 'i'}}
199   p++[p == xs]; // cxx11-warning {{unsequenced modification and access to 'p'}}
200   ++p[p++ == xs]; // cxx11-warning {{unsequenced modification and access to 'p'}}
201 
202   struct S { int x; } s, *ps = &s;
203   int (S::*PtrMem);
204   (PtrMem = &S::x ,s).*(PtrMem); // cxx11-warning {{unsequenced modification and access to 'PtrMem'}}
205   (PtrMem = &S::x ,s).*(PtrMem = &S::x); // cxx11-warning {{multiple unsequenced modifications to 'PtrMem'}}
206   (PtrMem = &S::x ,ps)->*(PtrMem); // cxx11-warning {{unsequenced modification and access to 'PtrMem'}}
207   (PtrMem = &S::x ,ps)->*(PtrMem = &S::x); // cxx11-warning {{multiple unsequenced modifications to 'PtrMem'}}
208   (PtrMem = nullptr) == (PtrMem = nullptr); // cxx11-warning {{multiple unsequenced modifications to 'PtrMem'}}
209                                             // cxx17-warning@-1 {{multiple unsequenced modifications to 'PtrMem'}}
210   (PtrMem = nullptr) == PtrMem; // cxx11-warning {{unsequenced modification and access to 'PtrMem'}}
211                                 // cxx17-warning@-1 {{unsequenced modification and access to 'PtrMem'}}
212 
213   i++ << i++; // cxx11-warning {{multiple unsequenced modifications to 'i'}}
214   ++i << ++i; // cxx11-warning {{multiple unsequenced modifications to 'i'}}
215   i++ << i; // cxx11-warning {{unsequenced modification and access to 'i'}}
216   i << i++; // cxx11-warning {{unsequenced modification and access to 'i'}}
217   i++ >> i++; // cxx11-warning {{multiple unsequenced modifications to 'i'}}
218   ++i >> ++i; // cxx11-warning {{multiple unsequenced modifications to 'i'}}
219   i++ >> i; // cxx11-warning {{unsequenced modification and access to 'i'}}
220   i >> i++; // cxx11-warning {{unsequenced modification and access to 'i'}}
221   (i++ << i) + i; // cxx11-warning {{unsequenced modification and access to 'i'}}
222                   // cxx17-warning@-1 {{unsequenced modification and access to 'i'}}
223   (i++ << i) << i++; // cxx11-warning {{unsequenced modification and access to 'i'}}
224 
225   ++i = i++; // cxx11-warning {{multiple unsequenced modifications to 'i'}}
226   i = i+= 1; // no-warning
227   i = i++ + ++i; // cxx11-warning {{multiple unsequenced modifications to 'i'}}
228                  // cxx17-warning@-1 {{multiple unsequenced modifications to 'i'}}
229   ++i += ++i; // cxx11-warning {{multiple unsequenced modifications to 'i'}}
230   ++i += i++; // cxx11-warning {{multiple unsequenced modifications to 'i'}}
231   (i++, i) += ++i; // cxx11-warning {{multiple unsequenced modifications to 'i'}}
232   (i++, i) += i++; // cxx11-warning {{multiple unsequenced modifications to 'i'}}
233   i += i+= 1; // cxx11-warning {{unsequenced modification and access to 'i'}}
234   i += i++; // cxx11-warning {{unsequenced modification and access to 'i'}}
235   i += ++i; // cxx11-warning {{unsequenced modification and access to 'i'}}
236   i -= i++; // cxx11-warning {{unsequenced modification and access to 'i'}}
237   i -= ++i; // cxx11-warning {{unsequenced modification and access to 'i'}}
238   i *= i++; // cxx11-warning {{unsequenced modification and access to 'i'}}
239   i *= ++i; // cxx11-warning {{unsequenced modification and access to 'i'}}
240   i /= i++; // cxx11-warning {{unsequenced modification and access to 'i'}}
241   i /= ++i; // cxx11-warning {{unsequenced modification and access to 'i'}}
242   i %= i++; // cxx11-warning {{unsequenced modification and access to 'i'}}
243   i %= ++i; // cxx11-warning {{unsequenced modification and access to 'i'}}
244   i ^= i++; // cxx11-warning {{unsequenced modification and access to 'i'}}
245   i ^= ++i; // cxx11-warning {{unsequenced modification and access to 'i'}}
246   i |= i++; // cxx11-warning {{unsequenced modification and access to 'i'}}
247   i |= ++i; // cxx11-warning {{unsequenced modification and access to 'i'}}
248   i &= i++; // cxx11-warning {{unsequenced modification and access to 'i'}}
249   i &= ++i; // cxx11-warning {{unsequenced modification and access to 'i'}}
250   i <<= i++; // cxx11-warning {{unsequenced modification and access to 'i'}}
251   i <<= ++i; // cxx11-warning {{unsequenced modification and access to 'i'}}
252   i >>= i++; // cxx11-warning {{unsequenced modification and access to 'i'}}
253   i >>= ++i; // cxx11-warning {{unsequenced modification and access to 'i'}}
254 
255   p[i++] = i; // cxx11-warning {{unsequenced modification and access to 'i'}}
256   p[i++] = (i = 42); // cxx11-warning {{multiple unsequenced modifications to 'i'}}
257   p++[i++] = (i = p ? i++ : i++); // cxx11-warning {{unsequenced modification and access to 'p'}}
258                                   // cxx11-warning@-1 {{multiple unsequenced modifications to 'i'}}
259 }
260 
261 namespace members {
262 
263 struct S1 {
264   unsigned bf1 : 2;
265   unsigned bf2 : 2;
266   unsigned a;
267   unsigned b;
268   static unsigned x;
269   void member_f(S1 &s);
270 };
271 
member_f(S1 & s)272 void S1::member_f(S1 &s) {
273   ++a + ++a; // cxx11-warning {{multiple unsequenced modifications to 'a'}}
274              // cxx17-warning@-1 {{multiple unsequenced modifications to 'a'}}
275   a + ++a; // cxx11-warning {{unsequenced modification and access to 'a'}}
276            // cxx17-warning@-1 {{unsequenced modification and access to 'a'}}
277   ++a + ++b; // no-warning
278   a + ++b; // no-warning
279 
280   // TODO: Warn here.
281   ++s.a + ++s.a; // no-warning TODO {{multiple unsequenced modifications to}}
282   s.a + ++s.a; // no-warning TODO {{unsequenced modification and access to}}
283   ++s.a + ++s.b; // no-warning
284   s.a + ++s.b; // no-warning
285 
286   ++a + ++s.a; // no-warning
287   a + ++s.a; // no-warning
288   ++a + ++s.b; // no-warning
289   a + ++s.b; // no-warning
290 
291   // TODO Warn here for bit-fields in the same memory location.
292   ++bf1 + ++bf1; // cxx11-warning {{multiple unsequenced modifications to 'bf1'}}
293                  // cxx17-warning@-1 {{multiple unsequenced modifications to 'bf1'}}
294   bf1 + ++bf1; // cxx11-warning {{unsequenced modification and access to 'bf1'}}
295                // cxx17-warning@-1 {{unsequenced modification and access to 'bf1'}}
296   ++bf1 + ++bf2; // no-warning TODO {{multiple unsequenced modifications to}}
297   bf1 + ++bf2; // no-warning TODO {{unsequenced modification and access to}}
298 
299   // TODO Warn here for bit-fields in the same memory location.
300   ++s.bf1 + ++s.bf1; // no-warning TODO {{multiple unsequenced modifications to}}
301   s.bf1 + ++s.bf1; // no-warning TODO {{unsequenced modification and access to}}
302   ++s.bf1 + ++s.bf2; // no-warning TODO {{multiple unsequenced modifications to}}
303   s.bf1 + ++s.bf2; // no-warning TODO {{unsequenced modification and access to}}
304 
305   ++bf1 + ++s.bf1; // no-warning
306   bf1 + ++s.bf1; // no-warning
307   ++bf1 + ++s.bf2; // no-warning
308   bf1 + ++s.bf2; // no-warning
309 
310   struct Der : S1 {};
311   Der d;
312   Der &d_ref = d;
313   S1 &s1_ref = d_ref;
314 
315   ++s1_ref.a + ++d_ref.a; // no-warning TODO {{multiple unsequenced modifications to member 'a' of 'd'}}
316   ++s1_ref.a + d_ref.a; // no-warning TODO {{unsequenced modification and access to member 'a' of 'd'}}
317   ++s1_ref.a + ++d_ref.b; // no-warning
318   ++s1_ref.a + d_ref.b; // no-warning
319 
320   ++x + ++x; // cxx11-warning {{multiple unsequenced modifications to 'x'}}
321              // cxx17-warning@-1 {{multiple unsequenced modifications to 'x'}}
322   ++x + x; // cxx11-warning {{unsequenced modification and access to 'x'}}
323            // cxx17-warning@-1 {{unsequenced modification and access to 'x'}}
324   ++s.x + x; // no-warning TODO {{unsequenced modification and access to static member 'x' of 'S1'}}
325   ++this->x + x; // cxx11-warning {{unsequenced modification and access to 'x'}}
326                  // cxx17-warning@-1 {{unsequenced modification and access to 'x'}}
327   ++d_ref.x + ++S1::x; // no-warning TODO {{unsequenced modification and access to static member 'x' of 'S1'}}
328 }
329 
330 struct S2 {
331   union { unsigned x, y; };
332   void f2();
333 };
334 
f2()335 void S2::f2() {
336   ++x + ++x; // no-warning TODO {{multiple unsequenced modifications to}}
337   x + ++x; // no-warning TODO {{unsequenced modification and access to}}
338   ++x + ++y; // no-warning
339   x + ++y; // no-warning
340 }
341 
f2(S2 & s)342 void f2(S2 &s) {
343   ++s.x + ++s.x; // no-warning TODO {{multiple unsequenced modifications to}}
344   s.x + ++s.x; // no-warning TODO {{unsequenced modification and access to}}
345   ++s.x + ++s.y; // no-warning
346   s.x + ++s.y; // no-warning
347 }
348 
349 struct S3 {
350   union {
351     union {
352       unsigned x;
353     };
354   };
355   unsigned y;
356   void f3();
357 };
358 
f3()359 void S3::f3() {
360   ++x + ++x; // no-warning TODO {{multiple unsequenced modifications to}}
361   x + ++x; // no-warning TODO {{unsequenced modification and access to}}
362   ++x + ++y; // no-warning
363   x + ++y; // no-warning
364 }
365 
f3(S3 & s)366 void f3(S3 &s) {
367   ++s.x + ++s.x; // no-warning TODO {{multiple unsequenced modifications to}}
368   s.x + ++s.x; // no-warning TODO {{unsequenced modification and access to}}
369   ++s.x + ++s.y; // no-warning
370   s.x + ++s.y; // no-warning
371 }
372 
373 struct S4 : S3 {
374   unsigned y;
375   void f4();
376 };
377 
f4()378 void S4::f4() {
379   ++x + ++x; // no-warning TODO {{multiple unsequenced modifications to}}
380   x + ++x; // no-warning TODO {{unsequenced modification and access to}}
381   ++x + ++y; // no-warning
382   x + ++y; // no-warning
383   ++S3::y + ++y; // no-warning
384   S3::y + ++y; // no-warning
385 }
386 
f4(S4 & s)387 void f4(S4 &s) {
388   ++s.x + ++s.x; // no-warning TODO {{multiple unsequenced modifications to}}
389   s.x + ++s.x; // no-warning TODO {{unsequenced modification and access to}}
390   ++s.x + ++s.y; // no-warning
391   s.x + ++s.y; // no-warning
392   ++s.S3::y + ++s.y; // no-warning
393   s.S3::y + ++s.y; // no-warning
394 }
395 
396 static union {
397   unsigned Ux;
398   unsigned Uy;
399 };
400 
f5()401 void f5() {
402   ++Ux + ++Ux; // no-warning TODO {{multiple unsequenced modifications to}}
403   Ux + ++Ux; // no-warning TODO {{unsequenced modification and access to}}
404   ++Ux + ++Uy; // no-warning
405   Ux + ++Uy; // no-warning
406 }
407 
f6()408 void f6() {
409   struct S { unsigned x, y; } s;
410   ++s.x + ++s.x; // no-warning TODO {{multiple unsequenced modifications to}}
411   s.x + ++s.x; // no-warning TODO {{unsequenced modification and access to}}
412   ++s.x + ++s.y; // no-warning
413   s.x + ++s.y; // no-warning
414 
415   struct { unsigned x, y; } t;
416   ++t.x + ++t.x; // no-warning TODO {{multiple unsequenced modifications to}}
417   t.x + ++t.x; // no-warning TODO {{unsequenced modification and access to}}
418   ++t.x + ++t.y; // no-warning
419   t.x + ++t.y; // no-warning
420 }
421 
422 } // namespace members
423 
424 namespace references {
reference_f()425 void reference_f() {
426   // TODO: Check that we can see through references.
427   // For now this is completely unhandled.
428   int a;
429   int xs[10];
430   int &b = a;
431   int &c = b;
432   int &ra1 = c;
433   int &ra2 = b;
434   int other;
435 
436   ++ra1 + ++ra2; // no-warning TODO {{multiple unsequenced modifications to}}
437   ra1 + ++ra2; // no-warning TODO {{unsequenced modification and access to}}
438   ++ra1 + ++other; // no-warning
439   ra1 + ++other; // no-warning
440 
441   // Make sure we handle reference cycles.
442   int &ref_cycle = ref_cycle;
443   ++ref_cycle + ++ref_cycle; // cxx11-warning {{multiple unsequenced modifications to 'ref_cycle'}}
444                              // cxx17-warning@-1 {{multiple unsequenced modifications to 'ref_cycle'}}
445   ref_cycle + ++ref_cycle; // cxx11-warning {{unsequenced modification and access to 'ref_cycle'}}
446                            // cxx17-warning@-1 {{unsequenced modification and access to 'ref_cycle'}}
447 }
448 } // namespace references
449 
450 namespace std {
451   using size_t = decltype(sizeof(0));
452   template<typename> struct tuple_size;
453   template<size_t, typename> struct tuple_element { using type = int; };
454 }
455 namespace bindings {
456 
457   struct A { int x, y; };
458   typedef int B[2];
459   struct C { template<int> int get(); };
460   struct D : A {};
461 
462 } // namespace bindings
463 template<> struct std::tuple_size<bindings::C> { enum { value = 2 }; };
464 namespace bindings {
testa()465 void testa() {
466   A a;
467   {
468     auto [x, y] = a;
469     ++x + ++x; // cxx11-warning {{multiple unsequenced modifications to 'x'}}
470                // cxx17-warning@-1 {{multiple unsequenced modifications to 'x'}}
471     ++x + x; // cxx11-warning {{unsequenced modification and access to 'x'}}
472              // cxx17-warning@-1 {{unsequenced modification and access to 'x'}}
473     ++x + ++y; // no-warning
474     ++x + y; // no-warning
475     ++x + ++a.x; // no-warning
476     ++x + a.x; // no-warning
477   }
478   {
479     auto &[x, y] = a;
480     ++x + ++x; // cxx11-warning {{multiple unsequenced modifications to 'x'}}
481                // cxx17-warning@-1 {{multiple unsequenced modifications to 'x'}}
482     ++x + x; // cxx11-warning {{unsequenced modification and access to 'x'}}
483              // cxx17-warning@-1 {{unsequenced modification and access to 'x'}}
484     ++x + ++y; // no-warning
485     ++x + y; // no-warning
486     ++x + ++a.x; // no-warning TODO
487     ++x + a.x; // no-warning TODO
488   }
489 }
testb()490 void testb() {
491   B b;
492   {
493     auto [x, y] = b;
494     ++x + ++x; // cxx11-warning {{multiple unsequenced modifications to 'x'}}
495                // cxx17-warning@-1 {{multiple unsequenced modifications to 'x'}}
496     ++x + x; // cxx11-warning {{unsequenced modification and access to 'x'}}
497              // cxx17-warning@-1 {{unsequenced modification and access to 'x'}}
498     ++x + ++y; // no-warning
499     ++x + y; // no-warning
500     ++x + ++b[0]; // no-warning
501     ++x + b[0]; // no-warning
502   }
503   {
504     auto &[x, y] = b;
505     ++x + ++x; // cxx11-warning {{multiple unsequenced modifications to 'x'}}
506                // cxx17-warning@-1 {{multiple unsequenced modifications to 'x'}}
507     ++x + x; // cxx11-warning {{unsequenced modification and access to 'x'}}
508              // cxx17-warning@-1 {{unsequenced modification and access to 'x'}}
509     ++x + ++y; // no-warning
510     ++x + y; // no-warning
511     ++x + ++b[0]; // no-warning TODO
512     ++x + b[0]; // no-warning TODO
513   }
514 }
testc()515 void testc() {
516   C c;
517   {
518     auto [x, y] = c;
519     ++x + ++x; // cxx11-warning {{multiple unsequenced modifications to 'x'}}
520                // cxx17-warning@-1 {{multiple unsequenced modifications to 'x'}}
521     ++x + x; // cxx11-warning {{unsequenced modification and access to 'x'}}
522              // cxx17-warning@-1 {{unsequenced modification and access to 'x'}}
523     ++x + ++y; // no-warning
524     ++x + y; // no-warning
525   }
526   {
527     auto &[x, y] = c;
528     ++x + ++x; // cxx11-warning {{multiple unsequenced modifications to 'x'}}
529                // cxx17-warning@-1 {{multiple unsequenced modifications to 'x'}}
530     ++x + x; // cxx11-warning {{unsequenced modification and access to 'x'}}
531              // cxx17-warning@-1 {{unsequenced modification and access to 'x'}}
532     ++x + ++y; // no-warning
533     ++x + y; // no-warning
534   }
535 }
testd()536 void testd() {
537   D d;
538   {
539     auto [x, y] = d;
540     ++x + ++x; // cxx11-warning {{multiple unsequenced modifications to 'x'}}
541                // cxx17-warning@-1 {{multiple unsequenced modifications to 'x'}}
542     ++x + x; // cxx11-warning {{unsequenced modification and access to 'x'}}
543              // cxx17-warning@-1 {{unsequenced modification and access to 'x'}}
544     ++x + ++y; // no-warning
545     ++x + y; // no-warning
546     ++x + ++d.x; // no-warning
547     ++x + d.x; // no-warning
548   }
549   {
550     auto &[x, y] = d;
551     ++x + ++x; // cxx11-warning {{multiple unsequenced modifications to 'x'}}
552                // cxx17-warning@-1 {{multiple unsequenced modifications to 'x'}}
553     ++x + x; // cxx11-warning {{unsequenced modification and access to 'x'}}
554              // cxx17-warning@-1 {{unsequenced modification and access to 'x'}}
555     ++x + ++y; // no-warning
556     ++x + y; // no-warning
557     ++x + ++d.x; // no-warning TODO
558     ++x + d.x; // no-warning TODO
559   }
560 }
561 } // namespace bindings
562 
563 namespace templates {
564 
565 template <typename T>
566 struct Bar {
gettemplates::Bar567   T get() { return 0; }
568 };
569 
570 template <typename X>
571 struct Foo {
572   int Run();
573   Bar<int> bar;
574 };
575 
576 enum E {e1, e2};
577 bool operator&&(E, E);
578 
579 void foo(int, int);
580 
581 template <typename X>
Run()582 int Foo<X>::Run() {
583   char num = 0;
584 
585   // Before instantiation, Clang may consider the builtin operator here as
586   // unresolved function calls, and treat the arguments as unordered when
587   // the builtin operator evaluatation is well-ordered.  Waiting until
588   // instantiation to check these expressions will prevent false positives.
589   if ((num = bar.get()) < 5 && num < 10) { }
590   if ((num = bar.get()) < 5 || num < 10) { }
591   if (static_cast<E>((num = bar.get()) < 5) || static_cast<E>(num < 10)) { }
592 
593   if (static_cast<E>((num = bar.get()) < 5) && static_cast<E>(num < 10)) { }
594   // cxx11-warning@-1 {{unsequenced modification and access to 'num'}}
595   // cxx17-warning@-2 {{unsequenced modification and access to 'num'}}
596 
597   foo(num++, num++);
598   // cxx11-warning@-1 {{multiple unsequenced modifications to 'num'}}
599   // cxx17-warning@-2 {{multiple unsequenced modifications to 'num'}}
600   return 1;
601 }
602 
603 int x = Foo<int>().Run();
604 // cxx11-note@-1 {{in instantiation of member function 'templates::Foo<int>::Run'}}
605 // cxx17-note@-2 {{in instantiation of member function 'templates::Foo<int>::Run'}}
606 
607 
608 template <typename T>
Run2()609 int Run2() {
610   T t = static_cast<T>(0);
611   return (t = static_cast<T>(1)) && t;
612   // cxx11-warning@-1 {{unsequenced modification and access to 't'}}
613   // cxx17-warning@-2 {{unsequenced modification and access to 't'}}
614 }
615 
616 int y = Run2<bool>();
617 int z = Run2<E>();
618 // cxx11-note@-1{{in instantiation of function template specialization 'templates::Run2<templates::E>' requested here}}
619 // cxx17-note@-2{{in instantiation of function template specialization 'templates::Run2<templates::E>' requested here}}
620 
621 template <typename T> int var = sizeof(T);
test_var()622 void test_var() {
623   var<int>++ + var<int>++; // cxx11-warning {{multiple unsequenced modifications to 'var<int>'}}
624                            // cxx17-warning@-1 {{multiple unsequenced modifications to 'var<int>'}}
625   var<int>++ + var<int>; // cxx11-warning {{unsequenced modification and access to 'var<int>'}}
626                          // cxx17-warning@-1 {{unsequenced modification and access to 'var<int>'}}
627   int &r = var<int>;
628   r++ + var<int>++; // no-warning TODO {{multiple unsequenced modifications to 'var<int>'}}
629   r++ + var<long>++; // no-warning
630 }
631 
632 } // namespace templates
633