From 79cb179b149b20e7e1bbfd45d1b5e5b055f3b067 Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Sun, 18 Oct 2020 13:52:31 -0700 Subject: [PATCH] PR47870: Properly mangle placeholders for deduced class template specializations that have no deduced type. --- clang/lib/AST/ItaniumMangle.cpp | 19 ++++++++++++------- clang/lib/Sema/SemaInit.cpp | 4 ++-- clang/test/CodeGenCXX/cxx1z-class-deduction.cpp | 21 +++++++++++++++++++++ 3 files changed, 35 insertions(+), 9 deletions(-) diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index ed8fc13..26fc7f8 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -3668,13 +3668,18 @@ void CXXNameMangler::mangleType(const AutoType *T) { } void CXXNameMangler::mangleType(const DeducedTemplateSpecializationType *T) { - // FIXME: This is not the right mangling. We also need to include a scope - // here in some cases. - QualType D = T->getDeducedType(); - if (D.isNull()) - mangleUnscopedTemplateName(T->getTemplateName(), nullptr); - else - mangleType(D); + QualType Deduced = T->getDeducedType(); + if (!Deduced.isNull()) + mangleType(Deduced); + else if (TemplateDecl *TD = T->getTemplateName().getAsTemplateDecl()) + mangleName(GlobalDecl(TD)); + else { + // For an unresolved template-name, mangle it as if it were a template + // specialization but leave off the template arguments. + Out << 'N'; + mangleTemplatePrefix(T->getTemplateName()); + Out << 'E'; + } } void CXXNameMangler::mangleType(const AtomicType *T) { diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index fc3ff14..485cb85 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -9761,7 +9761,7 @@ QualType Sema::DeduceTemplateSpecializationFromInitializer( auto TemplateName = DeducedTST->getTemplateName(); if (TemplateName.isDependent()) - return Context.DependentTy; + return SubstAutoType(TSInfo->getType(), Context.DependentTy); // We can only perform deduction for class templates. auto *Template = @@ -9780,7 +9780,7 @@ QualType Sema::DeduceTemplateSpecializationFromInitializer( Diag(TSInfo->getTypeLoc().getBeginLoc(), diag::warn_cxx14_compat_class_template_argument_deduction) << TSInfo->getTypeLoc().getSourceRange() << 0; - return Context.DependentTy; + return SubstAutoType(TSInfo->getType(), Context.DependentTy); } // FIXME: Perform "exact type" matching first, per CWG discussion? diff --git a/clang/test/CodeGenCXX/cxx1z-class-deduction.cpp b/clang/test/CodeGenCXX/cxx1z-class-deduction.cpp index 0761f21..8edab74 100644 --- a/clang/test/CodeGenCXX/cxx1z-class-deduction.cpp +++ b/clang/test/CodeGenCXX/cxx1z-class-deduction.cpp @@ -19,3 +19,24 @@ void f(int *p) { // CHECK: @_ZN1AIxEC A c = 123LL; } + +namespace N { + template struct B { B(T); }; +} +using N::B; + +struct X { + template struct C { C(T); }; +}; + +// CHECK: @_Z1gIiEDaT_DTcv1AfL0p_E1AIS0_E( +template auto g(T x, decltype(A(x)), A) {} +// CHECK: @_Z1hIiEDaT_DTcvN1N1BEfL0p_ENS1_1BIS0_EE( +template auto h(T x, decltype(B(x)), B) {} +// CHECK: @_Z1iI1XiEDaT0_DTcvNT_1CEfL0p_ENS2_1CIS1_EE( +template auto i(T x, decltype(typename U::C(x)), typename U::template C) {} +void test() { + g(1, 2, A(3)); + h(1, 2, B(3)); + i(1, 2, X::C(3)); +} -- 2.7.4