From bb5e431bf187a9f3cabb72045694fbaea414a702 Mon Sep 17 00:00:00 2001 From: Argyrios Kyrtzidis <akyrtzi@gmail.com> Date: Thu, 4 Nov 2010 03:18:57 +0000 Subject: [PATCH] Don't instantiate members not belonging in the semantic context of the template. e.g. for: template <int i> class A { class B *g; }; 'class B' has the template as lexical context but semantically it is introduced in namespace scope. Fixes rdar://8611125 & http://llvm.org/PR8505 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@118235 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaTemplateInstantiate.cpp | 12 ++++++++++++ test/CodeGenCXX/template-instantiation.cpp | 13 +++++++++++++ 2 files changed, 25 insertions(+) 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>; +} -- 2.40.0