• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
test()18 void test() {
19   int a;
20   int xs[10];
21   ++a = 0; // ok
22   a + ++a; // cxx11-warning {{unsequenced modification and access to 'a'}}
23            // cxx17-warning@-1 {{unsequenced modification and access to 'a'}}
24   a = ++a; // ok
25   a + a++; // cxx11-warning {{unsequenced modification and access to 'a'}}
26            // cxx17-warning@-1 {{unsequenced modification and access to 'a'}}
27   a = a++; // cxx11-warning {{multiple unsequenced modifications to 'a'}}
28   ++ ++a; // ok
29   (a++, a++); // ok
30   ++a + ++a; // cxx11-warning {{multiple unsequenced modifications to 'a'}}
31              // cxx17-warning@-1 {{multiple unsequenced modifications to 'a'}}
32   a++ + a++; // cxx11-warning {{multiple unsequenced modifications to 'a'}}
33              // cxx17-warning@-1 {{multiple unsequenced modifications to 'a'}}
34   (a++, a) = 0; // ok, increment is sequenced before value computation of LHS
35   a = xs[++a]; // ok
36   a = xs[a++]; // cxx11-warning {{multiple unsequenced modifications to 'a'}}
37   (a ? xs[0] : xs[1]) = ++a; // cxx11-warning {{unsequenced modification and access to 'a'}}
38   a = (++a, ++a); // ok
39   a = (a++, ++a); // ok
40   a = (a++, a++); // cxx11-warning {{multiple unsequenced modifications to 'a'}}
41   f(a, a); // ok
42   f(a = 0, a); // cxx11-warning {{unsequenced modification and access to 'a'}}
43                // cxx17-warning@-1 {{unsequenced modification and access to 'a'}}
44   f(a, a += 0); // cxx11-warning {{unsequenced modification and access to 'a'}}
45                 // cxx17-warning@-1 {{unsequenced modification and access to 'a'}}
46   f(a = 0, a = 0); // cxx11-warning {{multiple unsequenced modifications to 'a'}}
47                    // cxx17-warning@-1 {{multiple unsequenced modifications to 'a'}}
48   a = f(++a); // ok
49   a = f(a++); // ok
50   a = f(++a, a++); // cxx11-warning {{multiple unsequenced modifications to 'a'}}
51                    // cxx17-warning@-1 {{multiple unsequenced modifications to 'a'}}
52 
53   // Compound assignment "A OP= B" is equivalent to "A = A OP B" except that A
54   // is evaluated only once.
55   (++a, a) = 1; // ok
56   (++a, a) += 1; // ok
57   a = ++a; // ok
58   a += ++a; // cxx11-warning {{unsequenced modification and access to 'a'}}
59 
60   A agg1 = { a++, a++ }; // ok
61   A agg2 = { a++ + a, a++ }; // cxx11-warning {{unsequenced modification and access to 'a'}}
62                              // cxx17-warning@-1 {{unsequenced modification and access to 'a'}}
63 
64   S str1(a++, a++); // cxx11-warning {{multiple unsequenced modifications to 'a'}}
65                     // cxx17-warning@-1 {{multiple unsequenced modifications to 'a'}}
66   S str2 = { a++, a++ }; // ok
67   S str3 = { a++ + a, a++ }; // cxx11-warning {{unsequenced modification and access to 'a'}}
68                              // cxx17-warning@-1 {{unsequenced modification and access to 'a'}}
69 
70   struct Z { A a; S s; } z = { { ++a, ++a }, { ++a, ++a } }; // ok
71   a = S { ++a, a++ }.n; // ok
72   A { ++a, a++ }.x; // ok
73   a = A { ++a, a++ }.x; // cxx11-warning {{multiple unsequenced modifications to 'a'}}
74   A { ++a, a++ }.x + A { ++a, a++ }.y; // cxx11-warning {{multiple unsequenced modifications to 'a'}}
75                                        // cxx17-warning@-1 {{multiple unsequenced modifications to 'a'}}
76 
77   (xs[2] && (a = 0)) + a; // cxx11-warning {{unsequenced modification and access to 'a'}}
78                           // cxx17-warning@-1 {{unsequenced modification and access to 'a'}}
79   (0 && (a = 0)) + a; // ok
80   (1 && (a = 0)) + a; // cxx11-warning {{unsequenced modification and access to 'a'}}
81                       // cxx17-warning@-1 {{unsequenced modification and access to 'a'}}
82 
83   (xs[3] || (a = 0)) + a; // cxx11-warning {{unsequenced modification and access to 'a'}}
84                           // cxx17-warning@-1 {{unsequenced modification and access to 'a'}}
85   (0 || (a = 0)) + a; // cxx11-warning {{unsequenced modification and access to 'a'}}
86                       // cxx17-warning@-1 {{unsequenced modification and access to 'a'}}
87   (1 || (a = 0)) + a; // ok
88 
89   (xs[4] ? a : ++a) + a; // cxx11-warning {{unsequenced modification and access to 'a'}}
90                          // cxx17-warning@-1 {{unsequenced modification and access to 'a'}}
91   (0 ? a : ++a) + a; // cxx11-warning {{unsequenced modification and access to 'a'}}
92                      // cxx17-warning@-1 {{unsequenced modification and access to 'a'}}
93   (1 ? a : ++a) + a; // ok
94   (0 ? a : a++) + a; // cxx11-warning {{unsequenced modification and access to 'a'}}
95                      // cxx17-warning@-1 {{unsequenced modification and access to 'a'}}
96   (1 ? a : a++) + a; // ok
97   (xs[5] ? ++a : ++a) + a; // cxx11-warning {{unsequenced modification and access to 'a'}}
98                            // cxx17-warning@-1 {{unsequenced modification and access to 'a'}}
99 
100   (++a, xs[6] ? ++a : 0) + a; // cxx11-warning {{unsequenced modification and access to 'a'}}
101                               // cxx17-warning@-1 {{unsequenced modification and access to 'a'}}
102 
103   // Here, the read of the fourth 'a' might happen before or after the write to
104   // the second 'a'.
105   a += (a++, a) + a; // cxx11-warning {{unsequenced modification and access to 'a'}}
106                      // cxx17-warning@-1 {{unsequenced modification and access to 'a'}}
107 
108   a = a++ && a; // ok
109 
110   A *q = &agg1;
111   (q = &agg2)->y = q->x; // cxx11-warning {{unsequenced modification and access to 'q'}}
112 
113   // This has undefined behavior if a == 0; otherwise, the side-effect of the
114   // increment is sequenced before the value computation of 'f(a, a)', which is
115   // sequenced before the value computation of the '&&', which is sequenced
116   // before the assignment. We treat the sequencing in '&&' as being
117   // unconditional.
118   a = a++ && f(a, a);
119 
120   // This has undefined behavior if a != 0.
121   (a && a++) + a; // cxx11-warning {{unsequenced modification and access to 'a'}}
122                   // cxx17-warning@-1 {{unsequenced modification and access to 'a'}}
123 
124   // FIXME: Don't warn here.
125   (xs[7] && ++a) * (!xs[7] && ++a); // cxx11-warning {{multiple unsequenced modifications to 'a'}}
126                                     // cxx17-warning@-1 {{multiple unsequenced modifications to 'a'}}
127 
128   xs[0] = (a = 1, a); // ok
129   (a -= 128) &= 128; // ok
130   ++a += 1; // ok
131 
132   xs[8] ? ++a + a++ : 0; // cxx11-warning {{multiple unsequenced modifications to 'a'}}
133                          // cxx17-warning@-1 {{multiple unsequenced modifications to 'a'}}
134   xs[8] ? 0 : ++a + a++; // cxx11-warning {{multiple unsequenced modifications to 'a'}}
135                          // cxx17-warning@-1 {{multiple unsequenced modifications to 'a'}}
136   xs[8] ? ++a : a++; // no-warning
137   xs[8] ? a+=1 : a+= 2; // no-warning
138   (xs[8] ? a+=1 : a+= 2) = a; // cxx11-warning {{unsequenced modification and access to 'a'}}
139   (xs[8] ? a+=1 : a) = a; // cxx11-warning {{unsequenced modification and access to 'a'}}
140   (xs[8] ? a : a+= 2) = a; // cxx11-warning {{unsequenced modification and access to 'a'}}
141   a = (xs[8] ? a+=1 : a+= 2); // no-warning
142   a += (xs[8] ? a+=1 : a+= 2); // cxx11-warning {{unsequenced modification and access to 'a'}}
143 
144   (false ? a+=1 : a) = a; // no-warning
145   (true ? a+=1 : a) = a; // cxx11-warning {{unsequenced modification and access to 'a'}}
146   (false ? a : a+=2) = a; // cxx11-warning {{unsequenced modification and access to 'a'}}
147   (true ? a : a+=2) = a; // no-warning
148 
149   xs[8] && (++a + a++); // cxx11-warning {{multiple unsequenced modifications to 'a'}}
150                         // cxx17-warning@-1 {{multiple unsequenced modifications to 'a'}}
151   xs[8] || (++a + a++); // cxx11-warning {{multiple unsequenced modifications to 'a'}}
152                         // cxx17-warning@-1 {{multiple unsequenced modifications to 'a'}}
153 
154   ((a++, false) || (a++, false)); // no-warning PR39779
155   ((a++, true) && (a++, true)); // no-warning PR39779
156 
157   int i,j;
158   (i = g1(), false) || (j = g2(i)); // no-warning PR22197
159   (i = g1(), true) && (j = g2(i)); // no-warning PR22197
160 
161   (a++, false) || (a++, false) || (a++, false) || (a++, false); // no-warning
162   (a++, true) || (a++, true) || (a++, true) || (a++, true); // no-warning
163   a = ((a++, false) || (a++, false) || (a++, false) || (a++, false)); // no-warning
164   a = ((a++, true) && (a++, true) && (a++, true) && (a++, true)); // no-warning
165   a = ((a++, false) || (a++, false) || (a++, false) || a++); // cxx11-warning {{multiple unsequenced modifications to 'a'}}
166   a = ((a++, true) && (a++, true) && (a++, true) && a++); // cxx11-warning {{multiple unsequenced modifications to 'a'}}
167   a = ((a++, false) || (a++, false) || (a++, false) || (a + a, false)); // no-warning
168   a = ((a++, true) && (a++, true) && (a++, true) && (a + a, true)); // no-warning
169 
170   a = (false && a++); // no-warning
171   a = (true && a++); // cxx11-warning {{multiple unsequenced modifications to 'a'}}
172   a = (true && ++a); // no-warning
173   a = (true || a++); // no-warning
174   a = (false || a++); // cxx11-warning {{multiple unsequenced modifications to 'a'}}
175   a = (false || ++a); // no-warning
176 
177   (a++) | (a++); // cxx11-warning {{multiple unsequenced modifications to 'a'}}
178                  // cxx17-warning@-1 {{multiple unsequenced modifications to 'a'}}
179   (a++) & (a++); // cxx11-warning {{multiple unsequenced modifications to 'a'}}
180                  // cxx17-warning@-1 {{multiple unsequenced modifications to 'a'}}
181   (a++) ^ (a++); // cxx11-warning {{multiple unsequenced modifications to 'a'}}
182                  // cxx17-warning@-1 {{multiple unsequenced modifications to 'a'}}
183 
184   (__builtin_classify_type(++a) ? 1 : 0) + ++a; // ok
185   (__builtin_constant_p(++a) ? 1 : 0) + ++a; // ok
186   (__builtin_object_size(&(++a, a), 0) ? 1 : 0) + ++a; // ok
187   (__builtin_expect(++a, 0) ? 1 : 0) + ++a; // cxx11-warning {{multiple unsequenced modifications to 'a'}}
188                                             // cxx17-warning@-1 {{multiple unsequenced modifications to 'a'}}
189 
190 
191   int *p = xs;
192   a = *(a++, p); // no-warning
193   p[(long long unsigned)(p = 0)]; // cxx11-warning {{unsequenced modification and access to 'p'}}
194   (i++, xs)[i++]; // cxx11-warning {{multiple unsequenced modifications to 'i'}}
195   (++i, xs)[++i]; // cxx11-warning {{multiple unsequenced modifications to 'i'}}
196   (i, xs)[++i + ++i]; // cxx11-warning {{multiple unsequenced modifications to 'i'}}
197                       // cxx17-warning@-1 {{multiple unsequenced modifications to 'i'}}
198   p++[p == xs]; // cxx11-warning {{unsequenced modification and access to 'p'}}
199   ++p[p++ == xs]; // cxx11-warning {{unsequenced modification and access to 'p'}}
200 
201   struct S { int x; } s, *ps = &s;
202   int (S::*PtrMem);
203   (PtrMem = &S::x ,s).*(PtrMem); // cxx11-warning {{unsequenced modification and access to 'PtrMem'}}
204   (PtrMem = &S::x ,s).*(PtrMem = &S::x); // cxx11-warning {{multiple unsequenced modifications to 'PtrMem'}}
205   (PtrMem = &S::x ,ps)->*(PtrMem); // cxx11-warning {{unsequenced modification and access to 'PtrMem'}}
206   (PtrMem = &S::x ,ps)->*(PtrMem = &S::x); // cxx11-warning {{multiple unsequenced modifications to 'PtrMem'}}
207   (PtrMem = nullptr) == (PtrMem = nullptr); // cxx11-warning {{multiple unsequenced modifications to 'PtrMem'}}
208                                             // cxx17-warning@-1 {{multiple unsequenced modifications to 'PtrMem'}}
209   (PtrMem = nullptr) == PtrMem; // cxx11-warning {{unsequenced modification and access to 'PtrMem'}}
210                                 // cxx17-warning@-1 {{unsequenced modification and access to 'PtrMem'}}
211 
212   i++ << i++; // cxx11-warning {{multiple unsequenced modifications to 'i'}}
213   ++i << ++i; // cxx11-warning {{multiple unsequenced modifications to 'i'}}
214   i++ << i; // cxx11-warning {{unsequenced modification and access to 'i'}}
215   i << i++; // cxx11-warning {{unsequenced modification and access to 'i'}}
216   i++ >> i++; // cxx11-warning {{multiple unsequenced modifications to 'i'}}
217   ++i >> ++i; // cxx11-warning {{multiple unsequenced modifications to 'i'}}
218   i++ >> i; // cxx11-warning {{unsequenced modification and access to 'i'}}
219   i >> i++; // cxx11-warning {{unsequenced modification and access to 'i'}}
220   (i++ << i) + i; // cxx11-warning {{unsequenced modification and access to 'i'}}
221                   // cxx17-warning@-1 {{unsequenced modification and access to 'i'}}
222   (i++ << i) << i++; // cxx11-warning {{unsequenced modification and access to 'i'}}
223 
224   ++i = i++; // cxx11-warning {{multiple unsequenced modifications to 'i'}}
225   i = i+= 1; // no-warning
226   i = i++ + ++i; // cxx11-warning {{multiple unsequenced modifications to 'i'}}
227                  // cxx17-warning@-1 {{multiple unsequenced modifications to 'i'}}
228   ++i += ++i; // cxx11-warning {{multiple unsequenced modifications to 'i'}}
229   ++i += i++; // cxx11-warning {{multiple unsequenced modifications to 'i'}}
230   (i++, i) += ++i; // cxx11-warning {{multiple unsequenced modifications to 'i'}}
231   (i++, i) += i++; // cxx11-warning {{multiple unsequenced modifications to 'i'}}
232   i += i+= 1; // cxx11-warning {{unsequenced modification and access to 'i'}}
233   i += i++; // 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 
254   p[i++] = i; // cxx11-warning {{unsequenced modification and access to 'i'}}
255   p[i++] = (i = 42); // cxx11-warning {{multiple unsequenced modifications to 'i'}}
256   p++[i++] = (i = p ? i++ : i++); // cxx11-warning {{unsequenced modification and access to 'p'}}
257                                   // cxx11-warning@-1 {{multiple unsequenced modifications to 'i'}}
258 
259   (i++, f)(i++, 42); // cxx11-warning {{multiple unsequenced modifications to 'i'}}
260   (i++ + i++, f)(42, 42); // cxx11-warning {{multiple unsequenced modifications to 'i'}}
261                           // cxx17-warning@-1 {{multiple unsequenced modifications to 'i'}}
262   int (*pf)(int, int);
263   (pf = f)(pf != nullptr, pf != nullptr); // cxx11-warning {{unsequenced modification and access to 'pf'}}
264   pf((pf = f) != nullptr, 42); // cxx11-warning {{unsequenced modification and access to 'pf'}}
265   f((pf = f, 42), (pf = f, 42)); // cxx11-warning {{multiple unsequenced modifications to 'pf'}}
266                                  // cxx17-warning@-1 {{multiple unsequenced modifications to 'pf'}}
267   pf((pf = f) != nullptr, pf == nullptr); // cxx11-warning {{unsequenced modification and access to 'pf'}}
268                                           // cxx17-warning@-1 {{unsequenced modification and access to 'pf'}}
269 }
270 
271 namespace PR20819 {
272   struct foo { void bar(int); };
273   foo get_foo(int);
274 
g()275   void g() {
276     int a = 0;
277     get_foo(a).bar(a++);  // cxx11-warning {{unsequenced modification and access to 'a'}}
278   }
279 }
280 
281 namespace overloaded_operators {
282   struct E {
283     E &operator=(E &);
284     E operator()(E);
285     E operator()(E, E);
286     E operator[](E);
287   } e;
288   // Binary operators with unsequenced operands.
289   E operator+(E,E);
290   E operator-(E,E);
291   E operator*(E,E);
292   E operator/(E,E);
293   E operator%(E,E);
294   E operator^(E,E);
295   E operator&(E,E);
296   E operator|(E,E);
297 
298   E operator<(E,E);
299   E operator>(E,E);
300   E operator==(E,E);
301   E operator!=(E,E);
302   E operator>=(E,E);
303   E operator<=(E,E);
304 
305   // Binary operators where the RHS is sequenced before the LHS in C++17.
306   E operator+=(E,E);
307   E operator-=(E,E);
308   E operator*=(E,E);
309   E operator/=(E,E);
310   E operator%=(E,E);
311   E operator^=(E,E);
312   E operator&=(E,E);
313   E operator|=(E,E);
314   E operator<<=(E,E);
315   E operator>>=(E,E);
316 
317   // Binary operators where the LHS is sequenced before the RHS in C++17.
318   E operator<<(E,E);
319   E operator>>(E,E);
320   E operator&&(E,E);
321   E operator||(E,E);
322   E operator,(E,E);
323   E operator->*(E,E);
324 
test()325   void test() {
326     int i = 0;
327     // Binary operators with unsequenced operands.
328     ((void)i++,e) + ((void)i++,e);
329     // cxx11-warning@-1 {{multiple unsequenced modifications to 'i'}}
330     // cxx17-warning@-2 {{multiple unsequenced modifications to 'i'}}
331     ((void)i++,e) - ((void)i++,e);
332     // cxx11-warning@-1 {{multiple unsequenced modifications to 'i'}}
333     // cxx17-warning@-2 {{multiple unsequenced modifications to 'i'}}
334     ((void)i++,e) * ((void)i++,e);
335     // cxx11-warning@-1 {{multiple unsequenced modifications to 'i'}}
336     // cxx17-warning@-2 {{multiple unsequenced modifications to 'i'}}
337     ((void)i++,e) / ((void)i++,e);
338     // cxx11-warning@-1 {{multiple unsequenced modifications to 'i'}}
339     // cxx17-warning@-2 {{multiple unsequenced modifications to 'i'}}
340     ((void)i++,e) % ((void)i++,e);
341     // cxx11-warning@-1 {{multiple unsequenced modifications to 'i'}}
342     // cxx17-warning@-2 {{multiple unsequenced modifications to 'i'}}
343     ((void)i++,e) ^ ((void)i++,e);
344     // cxx11-warning@-1 {{multiple unsequenced modifications to 'i'}}
345     // cxx17-warning@-2 {{multiple unsequenced modifications to 'i'}}
346     ((void)i++,e) & ((void)i++,e);
347     // cxx11-warning@-1 {{multiple unsequenced modifications to 'i'}}
348     // cxx17-warning@-2 {{multiple unsequenced modifications to 'i'}}
349     ((void)i++,e) | ((void)i++,e);
350     // cxx11-warning@-1 {{multiple unsequenced modifications to 'i'}}
351     // cxx17-warning@-2 {{multiple unsequenced modifications to 'i'}}
352 
353     ((void)i++,e) < ((void)i++,e);
354     // cxx11-warning@-1 {{multiple unsequenced modifications to 'i'}}
355     // cxx17-warning@-2 {{multiple unsequenced modifications to 'i'}}
356     ((void)i++,e) > ((void)i++,e);
357     // cxx11-warning@-1 {{multiple unsequenced modifications to 'i'}}
358     // cxx17-warning@-2 {{multiple unsequenced modifications to 'i'}}
359     ((void)i++,e) == ((void)i++,e);
360     // cxx11-warning@-1 {{multiple unsequenced modifications to 'i'}}
361     // cxx17-warning@-2 {{multiple unsequenced modifications to 'i'}}
362     ((void)i++,e) != ((void)i++,e);
363     // cxx11-warning@-1 {{multiple unsequenced modifications to 'i'}}
364     // cxx17-warning@-2 {{multiple unsequenced modifications to 'i'}}
365     ((void)i++,e) <= ((void)i++,e);
366     // cxx11-warning@-1 {{multiple unsequenced modifications to 'i'}}
367     // cxx17-warning@-2 {{multiple unsequenced modifications to 'i'}}
368     ((void)i++,e) >= ((void)i++,e);
369     // cxx11-warning@-1 {{multiple unsequenced modifications to 'i'}}
370     // cxx17-warning@-2 {{multiple unsequenced modifications to 'i'}}
371 
372     // Binary operators where the RHS is sequenced before the LHS in C++17.
373     ((void)i++,e) = ((void)i++,e);
374     // cxx11-warning@-1 {{multiple unsequenced modifications to 'i'}}
375     ((void)i++,e) += ((void)i++,e);
376     // cxx11-warning@-1 {{multiple unsequenced modifications to 'i'}}
377     ((void)i++,e) -= ((void)i++,e);
378     // cxx11-warning@-1 {{multiple unsequenced modifications to 'i'}}
379     ((void)i++,e) *= ((void)i++,e);
380     // cxx11-warning@-1 {{multiple unsequenced modifications to 'i'}}
381     ((void)i++,e) /= ((void)i++,e);
382     // cxx11-warning@-1 {{multiple unsequenced modifications to 'i'}}
383     ((void)i++,e) %= ((void)i++,e);
384     // cxx11-warning@-1 {{multiple unsequenced modifications to 'i'}}
385     ((void)i++,e) ^= ((void)i++,e);
386     // cxx11-warning@-1 {{multiple unsequenced modifications to 'i'}}
387     ((void)i++,e) &= ((void)i++,e);
388     // cxx11-warning@-1 {{multiple unsequenced modifications to 'i'}}
389     ((void)i++,e) |= ((void)i++,e);
390     // cxx11-warning@-1 {{multiple unsequenced modifications to 'i'}}
391     ((void)i++,e) <<= ((void)i++,e);
392     // cxx11-warning@-1 {{multiple unsequenced modifications to 'i'}}
393     ((void)i++,e) >>= ((void)i++,e);
394     // cxx11-warning@-1 {{multiple unsequenced modifications to 'i'}}
395 
396     operator+=(((void)i++,e), ((void)i++,e));
397     // cxx11-warning@-1 {{multiple unsequenced modifications to 'i'}}
398     // cxx17-warning@-2 {{multiple unsequenced modifications to 'i'}}
399 
400     // Binary operators where the LHS is sequenced before the RHS in C++17.
401     ((void)i++,e) << ((void)i++,e);
402     // cxx11-warning@-1 {{multiple unsequenced modifications to 'i'}}
403     ((void)i++,e) >> ((void)i++,e);
404     // cxx11-warning@-1 {{multiple unsequenced modifications to 'i'}}
405     ((void)i++,e) || ((void)i++,e);
406     // cxx11-warning@-1 {{multiple unsequenced modifications to 'i'}}
407     ((void)i++,e) && ((void)i++,e);
408     // cxx11-warning@-1 {{multiple unsequenced modifications to 'i'}}
409     ((void)i++,e) , ((void)i++,e);
410     // cxx11-warning@-1 {{multiple unsequenced modifications to 'i'}}
411     ((void)i++,e)->*((void)i++,e);
412     // cxx11-warning@-1 {{multiple unsequenced modifications to 'i'}}
413 
414     operator<<(((void)i++,e), ((void)i++,e));
415     // cxx11-warning@-1 {{multiple unsequenced modifications to 'i'}}
416     // cxx17-warning@-2 {{multiple unsequenced modifications to 'i'}}
417 
418     ((void)i++,e)[((void)i++,e)];
419     // cxx11-warning@-1 {{multiple unsequenced modifications to 'i'}}
420 
421     ((void)i++,e)(((void)i++,e));
422     // cxx11-warning@-1 {{multiple unsequenced modifications to 'i'}}
423     e(((void)i++,e), ((void)i++,e));
424     // cxx11-warning@-1 {{multiple unsequenced modifications to 'i'}}
425     // cxx17-warning@-2 {{multiple unsequenced modifications to 'i'}}
426 
427     ((void)i++,e).operator()(((void)i++,e));
428     // cxx11-warning@-1 {{multiple unsequenced modifications to 'i'}}
429 
430   }
431 }
432 
433 namespace PR35340 {
434   struct S {};
435   S &operator<<(S &, int);
436 
test()437   void test() {
438     S s;
439     int i = 0;
440     s << i++ << i++;
441     // cxx11-warning@-1 {{multiple unsequenced modifications to 'i'}}
442 
443     operator<<(operator<<(s, i++), i++);
444     // cxx11-warning@-1 {{multiple unsequenced modifications to 'i'}}
445     // cxx17-warning@-2 {{multiple unsequenced modifications to 'i'}}
446   }
447 }
448 
449 namespace members {
450 
451 struct S1 {
452   unsigned bf1 : 2;
453   unsigned bf2 : 2;
454   unsigned a;
455   unsigned b;
456   static unsigned x;
457   void member_f(S1 &s);
458 };
459 
member_f(S1 & s)460 void S1::member_f(S1 &s) {
461   ++a + ++a; // cxx11-warning {{multiple unsequenced modifications to 'a'}}
462              // cxx17-warning@-1 {{multiple unsequenced modifications to 'a'}}
463   a + ++a; // cxx11-warning {{unsequenced modification and access to 'a'}}
464            // cxx17-warning@-1 {{unsequenced modification and access to 'a'}}
465   ++a + ++b; // no-warning
466   a + ++b; // no-warning
467 
468   // TODO: Warn here.
469   ++s.a + ++s.a; // no-warning TODO {{multiple unsequenced modifications to}}
470   s.a + ++s.a; // no-warning TODO {{unsequenced modification and access to}}
471   ++s.a + ++s.b; // no-warning
472   s.a + ++s.b; // no-warning
473 
474   ++a + ++s.a; // no-warning
475   a + ++s.a; // no-warning
476   ++a + ++s.b; // no-warning
477   a + ++s.b; // no-warning
478 
479   // TODO Warn here for bit-fields in the same memory location.
480   ++bf1 + ++bf1; // cxx11-warning {{multiple unsequenced modifications to 'bf1'}}
481                  // cxx17-warning@-1 {{multiple unsequenced modifications to 'bf1'}}
482   bf1 + ++bf1; // cxx11-warning {{unsequenced modification and access to 'bf1'}}
483                // cxx17-warning@-1 {{unsequenced modification and access to 'bf1'}}
484   ++bf1 + ++bf2; // no-warning TODO {{multiple unsequenced modifications to}}
485   bf1 + ++bf2; // no-warning TODO {{unsequenced modification and access to}}
486 
487   // TODO Warn here for bit-fields in the same memory location.
488   ++s.bf1 + ++s.bf1; // no-warning TODO {{multiple unsequenced modifications to}}
489   s.bf1 + ++s.bf1; // no-warning TODO {{unsequenced modification and access to}}
490   ++s.bf1 + ++s.bf2; // no-warning TODO {{multiple unsequenced modifications to}}
491   s.bf1 + ++s.bf2; // no-warning TODO {{unsequenced modification and access to}}
492 
493   ++bf1 + ++s.bf1; // no-warning
494   bf1 + ++s.bf1; // no-warning
495   ++bf1 + ++s.bf2; // no-warning
496   bf1 + ++s.bf2; // no-warning
497 
498   struct Der : S1 {};
499   Der d;
500   Der &d_ref = d;
501   S1 &s1_ref = d_ref;
502 
503   ++s1_ref.a + ++d_ref.a; // no-warning TODO {{multiple unsequenced modifications to member 'a' of 'd'}}
504   ++s1_ref.a + d_ref.a; // no-warning TODO {{unsequenced modification and access to member 'a' of 'd'}}
505   ++s1_ref.a + ++d_ref.b; // no-warning
506   ++s1_ref.a + d_ref.b; // no-warning
507 
508   ++x + ++x; // cxx11-warning {{multiple unsequenced modifications to 'x'}}
509              // cxx17-warning@-1 {{multiple unsequenced modifications to 'x'}}
510   ++x + x; // cxx11-warning {{unsequenced modification and access to 'x'}}
511            // cxx17-warning@-1 {{unsequenced modification and access to 'x'}}
512   ++s.x + x; // no-warning TODO {{unsequenced modification and access to static member 'x' of 'S1'}}
513   ++this->x + x; // cxx11-warning {{unsequenced modification and access to 'x'}}
514                  // cxx17-warning@-1 {{unsequenced modification and access to 'x'}}
515   ++d_ref.x + ++S1::x; // no-warning TODO {{unsequenced modification and access to static member 'x' of 'S1'}}
516 }
517 
518 struct S2 {
519   union { unsigned x, y; };
520   void f2();
521 };
522 
f2()523 void S2::f2() {
524   ++x + ++x; // no-warning TODO {{multiple unsequenced modifications to}}
525   x + ++x; // no-warning TODO {{unsequenced modification and access to}}
526   ++x + ++y; // no-warning
527   x + ++y; // no-warning
528 }
529 
f2(S2 & s)530 void f2(S2 &s) {
531   ++s.x + ++s.x; // no-warning TODO {{multiple unsequenced modifications to}}
532   s.x + ++s.x; // no-warning TODO {{unsequenced modification and access to}}
533   ++s.x + ++s.y; // no-warning
534   s.x + ++s.y; // no-warning
535 }
536 
537 struct S3 {
538   union {
539     union {
540       unsigned x;
541     };
542   };
543   unsigned y;
544   void f3();
545 };
546 
f3()547 void S3::f3() {
548   ++x + ++x; // no-warning TODO {{multiple unsequenced modifications to}}
549   x + ++x; // no-warning TODO {{unsequenced modification and access to}}
550   ++x + ++y; // no-warning
551   x + ++y; // no-warning
552 }
553 
f3(S3 & s)554 void f3(S3 &s) {
555   ++s.x + ++s.x; // no-warning TODO {{multiple unsequenced modifications to}}
556   s.x + ++s.x; // no-warning TODO {{unsequenced modification and access to}}
557   ++s.x + ++s.y; // no-warning
558   s.x + ++s.y; // no-warning
559 }
560 
561 struct S4 : S3 {
562   unsigned y;
563   void f4();
564 };
565 
f4()566 void S4::f4() {
567   ++x + ++x; // no-warning TODO {{multiple unsequenced modifications to}}
568   x + ++x; // no-warning TODO {{unsequenced modification and access to}}
569   ++x + ++y; // no-warning
570   x + ++y; // no-warning
571   ++S3::y + ++y; // no-warning
572   S3::y + ++y; // no-warning
573 }
574 
f4(S4 & s)575 void f4(S4 &s) {
576   ++s.x + ++s.x; // no-warning TODO {{multiple unsequenced modifications to}}
577   s.x + ++s.x; // no-warning TODO {{unsequenced modification and access to}}
578   ++s.x + ++s.y; // no-warning
579   s.x + ++s.y; // no-warning
580   ++s.S3::y + ++s.y; // no-warning
581   s.S3::y + ++s.y; // no-warning
582 }
583 
584 static union {
585   unsigned Ux;
586   unsigned Uy;
587 };
588 
f5()589 void f5() {
590   ++Ux + ++Ux; // no-warning TODO {{multiple unsequenced modifications to}}
591   Ux + ++Ux; // no-warning TODO {{unsequenced modification and access to}}
592   ++Ux + ++Uy; // no-warning
593   Ux + ++Uy; // no-warning
594 }
595 
f6()596 void f6() {
597   struct S { unsigned x, y; } s;
598   ++s.x + ++s.x; // no-warning TODO {{multiple unsequenced modifications to}}
599   s.x + ++s.x; // no-warning TODO {{unsequenced modification and access to}}
600   ++s.x + ++s.y; // no-warning
601   s.x + ++s.y; // no-warning
602 
603   struct { unsigned x, y; } t;
604   ++t.x + ++t.x; // no-warning TODO {{multiple unsequenced modifications to}}
605   t.x + ++t.x; // no-warning TODO {{unsequenced modification and access to}}
606   ++t.x + ++t.y; // no-warning
607   t.x + ++t.y; // no-warning
608 }
609 
610 } // namespace members
611 
612 namespace references {
reference_f()613 void reference_f() {
614   // TODO: Check that we can see through references.
615   // For now this is completely unhandled.
616   int a;
617   int xs[10];
618   int &b = a;
619   int &c = b;
620   int &ra1 = c;
621   int &ra2 = b;
622   int other;
623 
624   ++ra1 + ++ra2; // no-warning TODO {{multiple unsequenced modifications to}}
625   ra1 + ++ra2; // no-warning TODO {{unsequenced modification and access to}}
626   ++ra1 + ++other; // no-warning
627   ra1 + ++other; // no-warning
628 
629   // Make sure we handle reference cycles.
630   int &ref_cycle = ref_cycle;
631   ++ref_cycle + ++ref_cycle; // cxx11-warning {{multiple unsequenced modifications to 'ref_cycle'}}
632                              // cxx17-warning@-1 {{multiple unsequenced modifications to 'ref_cycle'}}
633   ref_cycle + ++ref_cycle; // cxx11-warning {{unsequenced modification and access to 'ref_cycle'}}
634                            // cxx17-warning@-1 {{unsequenced modification and access to 'ref_cycle'}}
635 }
636 } // namespace references
637 
638 namespace std {
639   using size_t = decltype(sizeof(0));
640   template<typename> struct tuple_size;
641   template<size_t, typename> struct tuple_element { using type = int; };
642 }
643 namespace bindings {
644 
645   struct A { int x, y; };
646   typedef int B[2];
647   struct C { template<int> int get(); };
648   struct D : A {};
649 
650 } // namespace bindings
651 template<> struct std::tuple_size<bindings::C> { enum { value = 2 }; };
652 namespace bindings {
testa()653 void testa() {
654   A a;
655   {
656     auto [x, y] = a;
657     ++x + ++x; // cxx11-warning {{multiple unsequenced modifications to 'x'}}
658                // cxx17-warning@-1 {{multiple unsequenced modifications to 'x'}}
659     ++x + x; // cxx11-warning {{unsequenced modification and access to 'x'}}
660              // cxx17-warning@-1 {{unsequenced modification and access to 'x'}}
661     ++x + ++y; // no-warning
662     ++x + y; // no-warning
663     ++x + ++a.x; // no-warning
664     ++x + a.x; // no-warning
665   }
666   {
667     auto &[x, y] = a;
668     ++x + ++x; // cxx11-warning {{multiple unsequenced modifications to 'x'}}
669                // cxx17-warning@-1 {{multiple unsequenced modifications to 'x'}}
670     ++x + x; // cxx11-warning {{unsequenced modification and access to 'x'}}
671              // cxx17-warning@-1 {{unsequenced modification and access to 'x'}}
672     ++x + ++y; // no-warning
673     ++x + y; // no-warning
674     ++x + ++a.x; // no-warning TODO
675     ++x + a.x; // no-warning TODO
676   }
677 }
testb()678 void testb() {
679   B b;
680   {
681     auto [x, y] = b;
682     ++x + ++x; // cxx11-warning {{multiple unsequenced modifications to 'x'}}
683                // cxx17-warning@-1 {{multiple unsequenced modifications to 'x'}}
684     ++x + x; // cxx11-warning {{unsequenced modification and access to 'x'}}
685              // cxx17-warning@-1 {{unsequenced modification and access to 'x'}}
686     ++x + ++y; // no-warning
687     ++x + y; // no-warning
688     ++x + ++b[0]; // no-warning
689     ++x + b[0]; // no-warning
690   }
691   {
692     auto &[x, y] = b;
693     ++x + ++x; // cxx11-warning {{multiple unsequenced modifications to 'x'}}
694                // cxx17-warning@-1 {{multiple unsequenced modifications to 'x'}}
695     ++x + x; // cxx11-warning {{unsequenced modification and access to 'x'}}
696              // cxx17-warning@-1 {{unsequenced modification and access to 'x'}}
697     ++x + ++y; // no-warning
698     ++x + y; // no-warning
699     ++x + ++b[0]; // no-warning TODO
700     ++x + b[0]; // no-warning TODO
701   }
702 }
testc()703 void testc() {
704   C c;
705   {
706     auto [x, y] = c;
707     ++x + ++x; // cxx11-warning {{multiple unsequenced modifications to 'x'}}
708                // cxx17-warning@-1 {{multiple unsequenced modifications to 'x'}}
709     ++x + x; // cxx11-warning {{unsequenced modification and access to 'x'}}
710              // cxx17-warning@-1 {{unsequenced modification and access to 'x'}}
711     ++x + ++y; // no-warning
712     ++x + y; // no-warning
713   }
714   {
715     auto &[x, y] = c;
716     ++x + ++x; // cxx11-warning {{multiple unsequenced modifications to 'x'}}
717                // cxx17-warning@-1 {{multiple unsequenced modifications to 'x'}}
718     ++x + x; // cxx11-warning {{unsequenced modification and access to 'x'}}
719              // cxx17-warning@-1 {{unsequenced modification and access to 'x'}}
720     ++x + ++y; // no-warning
721     ++x + y; // no-warning
722   }
723 }
testd()724 void testd() {
725   D d;
726   {
727     auto [x, y] = d;
728     ++x + ++x; // cxx11-warning {{multiple unsequenced modifications to 'x'}}
729                // cxx17-warning@-1 {{multiple unsequenced modifications to 'x'}}
730     ++x + x; // cxx11-warning {{unsequenced modification and access to 'x'}}
731              // cxx17-warning@-1 {{unsequenced modification and access to 'x'}}
732     ++x + ++y; // no-warning
733     ++x + y; // no-warning
734     ++x + ++d.x; // no-warning
735     ++x + d.x; // no-warning
736   }
737   {
738     auto &[x, y] = d;
739     ++x + ++x; // cxx11-warning {{multiple unsequenced modifications to 'x'}}
740                // cxx17-warning@-1 {{multiple unsequenced modifications to 'x'}}
741     ++x + x; // cxx11-warning {{unsequenced modification and access to 'x'}}
742              // cxx17-warning@-1 {{unsequenced modification and access to 'x'}}
743     ++x + ++y; // no-warning
744     ++x + y; // no-warning
745     ++x + ++d.x; // no-warning TODO
746     ++x + d.x; // no-warning TODO
747   }
748 }
749 } // namespace bindings
750 
751 namespace templates {
752 
753 template <typename T>
754 struct Bar {
gettemplates::Bar755   T get() { return 0; }
756 };
757 
758 template <typename X>
759 struct Foo {
760   int Run();
761   Bar<int> bar;
762 };
763 
764 enum E {e1, e2};
765 bool operator&&(E, E);
766 
767 void foo(int, int);
768 
769 template <typename X>
Run()770 int Foo<X>::Run() {
771   char num = 0;
772 
773   // Before instantiation, Clang may consider the builtin operator here as
774   // unresolved function calls, and treat the arguments as unordered when
775   // the builtin operator evaluatation is well-ordered.  Waiting until
776   // instantiation to check these expressions will prevent false positives.
777   if ((num = bar.get()) < 5 && num < 10) { }
778   if ((num = bar.get()) < 5 || num < 10) { }
779   if (static_cast<E>((num = bar.get()) < 5) || static_cast<E>(num < 10)) { }
780 
781   if (static_cast<E>((num = bar.get()) < 5) && static_cast<E>(num < 10)) { }
782   // cxx11-warning@-1 {{unsequenced modification and access to 'num'}}
783 
784   foo(num++, num++);
785   // cxx11-warning@-1 {{multiple unsequenced modifications to 'num'}}
786   // cxx17-warning@-2 {{multiple unsequenced modifications to 'num'}}
787   return 1;
788 }
789 
790 int x = Foo<int>().Run();
791 // cxx11-note@-1 {{in instantiation of member function 'templates::Foo<int>::Run'}}
792 // cxx17-note@-2 {{in instantiation of member function 'templates::Foo<int>::Run'}}
793 
794 
795 template <typename T>
Run2()796 int Run2() {
797   T t = static_cast<T>(0);
798   return (t = static_cast<T>(1)) && t;
799   // cxx11-warning@-1 {{unsequenced modification and access to 't'}}
800 }
801 
802 int y = Run2<bool>();
803 int z = Run2<E>();
804 // cxx11-note@-1{{in instantiation of function template specialization 'templates::Run2<templates::E>' requested here}}
805 
806 template <typename T> int var = sizeof(T);
test_var()807 void test_var() {
808   var<int>++ + var<int>++; // cxx11-warning {{multiple unsequenced modifications to 'var<int>'}}
809                            // cxx17-warning@-1 {{multiple unsequenced modifications to 'var<int>'}}
810   var<int>++ + var<int>; // cxx11-warning {{unsequenced modification and access to 'var<int>'}}
811                          // cxx17-warning@-1 {{unsequenced modification and access to 'var<int>'}}
812   int &r = var<int>;
813   r++ + var<int>++; // no-warning TODO {{multiple unsequenced modifications to 'var<int>'}}
814   r++ + var<long>++; // no-warning
815 }
816 
817 } // namespace templates
818