PR47870: Properly mangle placeholders for deduced class template
authorRichard Smith <richard@metafoo.co.uk>
Sun, 18 Oct 2020 20:52:31 +0000 (13:52 -0700)
committerRichard Smith <richard@metafoo.co.uk>
Sun, 18 Oct 2020 20:57:41 +0000 (13:57 -0700)
specializations that have no deduced type.

clang/lib/AST/ItaniumMangle.cpp
clang/lib/Sema/SemaInit.cpp
clang/test/CodeGenCXX/cxx1z-class-deduction.cpp

index ed8fc13..26fc7f8 100644 (file)
@@ -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) {
index fc3ff14..485cb85 100644 (file)
@@ -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?
index 0761f21..8edab74 100644 (file)
@@ -19,3 +19,24 @@ void f(int *p) {
   // CHECK: @_ZN1AIxEC
   A c = 123LL;
 }
+
+namespace N {
+  template<typename T> struct B { B(T); };
+}
+using N::B;
+
+struct X {
+  template<typename T> struct C { C(T); };
+};
+
+// CHECK: @_Z1gIiEDaT_DTcv1AfL0p_E1AIS0_E(
+template<typename T> auto g(T x, decltype(A(x)), A<T>) {}
+// CHECK: @_Z1hIiEDaT_DTcvN1N1BEfL0p_ENS1_1BIS0_EE(
+template<typename T> auto h(T x, decltype(B(x)), B<T>) {}
+// CHECK: @_Z1iI1XiEDaT0_DTcvNT_1CEfL0p_ENS2_1CIS1_EE(
+template<typename U, typename T> auto i(T x, decltype(typename U::C(x)), typename U::template C<T>) {}
+void test() {
+  g(1, 2, A(3));
+  h(1, 2, B(3));
+  i<X>(1, 2, X::C(3));
+}