diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2017-06-26 20:33:42 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2017-06-26 20:33:42 +0000 |
commit | 6cfb5bf41823be28bca09fe72dd3d4b83f4e1be8 (patch) | |
tree | feee0d7293bfe84c684d266558865331c9a47666 | |
parent | f2468c5d9d036f29b7dae03c6753e8474f5cffff (diff) |
Check that the initializer of a non-dependent constexpr variable is constant even within templates.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@306327 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 4 | ||||
-rw-r--r-- | test/SemaCXX/constant-expression-cxx11.cpp | 16 |
2 files changed, 14 insertions, 6 deletions
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index e340456bc6..71f4d069b8 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -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()) { diff --git a/test/SemaCXX/constant-expression-cxx11.cpp b/test/SemaCXX/constant-expression-cxx11.cpp index 4abbc8e928..3fda2d0a7f 100644 --- a/test/SemaCXX/constant-expression-cxx11.cpp +++ b/test/SemaCXX/constant-expression-cxx11.cpp @@ -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 { |