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