diff options
author | David Majnemer <david.majnemer@gmail.com> | 2014-10-24 20:22:57 +0000 |
---|---|---|
committer | David Majnemer <david.majnemer@gmail.com> | 2014-10-24 20:22:57 +0000 |
commit | 90a3b19e645143e320b8ea4b5ca348bc6fb34e94 (patch) | |
tree | f64c52fc1c00e55870b4e9bdcd4c9b355fdc3a9b | |
parent | 8925dc0ae0800623e882fd3c650d8ac4b6ceacf9 (diff) | |
download | bcm5719-llvm-90a3b19e645143e320b8ea4b5ca348bc6fb34e94.tar.gz bcm5719-llvm-90a3b19e645143e320b8ea4b5ca348bc6fb34e94.zip |
Itanium ABI: Template template parameters are usable as substitutions
Template template parameters weren't added to the list of substitutions.
This would make the substitution map contain inaccurate mappings,
leading to Clang violating the Itanium ABI and breaking compatibility
with GCC.
This fixes PR21351.
Differential Revision: http://reviews.llvm.org/D5959
llvm-svn: 220588
-rw-r--r-- | clang/lib/AST/ItaniumMangle.cpp | 17 | ||||
-rw-r--r-- | clang/test/CodeGenCXX/mangle.cpp | 22 |
2 files changed, 29 insertions, 10 deletions
diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index 5965ef05158..76664673d53 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -637,13 +637,11 @@ void CXXNameMangler::mangleUnscopedTemplateName(const TemplateDecl *ND) { return; // <template-template-param> ::= <template-param> - if (const TemplateTemplateParmDecl *TTP - = dyn_cast<TemplateTemplateParmDecl>(ND)) { + if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(ND)) mangleTemplateParameter(TTP->getIndex()); - return; - } + else + mangleUnscopedName(ND->getTemplatedDecl()); - mangleUnscopedName(ND->getTemplatedDecl()); addSubstitution(ND); } @@ -1563,14 +1561,13 @@ void CXXNameMangler::mangleTemplatePrefix(const TemplateDecl *ND, return; // <template-template-param> ::= <template-param> - if (const TemplateTemplateParmDecl *TTP - = dyn_cast<TemplateTemplateParmDecl>(ND)) { + if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(ND)) { mangleTemplateParameter(TTP->getIndex()); - return; + } else { + manglePrefix(getEffectiveDeclContext(ND), NoFunction); + mangleUnqualifiedName(ND->getTemplatedDecl()); } - manglePrefix(getEffectiveDeclContext(ND), NoFunction); - mangleUnqualifiedName(ND->getTemplatedDecl()); addSubstitution(ND); } diff --git a/clang/test/CodeGenCXX/mangle.cpp b/clang/test/CodeGenCXX/mangle.cpp index 9bdac7f1728..9af0d9da997 100644 --- a/clang/test/CodeGenCXX/mangle.cpp +++ b/clang/test/CodeGenCXX/mangle.cpp @@ -991,3 +991,25 @@ namespace test48 { template void f<S>(S::u *); // CHECK-LABEL: define weak_odr void @_ZN6test481fINS_1SEEEvPTuNT_1uE(%"union.test48::S::u"*) } + +namespace test49 { + template <int> + struct S {}; + + template <template <int> class T> + T<3> fin(T<3>); + + auto v = fin<S>; + // CHECK-LABEL: declare void @_ZN6test493finINS_1SEEET_ILi3EES3_() +} + +namespace test50 { + template <int> + struct S {}; + + template <template <int> class T> + T<3> fin(T<4>); + + auto v = fin<S>; + // CHECK-LABEL: declare void @_ZN6test503finINS_1SEEET_ILi3EES2_ILi4EE() +} |