145
|
1 // PR c++/91361 - P1152R4: Deprecating some uses of volatile.
|
|
2 // { dg-do compile { target c++2a } }
|
|
3 // { dg-options "-Wno-volatile" }
|
|
4
|
|
5 #define ACCESS_ONCE(x) (*(volatile __typeof(x) *)&(x))
|
|
6
|
|
7 struct S {
|
|
8 volatile int a : 4;
|
|
9 int b : 2;
|
|
10 };
|
|
11
|
|
12 struct T {
|
|
13 int a : 4;
|
|
14 int b : 2;
|
|
15 };
|
|
16
|
|
17 union U {
|
|
18 char c;
|
|
19 int i;
|
|
20 };
|
|
21
|
|
22 struct W {
|
|
23 W();
|
|
24 W(volatile W&);
|
|
25 W& operator=(volatile W&) volatile;
|
|
26 };
|
|
27
|
|
28 volatile int
|
|
29 fn (volatile int i)
|
|
30 {
|
|
31 volatile int v = 10;
|
|
32 int *volatile p = nullptr;
|
|
33
|
|
34 // Pre/post ++/--.
|
|
35 v++;
|
|
36 ++v;
|
|
37 v--;
|
|
38 --v;
|
|
39 p++;
|
|
40 ++p;
|
|
41 p--;
|
|
42 --p;
|
|
43 return v + i + *p;
|
|
44 }
|
|
45
|
|
46 void
|
|
47 fn2 ()
|
|
48 {
|
|
49 volatile int vi = 42;
|
|
50 int i = 24;
|
|
51
|
|
52 // Discarded-value expression ([expr.context]).
|
|
53 // The lvalue-to-rvalue conversion is applied here:
|
|
54 vi;
|
|
55 // ...but not here. Otherwise we'd write to VI and then immediately read it.
|
|
56 vi = 42;
|
|
57 vi = i;
|
|
58 vi = i = 42;
|
|
59 i = vi = 42;
|
|
60 &(vi = i);
|
|
61 (vi = 42, 45);
|
|
62 (i = vi = 42, 10);
|
|
63 i = vi; // LHS not volatile.
|
|
64 i = (vi = i, 42);
|
|
65 static_cast<void>(vi = i);
|
|
66 static_cast<void>(i = vi = 42);
|
|
67 (void)(vi = i);
|
|
68 (void)(i = vi = 42);
|
|
69
|
|
70 // Unevaluated operand.
|
|
71 decltype(vi = 42) x = vi;
|
|
72 decltype(i = vi = 42) x3 = i;
|
|
73
|
|
74 // Compound assignments.
|
|
75 vi += i;
|
|
76 vi -= i;
|
|
77 vi %= i;
|
|
78 vi ^= i;
|
|
79 vi |= i;
|
|
80 vi /= i;
|
|
81 vi = vi += 42;
|
|
82 vi += vi = 42;
|
|
83 i *= vi;
|
|
84 decltype(vi -= 42) x2 = vi;
|
|
85
|
|
86 // Structured bindings.
|
|
87 int a[] = { 10, 5 };
|
|
88 const auto & [cxr, cyr] = a;
|
|
89 const volatile auto & [cvxr, cvyr] = a;
|
|
90 volatile auto & [vxr, vyr] = a;
|
|
91 }
|
|
92
|
|
93 void
|
|
94 fn3 ()
|
|
95 {
|
|
96 volatile int i, j, k = 0;
|
|
97 i = j = k;
|
|
98
|
|
99 ACCESS_ONCE(j);
|
|
100
|
|
101 S s;
|
|
102 s.b = 1;
|
|
103
|
|
104 volatile U u;
|
|
105 u.c = 42;
|
|
106 i = u.c = 42;
|
|
107 u.c += 42;
|
|
108
|
|
109 volatile T t;
|
|
110 t.a = 3;
|
|
111 j = t.a = 3;
|
|
112 t.a += 3;
|
|
113
|
|
114 volatile int *src = &i;
|
|
115 *src; // No assignment, don't warn.
|
|
116 }
|
|
117
|
|
118 void
|
|
119 fn4 ()
|
|
120 {
|
|
121 volatile W vw;
|
|
122 W w;
|
|
123 // Assignment to objects of a class is defined by the copy/move assignment
|
|
124 // operator.
|
|
125 vw = w;
|
|
126 w = vw;
|
|
127 }
|
|
128
|
|
129 template<typename T>
|
|
130 void raccoon ()
|
|
131 {
|
|
132 volatile T t, u;
|
|
133 t = 42;
|
|
134 u = t = 42;
|
|
135 t &= 42;
|
|
136 }
|
|
137
|
|
138 void
|
|
139 fn5 ()
|
|
140 {
|
|
141 raccoon<int>();
|
|
142 }
|