1 // PR c++/91361 - P1152R4: Deprecating some uses of volatile.
2 // { dg-do compile { target c++17 } }
3 // { dg-options "-Wvolatile" }
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 // { dg-warning ".volatile.-qualified return type is deprecated" }
fn(volatile int i)29 fn (volatile int i) // { dg-warning ".volatile.-qualified parameter is deprecated" }
30 {
31 volatile int v = 10;
32 int *volatile p = nullptr;
33
34 // Pre/post ++/--.
35 v++; // { dg-warning "expression of .volatile.-qualified type is deprecated" }
36 ++v; // { dg-warning "expression of .volatile.-qualified type is deprecated" }
37 v--; // { dg-warning "expression of .volatile.-qualified type is deprecated" }
38 --v; // { dg-warning "expression of .volatile.-qualified type is deprecated" }
39 p++; // { dg-warning "expression of .volatile.-qualified type is deprecated" }
40 ++p; // { dg-warning "expression of .volatile.-qualified type is deprecated" }
41 p--; // { dg-warning "expression of .volatile.-qualified type is deprecated" }
42 --p; // { dg-warning "expression of .volatile.-qualified type is deprecated" }
43 return v + i + *p;
44 }
45
46 void
fn2()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; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" }
60 &(vi = i); // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" }
61 (vi = 42, 45);
62 (i = vi = 42, 10); // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" }
63 i = vi; // LHS not volatile.
64 i = (vi = i, 42);
65 static_cast<void>(vi = i);
66 static_cast<void>(i = vi = 42); // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" }
67 (void)(vi = i);
68 (void)(i = vi = 42); // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" }
69
70 // Unevaluated operand.
71 decltype(vi = 42) x = vi;
72 decltype(i = vi = 42) x3 = i;
73
74 // Compound assignments.
75 vi += i; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" }
76 vi -= i; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" }
77 vi %= i; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" }
78 vi ^= i; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" }
79 vi |= i; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" }
80 vi /= i; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" }
81 vi = vi += 42; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" }
82 vi += vi = 42; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" }
83 i *= vi;
84 decltype(vi -= 42) x2 = vi; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" }
85
86 // Structured bindings.
87 int a[] = { 10, 5 };
88 const auto & [cxr, cyr] = a;
89 const volatile auto & [cvxr, cvyr] = a; // { dg-warning ".volatile.-qualified structured binding is deprecated" }
90 volatile auto & [vxr, vyr] = a; // { dg-warning ".volatile.-qualified structured binding is deprecated" }
91 }
92
93 void
fn3()94 fn3 ()
95 {
96 volatile int i, j, k = 0;
97 i = j = k; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" }
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; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" }
107 u.c += 42; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" }
108
109 volatile T t;
110 t.a = 3;
111 j = t.a = 3; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" }
112 t.a += 3; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" }
113
114 volatile int *src = &i;
115 *src; // No assignment, don't warn.
116 }
117
118 void
fn4()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>
raccoon()130 void raccoon ()
131 {
132 volatile T t, u;
133 t = 42;
134 u = t = 42; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" }
135 t &= 42; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" }
136 }
137
138 void
fn5()139 fn5 ()
140 {
141 raccoon<int>();
142 }
143