]> granicus.if.org Git - clang/commitdiff
Check that the initializer of a non-dependent constexpr variable is constant even...
authorRichard Smith <richard-llvm@metafoo.co.uk>
Mon, 26 Jun 2017 20:33:42 +0000 (20:33 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Mon, 26 Jun 2017 20:33:42 +0000 (20:33 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@306327 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaDecl.cpp
test/SemaCXX/constant-expression-cxx11.cpp

index e340456bc6dad7611edadc7b5fd5622fa0699e3d..71f4d069b804ec9bbaa3ba989460f3e91bfe504e 100644 (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()) {
index 4abbc8e9284796a4058f08ac64382e861ce801d1..3fda2d0a7fd0ede6c201b27dd1ca750579200482 100644 (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 {