From 089cd19a554a9d37d89e674a65e095646104d768 Mon Sep 17 00:00:00 2001 From: David Majnemer <david.majnemer@gmail.com> Date: Wed, 4 Dec 2013 09:01:55 +0000 Subject: [PATCH] Sema: Propagate the mangling number into instantiations We would lose track of the mangling number assigned to the original declaration which would cause us to create manglings that didn't match the Itanium C++ specification. e.g. Two static fields with the same name inside of a function template would receive the same mangling with LLVM fixing up the second field so they wouldn't collide. This would create an incompatibility with other compilers following the Itanium ABI. I've confirmed that the new mangling is identical to the ones generated by icc and gcc. N.B. This was uncovered while working on Microsoft mangler. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@196368 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaTemplateInstantiateDecl.cpp | 13 +++++++++++++ test/CodeGenCXX/mangle-template.cpp | 22 ++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index 0e6e204e661..b10cb397ffe 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -648,6 +648,8 @@ Decl *TemplateDeclInstantiator::VisitEnumDecl(EnumDecl *D) { Enum->setInstantiationOfMemberEnum(D, TSK_ImplicitInstantiation); Enum->setAccess(D->getAccess()); + // Forward the mangling number from the template to the instantiated decl. + SemaRef.Context.setManglingNumber(Enum, SemaRef.Context.getManglingNumber(D)); if (SubstQualifier(D, Enum)) return 0; Owner->addDecl(Enum); @@ -1133,6 +1135,10 @@ Decl *TemplateDeclInstantiator::VisitCXXRecordDecl(CXXRecordDecl *D) { if (D->isLocalClass()) SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, Record); + // Forward the mangling number from the template to the instantiated decl. + SemaRef.Context.setManglingNumber(Record, + SemaRef.Context.getManglingNumber(D)); + Owner->addDecl(Record); // DR1484 clarifies that the members of a local class are instantiated as part @@ -3023,6 +3029,10 @@ TemplateDeclInstantiator::InitFunctionInstantiation(FunctionDecl *New, if (Tmpl->isDeleted()) New->setDeletedAsWritten(); + // Forward the mangling number from the template to the instantiated decl. + SemaRef.Context.setManglingNumber(New, + SemaRef.Context.getManglingNumber(Tmpl)); + // If we are performing substituting explicitly-specified template arguments // or deduced template arguments into a function template and we reach this // point, we are now past the point where SFINAE applies and have committed @@ -3453,6 +3463,9 @@ void Sema::BuildVariableInstantiation( NewVar->setInstantiationOfStaticDataMember(OldVar, TSK_ImplicitInstantiation); + // Forward the mangling number from the template to the instantiated decl. + Context.setManglingNumber(NewVar, Context.getManglingNumber(OldVar)); + // Delay instantiation of the initializer for variable templates until a // definition of the variable is needed. if (!isa<VarTemplateSpecializationDecl>(NewVar) && !InstantiatingVarTemplate) diff --git a/test/CodeGenCXX/mangle-template.cpp b/test/CodeGenCXX/mangle-template.cpp index 3b7f3027f6c..9bd74b54a5b 100644 --- a/test/CodeGenCXX/mangle-template.cpp +++ b/test/CodeGenCXX/mangle-template.cpp @@ -182,3 +182,25 @@ namespace test13 { template short returnShort<-32768>(); // CHECK: @_ZN6test1311returnShortILsn32768EEEsv() } + +namespace test14 { + template <typename> inline int inl(bool b) { + if (b) { + static struct { + int field; + } a; + // CHECK: @_ZZN6test143inlIvEEibE1a + + return a.field; + } else { + static struct { + int field; + } a; + // CHECK: @_ZZN6test143inlIvEEibE1a_0 + + return a.field; + } + } + + int call(bool b) { return inl<void>(b); } +} -- GitLab