diff options
-rw-r--r-- | lib/Sema/SemaTemplateInstantiate.cpp | 5 | ||||
-rw-r--r-- | test/CXX/temp/temp.spec/p5.cpp | 17 |
2 files changed, 21 insertions, 1 deletions
diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp index 1943a2ae17..a2bd37c0bb 100644 --- a/lib/Sema/SemaTemplateInstantiate.cpp +++ b/lib/Sema/SemaTemplateInstantiate.cpp @@ -1446,7 +1446,10 @@ Sema::InstantiateClassMembers(SourceLocation PointOfInstantiation, } } } else if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(*D)) { - if (Record->isInjectedClassName()) + // Always skip the injected-class-name, along with any + // redeclarations of nested classes, since both would cause us + // to try to instantiate the members of a class twice. + if (Record->isInjectedClassName() || Record->getPreviousDeclaration()) continue; MemberSpecializationInfo *MSInfo = Record->getMemberSpecializationInfo(); diff --git a/test/CXX/temp/temp.spec/p5.cpp b/test/CXX/temp/temp.spec/p5.cpp index c37817cc49..ba99dd7093 100644 --- a/test/CXX/temp/temp.spec/p5.cpp +++ b/test/CXX/temp/temp.spec/p5.cpp @@ -27,3 +27,20 @@ template union X0<float>::Inner; // expected-error{{duplicate explicit instantia template float X0<float>::value; // expected-note{{previous explicit instantiation}} template float X0<float>::value; // expected-error{{duplicate explicit instantiation}} + +// Make sure that we don't get tricked by redeclarations of nested classes. +namespace NestedClassRedecls { + template<typename T> + struct X { + struct Nested; + friend struct Nested; + + struct Nested { + Nested() {} + } nested; + }; + + X<int> xi; + + template struct X<int>; +} |