blob: f10a29756a9dbc286bdb8de1254d034784a6fe06 [file] [log] [blame]
// PR c++/91361 - P1152R4: Deprecating some uses of volatile.
// { dg-do compile { target c++17 } }
// { dg-options "-Wvolatile" }
#define ACCESS_ONCE(x) (*(volatile __typeof(x) *)&(x))
struct S {
volatile int a : 4;
int b : 2;
};
struct T {
int a : 4;
int b : 2;
};
union U {
char c;
int i;
};
struct W {
W();
W(volatile W&);
W& operator=(volatile W&) volatile;
};
volatile int // { dg-warning ".volatile.-qualified return type is deprecated" }
fn (volatile int i) // { dg-warning ".volatile.-qualified parameter is deprecated" }
{
volatile int v = 10;
int *volatile p = nullptr;
// Pre/post ++/--.
v++; // { dg-warning "expression of .volatile.-qualified type is deprecated" }
++v; // { dg-warning "expression of .volatile.-qualified type is deprecated" }
v--; // { dg-warning "expression of .volatile.-qualified type is deprecated" }
--v; // { dg-warning "expression of .volatile.-qualified type is deprecated" }
p++; // { dg-warning "expression of .volatile.-qualified type is deprecated" }
++p; // { dg-warning "expression of .volatile.-qualified type is deprecated" }
p--; // { dg-warning "expression of .volatile.-qualified type is deprecated" }
--p; // { dg-warning "expression of .volatile.-qualified type is deprecated" }
return v + i + *p;
}
void
fn2 ()
{
volatile int vi = 42;
int i = 24;
// Discarded-value expression ([expr.context]).
// The lvalue-to-rvalue conversion is applied here:
vi;
// ...but not here. Otherwise we'd write to VI and then immediately read it.
vi = 42;
vi = i;
vi = i = 42;
i = vi = 42; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" }
&(vi = i); // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" }
(vi = 42, 45);
(i = vi = 42, 10); // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" }
i = vi; // LHS not volatile.
i = (vi = i, 42);
static_cast<void>(vi = i);
static_cast<void>(i = vi = 42); // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" }
(void)(vi = i);
(void)(i = vi = 42); // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" }
// Unevaluated operand.
decltype(vi = 42) x = vi;
decltype(i = vi = 42) x3 = i;
// Compound assignments.
vi += i; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" }
vi -= i; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" }
vi %= i; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" }
vi ^= i; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" }
vi |= i; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" }
vi /= i; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" }
vi = vi += 42; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" }
vi += vi = 42; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" }
i *= vi;
decltype(vi -= 42) x2 = vi; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" }
// Structured bindings.
int a[] = { 10, 5 };
const auto & [cxr, cyr] = a;
const volatile auto & [cvxr, cvyr] = a; // { dg-warning ".volatile.-qualified structured binding is deprecated" }
volatile auto & [vxr, vyr] = a; // { dg-warning ".volatile.-qualified structured binding is deprecated" }
}
void
fn3 ()
{
volatile int i, j, k = 0;
i = j = k; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" }
ACCESS_ONCE(j);
S s;
s.b = 1;
volatile U u;
u.c = 42;
i = u.c = 42; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" }
u.c += 42; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" }
volatile T t;
t.a = 3;
j = t.a = 3; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" }
t.a += 3; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" }
volatile int *src = &i;
*src; // No assignment, don't warn.
}
void
fn4 ()
{
volatile W vw;
W w;
// Assignment to objects of a class is defined by the copy/move assignment
// operator.
vw = w;
w = vw;
}
template<typename T>
void raccoon ()
{
volatile T t, u;
t = 42;
u = t = 42; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" }
t &= 42; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" }
}
void
fn5 ()
{
raccoon<int>();
}