Richard Smith 2b4fa5348e For P0784R7: compute whether a variable has constant destruction if it
has a constexpr destructor.

For constexpr variables, reject if the variable does not have constant
destruction. In all cases, do not emit runtime calls to the destructor
for variables with constant destruction.

llvm-svn: 373159
2019-09-29 05:08:46 +00:00

44 lines
1.5 KiB
C++

// RUN: %clang_cc1 -std=c++2a -verify %s
constexpr int non_class = 42;
constexpr int arr_non_class[5] = {1, 2, 3};
struct A {
int member = 1;
constexpr ~A() { member = member + 1; }
};
constexpr A class_ = {};
constexpr A arr_class[5] = {{}, {}};
struct Mutable {
mutable int member = 1; // expected-note {{declared here}}
constexpr ~Mutable() { member = member + 1; } // expected-note {{read of mutable member}}
};
constexpr Mutable mut_member; // expected-error {{must have constant destruction}} expected-note {{in call}}
struct MutableStore {
mutable int member = 1; // expected-note {{declared here}}
constexpr ~MutableStore() { member = 2; } // expected-note {{assignment to mutable member}}
};
constexpr MutableStore mut_store; // expected-error {{must have constant destruction}} expected-note {{in call}}
// Note: the constant destruction rules disallow this example even though hcm.n is a const object.
struct MutableConst {
struct HasConstMember {
const int n = 4;
};
mutable HasConstMember hcm; // expected-note {{here}}
constexpr ~MutableConst() {
int q = hcm.n; // expected-note {{read of mutable}}
}
};
constexpr MutableConst mc; // expected-error {{must have constant destruction}} expected-note {{in call}}
struct Temporary {
int &&temp;
constexpr ~Temporary() {
int n = temp; // expected-note {{outside the expression that created the temporary}}
}
};
constexpr Temporary t = {3}; // expected-error {{must have constant destruction}} expected-note {{created here}} expected-note {{in call}}