diff options
-rw-r--r-- | lib/Sema/SemaTemplateInstantiateDecl.cpp | 18 | ||||
-rw-r--r-- | test/SemaTemplate/explicit-instantiation.cpp | 7 |
2 files changed, 25 insertions, 0 deletions
diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index caeea58470..a55193aa74 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -2323,6 +2323,24 @@ void Sema::PerformPendingImplicitInstantiations(bool LocalOnly) { VarDecl *Var = cast<VarDecl>(Inst.first); assert(Var->isStaticDataMember() && "Not a static data member?"); + // Don't try to instantiate declarations if the most recent redeclaration + // is invalid. + if (Var->getMostRecentDeclaration()->isInvalidDecl()) + continue; + + // Check if the most recent declaration has changed the specialization kind + // and removed the need for implicit instantiation. + switch (Var->getMostRecentDeclaration()->getTemplateSpecializationKind()) { + case TSK_Undeclared: + assert(false && "Cannot instantitiate an undeclared specialization."); + case TSK_ExplicitInstantiationDeclaration: + case TSK_ExplicitInstantiationDefinition: + case TSK_ExplicitSpecialization: + continue; // No longer need implicit instantiation. + case TSK_ImplicitInstantiation: + break; + } + PrettyStackTraceActionsDecl CrashInfo(DeclPtrTy::make(Var), Var->getLocation(), *this, Context.getSourceManager(), diff --git a/test/SemaTemplate/explicit-instantiation.cpp b/test/SemaTemplate/explicit-instantiation.cpp index 227856f1a8..de51f0992b 100644 --- a/test/SemaTemplate/explicit-instantiation.cpp +++ b/test/SemaTemplate/explicit-instantiation.cpp @@ -76,3 +76,10 @@ template void print_type<double>(double*); // PR5069 template<int I> void foo0 (int (&)[I + 1]) { } template void foo0<2> (int (&)[3]); + +namespace explicit_instantiation_after_implicit_instantiation { + template <int I> struct X0 { static int x; }; + template <int I> int X0<I>::x; + void test1() { (void)&X0<1>::x; } + template struct X0<1>; +} |