From 15fd31835bad6f75549ed923319f7e580a3c91d8 Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Fri, 11 Jul 2014 00:20:06 +0000 Subject: [PATCH] [modules] Don't try to merge template specializations by performing name lookup into their container; we won't find them there. These things are already being merged when they're added to their primary template's folding set, so this merging is redundant (and causes us to reject-valid because we think we've found an odr violation). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@212788 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Serialization/ASTReaderDecl.cpp | 7 +++++-- test/Modules/Inputs/cxx-templates-a.h | 4 ++++ test/Modules/Inputs/cxx-templates-b.h | 4 ++++ test/Modules/Inputs/cxx-templates-common.h | 4 ++-- test/Modules/cxx-templates.cpp | 3 +++ 5 files changed, 18 insertions(+), 4 deletions(-) diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp index d8495da1ba..f9fed46ad9 100644 --- a/lib/Serialization/ASTReaderDecl.cpp +++ b/lib/Serialization/ASTReaderDecl.cpp @@ -1017,7 +1017,8 @@ ASTDeclReader::RedeclarableResult ASTDeclReader::VisitVarDeclImpl(VarDecl *VD) { switch ((VarKind)Record[Idx++]) { case VarNotTemplate: // Only true variables (not parameters or implicit parameters) can be merged - if (VD->getKind() != Decl::ParmVar && VD->getKind() != Decl::ImplicitParam) + if (VD->getKind() != Decl::ParmVar && VD->getKind() != Decl::ImplicitParam && + !isa(VD)) mergeRedeclarable(VD, Redecl); break; case VarTemplate: @@ -1438,7 +1439,9 @@ ASTDeclReader::VisitCXXRecordDeclImpl(CXXRecordDecl *D) { }; switch ((CXXRecKind)Record[Idx++]) { case CXXRecNotTemplate: - mergeRedeclarable(D, Redecl); + // Merged when we merge the folding set entry in the primary template. + if (!isa(D)) + mergeRedeclarable(D, Redecl); break; case CXXRecTemplate: { // Merged when we merge the template. diff --git a/test/Modules/Inputs/cxx-templates-a.h b/test/Modules/Inputs/cxx-templates-a.h index 12b647b52d..5ac1697bff 100644 --- a/test/Modules/Inputs/cxx-templates-a.h +++ b/test/Modules/Inputs/cxx-templates-a.h @@ -63,3 +63,7 @@ template<> struct WithExplicitSpecialization { return n; } }; + +template template +constexpr int Outer::Inner::f() { return 1; } +static_assert(Outer::Inner::f() == 1, ""); diff --git a/test/Modules/Inputs/cxx-templates-b.h b/test/Modules/Inputs/cxx-templates-b.h index a682855302..efd07c617e 100644 --- a/test/Modules/Inputs/cxx-templates-b.h +++ b/test/Modules/Inputs/cxx-templates-b.h @@ -20,6 +20,10 @@ extern DefinedInCommon &defined_in_common; template struct MergeTemplates; MergeTemplates<0> *merge_templates_b; +template template +constexpr int Outer::Inner::g() { return 2; } +static_assert(Outer::Inner::g() == 2, ""); + @import cxx_templates_b_impl; template struct Identity { typedef T type; }; diff --git a/test/Modules/Inputs/cxx-templates-common.h b/test/Modules/Inputs/cxx-templates-common.h index 986c52b362..682ef939ce 100644 --- a/test/Modules/Inputs/cxx-templates-common.h +++ b/test/Modules/Inputs/cxx-templates-common.h @@ -26,8 +26,8 @@ template struct TemplateInstantiationVisibility { typedef int type; template struct Outer { template struct Inner { - void f(); - void g(); + static constexpr int f(); + static constexpr int g(); }; }; diff --git a/test/Modules/cxx-templates.cpp b/test/Modules/cxx-templates.cpp index f68bc72a27..679d7d12b1 100644 --- a/test/Modules/cxx-templates.cpp +++ b/test/Modules/cxx-templates.cpp @@ -107,6 +107,9 @@ void g() { int &q = WithExplicitSpecializationUse().inner_template(); } +static_assert(Outer::Inner::f() == 1, ""); +static_assert(Outer::Inner::g() == 2, ""); + RedeclaredAsFriend raf1; RedeclareTemplateAsFriend rtaf; RedeclaredAsFriend raf2; -- 2.40.0