aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Sema/SemaTemplateInstantiate.cpp12
-rw-r--r--test/CodeGenCXX/template-instantiation.cpp13
2 files changed, 25 insertions, 0 deletions
diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp
index 71235d9285..f78fe81aa8 100644
--- a/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/lib/Sema/SemaTemplateInstantiate.cpp
@@ -1223,6 +1223,18 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation,
for (RecordDecl::decl_iterator Member = Pattern->decls_begin(),
MemberEnd = Pattern->decls_end();
Member != MemberEnd; ++Member) {
+ // Don't instantiate members not belonging in this semantic context.
+ // e.g. for:
+ // @code
+ // template <int i> class A {
+ // class B *g;
+ // };
+ // @endcode
+ // 'class B' has the template as lexical context but semantically it is
+ // introduced in namespace scope.
+ if ((*Member)->getDeclContext() != Pattern)
+ continue;
+
Decl *NewMember = SubstDecl(*Member, Instantiation, TemplateArgs);
if (NewMember) {
if (FieldDecl *Field = dyn_cast<FieldDecl>(NewMember))
diff --git a/test/CodeGenCXX/template-instantiation.cpp b/test/CodeGenCXX/template-instantiation.cpp
index a8729035e2..0df2e23c70 100644
--- a/test/CodeGenCXX/template-instantiation.cpp
+++ b/test/CodeGenCXX/template-instantiation.cpp
@@ -109,3 +109,16 @@ namespace test4 {
A<int>::foo();
}
}
+
+namespace PR8505 {
+// Hits an assertion due to bogus instantiation of class B.
+template <int i> class A {
+ class B* g;
+};
+class B {
+ void f () {}
+};
+// Should not instantiate class B since it is introduced in namespace scope.
+// CHECK-NOT: _ZN6PR85051AILi0EE1B1fEv
+template class A<0>;
+}