1418dd3eb3e813235af089b5c88182941f8a03d20Richard Smith// RUN: %clang_cc1 -fsyntax-only -verify -std=c11 -Wno-unused %s
2418dd3eb3e813235af089b5c88182941f8a03d20Richard Smith
3418dd3eb3e813235af089b5c88182941f8a03d20Richard Smithint f(int, int);
4418dd3eb3e813235af089b5c88182941f8a03d20Richard Smith
5418dd3eb3e813235af089b5c88182941f8a03d20Richard Smithtypedef struct A {
6418dd3eb3e813235af089b5c88182941f8a03d20Richard Smith  int x, y;
7418dd3eb3e813235af089b5c88182941f8a03d20Richard Smith} A;
8418dd3eb3e813235af089b5c88182941f8a03d20Richard Smith
9418dd3eb3e813235af089b5c88182941f8a03d20Richard Smithvoid test() {
10418dd3eb3e813235af089b5c88182941f8a03d20Richard Smith  int a;
11418dd3eb3e813235af089b5c88182941f8a03d20Richard Smith  int xs[10];
12418dd3eb3e813235af089b5c88182941f8a03d20Richard Smith  a + ++a; // expected-warning {{unsequenced modification and access to 'a'}}
13418dd3eb3e813235af089b5c88182941f8a03d20Richard Smith  a = ++a; // expected-warning {{multiple unsequenced modifications to 'a'}}
14418dd3eb3e813235af089b5c88182941f8a03d20Richard Smith  a + a++; // expected-warning {{unsequenced modification and access to 'a'}}
15418dd3eb3e813235af089b5c88182941f8a03d20Richard Smith  a = a++; // expected-warning {{multiple unsequenced modifications to 'a'}}
16418dd3eb3e813235af089b5c88182941f8a03d20Richard Smith  (a++, a++); // ok
17418dd3eb3e813235af089b5c88182941f8a03d20Richard Smith  ++a + ++a; // expected-warning {{multiple unsequenced modifications}}
18418dd3eb3e813235af089b5c88182941f8a03d20Richard Smith  a++ + a++; // expected-warning {{multiple unsequenced modifications}}
19418dd3eb3e813235af089b5c88182941f8a03d20Richard Smith  a = xs[++a]; // expected-warning {{multiple unsequenced modifications}}
20418dd3eb3e813235af089b5c88182941f8a03d20Richard Smith  a = xs[a++]; // expected-warning {{multiple unsequenced modifications}}
21418dd3eb3e813235af089b5c88182941f8a03d20Richard Smith  a = (++a, ++a); // expected-warning {{multiple unsequenced modifications}}
22418dd3eb3e813235af089b5c88182941f8a03d20Richard Smith  a = (a++, ++a); // expected-warning {{multiple unsequenced modifications}}
23418dd3eb3e813235af089b5c88182941f8a03d20Richard Smith  a = (a++, a++); // expected-warning {{multiple unsequenced modifications}}
24418dd3eb3e813235af089b5c88182941f8a03d20Richard Smith  f(a, a); // ok
25418dd3eb3e813235af089b5c88182941f8a03d20Richard Smith  f(a = 0, a); // expected-warning {{unsequenced modification and access}}
26418dd3eb3e813235af089b5c88182941f8a03d20Richard Smith  f(a, a += 0); // expected-warning {{unsequenced modification and access}}
27418dd3eb3e813235af089b5c88182941f8a03d20Richard Smith  f(a = 0, a = 0); // expected-warning {{multiple unsequenced modifications}}
280c0b3909d11de7440d77556089516918b9c04cefRichard Smith  a = f(++a, 0); // ok
290c0b3909d11de7440d77556089516918b9c04cefRichard Smith  a = f(a++, 0); // ok
300c0b3909d11de7440d77556089516918b9c04cefRichard Smith  a = f(++a, a++); // expected-warning {{multiple unsequenced modifications}}
31418dd3eb3e813235af089b5c88182941f8a03d20Richard Smith
320e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  ++a + f(++a, 0); // expected-warning {{multiple unsequenced modifications}}
330e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  f(++a, 0) + ++a; // expected-warning {{multiple unsequenced modifications}}
340e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  a++ + f(a++, 0); // expected-warning {{multiple unsequenced modifications}}
350e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  f(a++, 0) + a++; // expected-warning {{multiple unsequenced modifications}}
360e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
37418dd3eb3e813235af089b5c88182941f8a03d20Richard Smith  a = ++a; // expected-warning {{multiple unsequenced modifications}}
38418dd3eb3e813235af089b5c88182941f8a03d20Richard Smith  a += ++a; // expected-warning {{unsequenced modification and access}}
39418dd3eb3e813235af089b5c88182941f8a03d20Richard Smith
40418dd3eb3e813235af089b5c88182941f8a03d20Richard Smith  A agg1 = { a++, a++ }; // expected-warning {{multiple unsequenced modifications}}
41418dd3eb3e813235af089b5c88182941f8a03d20Richard Smith  A agg2 = { a++ + a, a++ }; // expected-warning {{unsequenced modification and access}}
42418dd3eb3e813235af089b5c88182941f8a03d20Richard Smith
43418dd3eb3e813235af089b5c88182941f8a03d20Richard Smith  (xs[2] && (a = 0)) + a; // ok
44418dd3eb3e813235af089b5c88182941f8a03d20Richard Smith  (0 && (a = 0)) + a; // ok
45418dd3eb3e813235af089b5c88182941f8a03d20Richard Smith  (1 && (a = 0)) + a; // expected-warning {{unsequenced modification and access}}
46418dd3eb3e813235af089b5c88182941f8a03d20Richard Smith
47418dd3eb3e813235af089b5c88182941f8a03d20Richard Smith  (xs[3] || (a = 0)) + a; // ok
48418dd3eb3e813235af089b5c88182941f8a03d20Richard Smith  (0 || (a = 0)) + a; // expected-warning {{unsequenced modification and access}}
49418dd3eb3e813235af089b5c88182941f8a03d20Richard Smith  (1 || (a = 0)) + a; // ok
50418dd3eb3e813235af089b5c88182941f8a03d20Richard Smith
51418dd3eb3e813235af089b5c88182941f8a03d20Richard Smith  (xs[4] ? a : ++a) + a; // ok
52418dd3eb3e813235af089b5c88182941f8a03d20Richard Smith  (0 ? a : ++a) + a; // expected-warning {{unsequenced modification and access}}
53418dd3eb3e813235af089b5c88182941f8a03d20Richard Smith  (1 ? a : ++a) + a; // ok
54418dd3eb3e813235af089b5c88182941f8a03d20Richard Smith  (xs[5] ? ++a : ++a) + a; // FIXME: warn here
55418dd3eb3e813235af089b5c88182941f8a03d20Richard Smith
560e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  (++a, xs[6] ? ++a : 0) + a; // expected-warning {{unsequenced modification and access}}
57418dd3eb3e813235af089b5c88182941f8a03d20Richard Smith
58418dd3eb3e813235af089b5c88182941f8a03d20Richard Smith  // Here, the read of the fourth 'a' might happen before or after the write to
59418dd3eb3e813235af089b5c88182941f8a03d20Richard Smith  // the second 'a'.
60418dd3eb3e813235af089b5c88182941f8a03d20Richard Smith  a += (a++, a) + a; // expected-warning {{unsequenced modification and access}}
61418dd3eb3e813235af089b5c88182941f8a03d20Richard Smith
62418dd3eb3e813235af089b5c88182941f8a03d20Richard Smith  int *p = xs;
63418dd3eb3e813235af089b5c88182941f8a03d20Richard Smith  a = *(a++, p); // ok
64418dd3eb3e813235af089b5c88182941f8a03d20Richard Smith  a = a++ && a; // ok
65418dd3eb3e813235af089b5c88182941f8a03d20Richard Smith
66418dd3eb3e813235af089b5c88182941f8a03d20Richard Smith  A *q = &agg1;
67418dd3eb3e813235af089b5c88182941f8a03d20Richard Smith  (q = &agg2)->y = q->x; // expected-warning {{unsequenced modification and access to 'q'}}
68418dd3eb3e813235af089b5c88182941f8a03d20Richard Smith
69418dd3eb3e813235af089b5c88182941f8a03d20Richard Smith  // This has undefined behavior if a == 0; otherwise, the side-effect of the
70418dd3eb3e813235af089b5c88182941f8a03d20Richard Smith  // increment is sequenced before the value computation of 'f(a, a)', which is
71418dd3eb3e813235af089b5c88182941f8a03d20Richard Smith  // sequenced before the value computation of the '&&', which is sequenced
72418dd3eb3e813235af089b5c88182941f8a03d20Richard Smith  // before the assignment. We treat the sequencing in '&&' as being
73418dd3eb3e813235af089b5c88182941f8a03d20Richard Smith  // unconditional.
74418dd3eb3e813235af089b5c88182941f8a03d20Richard Smith  a = a++ && f(a, a);
75418dd3eb3e813235af089b5c88182941f8a03d20Richard Smith
76418dd3eb3e813235af089b5c88182941f8a03d20Richard Smith  // This has undefined behavior if a != 0. FIXME: We should diagnose this.
77418dd3eb3e813235af089b5c88182941f8a03d20Richard Smith  (a && a++) + a;
78418dd3eb3e813235af089b5c88182941f8a03d20Richard Smith
79418dd3eb3e813235af089b5c88182941f8a03d20Richard Smith  (xs[7] && ++a) * (!xs[7] && ++a); // ok
80418dd3eb3e813235af089b5c88182941f8a03d20Richard Smith
81418dd3eb3e813235af089b5c88182941f8a03d20Richard Smith  xs[0] = (a = 1, a); // ok
82418dd3eb3e813235af089b5c88182941f8a03d20Richard Smith
83418dd3eb3e813235af089b5c88182941f8a03d20Richard Smith  xs[8] ? ++a + a++ : 0; // expected-warning {{multiple unsequenced modifications}}
84418dd3eb3e813235af089b5c88182941f8a03d20Richard Smith  xs[8] ? 0 : ++a + a++; // expected-warning {{multiple unsequenced modifications}}
85418dd3eb3e813235af089b5c88182941f8a03d20Richard Smith  xs[8] ? ++a : a++; // ok
86418dd3eb3e813235af089b5c88182941f8a03d20Richard Smith
87418dd3eb3e813235af089b5c88182941f8a03d20Richard Smith  xs[8] && (++a + a++); // expected-warning {{multiple unsequenced modifications}}
88418dd3eb3e813235af089b5c88182941f8a03d20Richard Smith  xs[8] || (++a + a++); // expected-warning {{multiple unsequenced modifications}}
89418dd3eb3e813235af089b5c88182941f8a03d20Richard Smith
90418dd3eb3e813235af089b5c88182941f8a03d20Richard Smith  (__builtin_classify_type(++a) ? 1 : 0) + ++a; // ok
91418dd3eb3e813235af089b5c88182941f8a03d20Richard Smith  (__builtin_constant_p(++a) ? 1 : 0) + ++a; // ok
920e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  (__builtin_expect(++a, 0) ? 1 : 0) + ++a; // expected-warning {{multiple unsequenced modifications}}
930e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  _Generic(++a, default: 0) + ++a; // ok
940e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  sizeof(++a) + ++a; // ok
950e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  _Alignof(++a) + ++a; // expected-warning {{extension}}
96418dd3eb3e813235af089b5c88182941f8a03d20Richard Smith}
97