1 | // RUN: %clang_cc1 -fsyntax-only -verify -std=c11 -Wno-unused %s |
2 | |
3 | int f(int, int); |
4 | |
5 | typedef struct A { |
6 | int x, y; |
7 | } A; |
8 | |
9 | void test() { |
10 | int a; |
11 | int xs[10]; |
12 | a + ++a; // expected-warning {{unsequenced modification and access to 'a'}} |
13 | a = ++a; // expected-warning {{multiple unsequenced modifications to 'a'}} |
14 | a + a++; // expected-warning {{unsequenced modification and access to 'a'}} |
15 | a = a++; // expected-warning {{multiple unsequenced modifications to 'a'}} |
16 | (a++, a++); // ok |
17 | ++a + ++a; // expected-warning {{multiple unsequenced modifications}} |
18 | a++ + a++; // expected-warning {{multiple unsequenced modifications}} |
19 | a = xs[++a]; // expected-warning {{multiple unsequenced modifications}} |
20 | a = xs[a++]; // expected-warning {{multiple unsequenced modifications}} |
21 | a = (++a, ++a); // expected-warning {{multiple unsequenced modifications}} |
22 | a = (a++, ++a); // expected-warning {{multiple unsequenced modifications}} |
23 | a = (a++, a++); // expected-warning {{multiple unsequenced modifications}} |
24 | f(a, a); // ok |
25 | f(a = 0, a); // expected-warning {{unsequenced modification and access}} |
26 | f(a, a += 0); // expected-warning {{unsequenced modification and access}} |
27 | f(a = 0, a = 0); // expected-warning {{multiple unsequenced modifications}} |
28 | a = f(++a, 0); // ok |
29 | a = f(a++, 0); // ok |
30 | a = f(++a, a++); // expected-warning {{multiple unsequenced modifications}} |
31 | |
32 | ++a + f(++a, 0); // expected-warning {{multiple unsequenced modifications}} |
33 | f(++a, 0) + ++a; // expected-warning {{multiple unsequenced modifications}} |
34 | a++ + f(a++, 0); // expected-warning {{multiple unsequenced modifications}} |
35 | f(a++, 0) + a++; // expected-warning {{multiple unsequenced modifications}} |
36 | |
37 | a = ++a; // expected-warning {{multiple unsequenced modifications}} |
38 | a += ++a; // expected-warning {{unsequenced modification and access}} |
39 | |
40 | A agg1 = { a++, a++ }; // expected-warning {{multiple unsequenced modifications}} |
41 | A agg2 = { a++ + a, a++ }; // expected-warning {{unsequenced modification and access}} |
42 | |
43 | (xs[2] && (a = 0)) + a; // ok |
44 | (0 && (a = 0)) + a; // ok |
45 | (1 && (a = 0)) + a; // expected-warning {{unsequenced modification and access}} |
46 | |
47 | (xs[3] || (a = 0)) + a; // ok |
48 | (0 || (a = 0)) + a; // expected-warning {{unsequenced modification and access}} |
49 | (1 || (a = 0)) + a; // ok |
50 | |
51 | (xs[4] ? a : ++a) + a; // ok |
52 | (0 ? a : ++a) + a; // expected-warning {{unsequenced modification and access}} |
53 | (1 ? a : ++a) + a; // ok |
54 | (xs[5] ? ++a : ++a) + a; // FIXME: warn here |
55 | |
56 | (++a, xs[6] ? ++a : 0) + a; // expected-warning {{unsequenced modification and access}} |
57 | |
58 | // Here, the read of the fourth 'a' might happen before or after the write to |
59 | // the second 'a'. |
60 | a += (a++, a) + a; // expected-warning {{unsequenced modification and access}} |
61 | |
62 | int *p = xs; |
63 | a = *(a++, p); // ok |
64 | a = a++ && a; // ok |
65 | |
66 | A *q = &agg1; |
67 | (q = &agg2)->y = q->x; // expected-warning {{unsequenced modification and access to 'q'}} |
68 | |
69 | // This has undefined behavior if a == 0; otherwise, the side-effect of the |
70 | // increment is sequenced before the value computation of 'f(a, a)', which is |
71 | // sequenced before the value computation of the '&&', which is sequenced |
72 | // before the assignment. We treat the sequencing in '&&' as being |
73 | // unconditional. |
74 | a = a++ && f(a, a); |
75 | |
76 | // This has undefined behavior if a != 0. FIXME: We should diagnose this. |
77 | (a && a++) + a; |
78 | |
79 | (xs[7] && ++a) * (!xs[7] && ++a); // ok |
80 | |
81 | xs[0] = (a = 1, a); // ok |
82 | |
83 | xs[8] ? ++a + a++ : 0; // expected-warning {{multiple unsequenced modifications}} |
84 | xs[8] ? 0 : ++a + a++; // expected-warning {{multiple unsequenced modifications}} |
85 | xs[8] ? ++a : a++; // ok |
86 | |
87 | xs[8] && (++a + a++); // expected-warning {{multiple unsequenced modifications}} |
88 | xs[8] || (++a + a++); // expected-warning {{multiple unsequenced modifications}} |
89 | |
90 | (__builtin_classify_type(++a) ? 1 : 0) + ++a; // ok |
91 | (__builtin_constant_p(++a) ? 1 : 0) + ++a; // ok |
92 | (__builtin_expect(++a, 0) ? 1 : 0) + ++a; // expected-warning {{multiple unsequenced modifications}} |
93 | _Generic(++a, default: 0) + ++a; // ok |
94 | sizeof(++a) + ++a; // ok |
95 | _Alignof(++a) + ++a; // expected-warning {{extension}} |
96 | } |
97 | |