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
44 lines
1.5 KiB
C++
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}}
|