erik.pilkington created this revision.
erik.pilkington added reviewers: rsmith, faisalv.
erik.pilkington added a subscriber: cfe-commits.

This is a regression that only affects -std=c++1z, introduced in r273754. The 
following test case (thanks rsmith!) fails to compile:

```
template<int N> struct X {};

template<typename T> struct Y {
  static constexpr int s_v[] = {0};
  X<*s_v> x; // Clang incorrectly says: error, *s_v is not a constant expression
};

template struct Y<int>;
```

The problem is that the initializer for `s_v` (an implicitly inline variable in 
c++1z) is not instantiated. This patch requires that the initializer for an 
IncompleteArrayType is instantiated, which is the same rule as an initializer 
for an `auto` type.

Fixes PR28385.

Thanks!

http://reviews.llvm.org/D22053

Files:
  lib/Sema/SemaTemplateInstantiateDecl.cpp
  test/CXX/temp/temp.spec/temp.inst/p1.cpp

Index: test/CXX/temp/temp.spec/temp.inst/p1.cpp
===================================================================
--- test/CXX/temp/temp.spec/temp.inst/p1.cpp
+++ test/CXX/temp/temp.spec/temp.inst/p1.cpp
@@ -109,5 +109,16 @@
   int test2 = g<int>(); // expected-note {{here}}
 }
 
+namespace PR28385 {
+template <int N> struct X {};
+
+template <typename T> struct Y {
+  static constexpr int s_v[] = {0};
+  X<*s_v> x;
+};
+
+template struct Y<int>;
+}
+
 // FIXME:
 //- - member anonymous unions
Index: lib/Sema/SemaTemplateInstantiateDecl.cpp
===================================================================
--- lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -3858,11 +3858,12 @@
 
   // Delay instantiation of the initializer for variable templates or inline
   // static data members until a definition of the variable is needed. We need
-  // it right away if the type contains 'auto'.
+  // it right away if the type contains 'auto' or is an IncompleteArrayType.
   if ((!isa<VarTemplateSpecializationDecl>(NewVar) &&
        !InstantiatingVarTemplate &&
        !(OldVar->isInline() && OldVar->isThisDeclarationADefinition())) ||
-      NewVar->getType()->isUndeducedType())
+      NewVar->getType()->isUndeducedType() ||
+      NewVar->getType()->isIncompleteArrayType())
     InstantiateVariableInitializer(NewVar, OldVar, TemplateArgs);
 
   // Diagnose unused local variables with dependent types, where the diagnostic


Index: test/CXX/temp/temp.spec/temp.inst/p1.cpp
===================================================================
--- test/CXX/temp/temp.spec/temp.inst/p1.cpp
+++ test/CXX/temp/temp.spec/temp.inst/p1.cpp
@@ -109,5 +109,16 @@
   int test2 = g<int>(); // expected-note {{here}}
 }
 
+namespace PR28385 {
+template <int N> struct X {};
+
+template <typename T> struct Y {
+  static constexpr int s_v[] = {0};
+  X<*s_v> x;
+};
+
+template struct Y<int>;
+}
+
 // FIXME:
 //- - member anonymous unions
Index: lib/Sema/SemaTemplateInstantiateDecl.cpp
===================================================================
--- lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -3858,11 +3858,12 @@
 
   // Delay instantiation of the initializer for variable templates or inline
   // static data members until a definition of the variable is needed. We need
-  // it right away if the type contains 'auto'.
+  // it right away if the type contains 'auto' or is an IncompleteArrayType.
   if ((!isa<VarTemplateSpecializationDecl>(NewVar) &&
        !InstantiatingVarTemplate &&
        !(OldVar->isInline() && OldVar->isThisDeclarationADefinition())) ||
-      NewVar->getType()->isUndeducedType())
+      NewVar->getType()->isUndeducedType() ||
+      NewVar->getType()->isIncompleteArrayType())
     InstantiateVariableInitializer(NewVar, OldVar, TemplateArgs);
 
   // Diagnose unused local variables with dependent types, where the diagnostic
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to