Check that the initializer of a non-dependent constexpr variable is constant even within templates.

llvm-svn: 306327
This commit is contained in:
Richard Smith 2017-06-26 20:33:42 +00:00
parent b4fd6a6141
commit f6766bd246
2 changed files with 14 additions and 6 deletions

View File

@ -11100,9 +11100,7 @@ void Sema::CheckCompleteVariableDeclaration(VarDecl *var) {
bool IsGlobal = GlobalStorage && !var->isStaticLocal();
QualType baseType = Context.getBaseElementType(type);
if (!var->getDeclContext()->isDependentContext() &&
Init && !Init->isValueDependent()) {
if (Init && !Init->isValueDependent()) {
if (var->isConstexpr()) {
SmallVector<PartialDiagnosticAt, 8> Notes;
if (!var->evaluateValue(Notes) || !var->isInitICE()) {

View File

@ -608,7 +608,7 @@ namespace DependentValues {
struct I { int n; typedef I V[10]; };
I::V x, y;
int g();
int g(); // expected-note {{declared here}}
template<bool B, typename T> struct S : T {
int k;
void f() {
@ -616,13 +616,23 @@ template<bool B, typename T> struct S : T {
I &i = cells[k];
switch (i.n) {}
// FIXME: We should be able to diagnose this.
constexpr int n = g();
constexpr int n = g(); // expected-error {{must be initialized by a constant expression}} expected-note {{non-constexpr function 'g'}}
constexpr int m = this->g(); // ok, could be constexpr
}
};
extern const int n;
template<typename T> void f() {
// This is ill-formed, because a hypothetical instantiation at the point of
// template definition would be ill-formed due to a construct that does not
// depend on a template parameter.
constexpr int k = n; // expected-error {{must be initialized by a constant expression}}
}
// It doesn't matter that the instantiation could later become valid:
constexpr int n = 4;
template void f<int>();
}
namespace Class {