Author: Younan Zhang
Date: 2025-03-24T16:46:48+08:00
New Revision: 38d71c9bdcf6b10c6fe02d5bd74fc8e6efb50a4d

URL: 
https://github.com/llvm/llvm-project/commit/38d71c9bdcf6b10c6fe02d5bd74fc8e6efb50a4d
DIFF: 
https://github.com/llvm/llvm-project/commit/38d71c9bdcf6b10c6fe02d5bd74fc8e6efb50a4d.diff

LOG: [Clang] Fix the assertion condition after b8d1f3d6 (#132669)

Thanks to the example provided by MagentaTreehouse, I realized the
assertion I added in b8d1f3d6 didn't cover all valid cases like, when
inheriting from a class template specialization, the source of a
synthesized template parameter might be an implicit specialization,
whose inner function template is thus living at depth 0, for which we
don’t want it to overflow too.

I've decided to remove that assertion because I don't think it's
particularly useful: we're checking whether Depth = 0 parameters come
from function templates whose parents contribute no template parameters
to the depth, which is redundant given what the template depth already
means.

This also incorporates a drive-by fix for
https://github.com/llvm/llvm-project/pull/132061#discussion_r2008756718,
which I somehow missed.

Added: 
    

Modified: 
    clang/lib/Sema/SemaTemplateDeductionGuide.cpp
    clang/test/SemaTemplate/deduction-guide.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Sema/SemaTemplateDeductionGuide.cpp 
b/clang/lib/Sema/SemaTemplateDeductionGuide.cpp
index 9cfdb7596b660..3b2129e0df815 100644
--- a/clang/lib/Sema/SemaTemplateDeductionGuide.cpp
+++ b/clang/lib/Sema/SemaTemplateDeductionGuide.cpp
@@ -376,12 +376,10 @@ struct ConvertConstructorToDeductionGuideTransform {
         if (NestedPattern)
           Args.addOuterRetainedLevels(NestedPattern->getTemplateDepth());
         auto [Depth, Index] = getDepthAndIndex(Param);
-        // Depth can still be 0 if FTD belongs to an explicit class template
-        // specialization with an empty template parameter list. In that case,
-        // we don't want the NewDepth to overflow, and it should remain 0.
-        assert(Depth ||
-               cast<ClassTemplateSpecializationDecl>(FTD->getDeclContext())
-                   ->isExplicitSpecialization());
+        // Depth can be 0 if FTD belongs to a non-template class/a class
+        // template specialization with an empty template parameter list. In
+        // that case, we don't want the NewDepth to overflow, and it should
+        // remain 0.
         NamedDecl *NewParam = transformTemplateParameter(
             SemaRef, DC, Param, Args, Index + Depth1IndexAdjustment,
             Depth ? Depth - 1 : 0);
@@ -970,6 +968,19 @@ getRHSTemplateDeclAndArgs(Sema &SemaRef, 
TypeAliasTemplateDecl *AliasTemplate) {
   return {Template, AliasRhsTemplateArgs};
 }
 
+bool IsNonDeducedArgument(const TemplateArgument &TA) {
+  // The following cases indicate the template argument is non-deducible:
+  //   1. The result is null. E.g. When it comes from a default template
+  //   argument that doesn't appear in the alias declaration.
+  //   2. The template parameter is a pack and that cannot be deduced from
+  //   the arguments within the alias declaration.
+  // Non-deducible template parameters will persist in the transformed
+  // deduction guide.
+  return TA.isNull() ||
+         (TA.getKind() == TemplateArgument::Pack &&
+          llvm::any_of(TA.pack_elements(), IsNonDeducedArgument));
+}
+
 // Build deduction guides for a type alias template from the given underlying
 // deduction guide F.
 FunctionTemplateDecl *
@@ -1033,20 +1044,6 @@ BuildDeductionGuideForTypeAlias(Sema &SemaRef,
       AliasRhsTemplateArgs, TDeduceInfo, DeduceResults,
       /*NumberOfArgumentsMustMatch=*/false);
 
-  static std::function<bool(const TemplateArgument &TA)> IsNonDeducedArgument =
-      [](const TemplateArgument &TA) {
-        // The following cases indicate the template argument is non-deducible:
-        //   1. The result is null. E.g. When it comes from a default template
-        //   argument that doesn't appear in the alias declaration.
-        //   2. The template parameter is a pack and that cannot be deduced 
from
-        //   the arguments within the alias declaration.
-        // Non-deducible template parameters will persist in the transformed
-        // deduction guide.
-        return TA.isNull() ||
-               (TA.getKind() == TemplateArgument::Pack &&
-                llvm::any_of(TA.pack_elements(), IsNonDeducedArgument));
-      };
-
   SmallVector<TemplateArgument> DeducedArgs;
   SmallVector<unsigned> NonDeducedTemplateParamsInFIndex;
   // !!NOTE: DeduceResults respects the sequence of template parameters of

diff  --git a/clang/test/SemaTemplate/deduction-guide.cpp 
b/clang/test/SemaTemplate/deduction-guide.cpp
index ecd152abebd74..6db132ca37c7e 100644
--- a/clang/test/SemaTemplate/deduction-guide.cpp
+++ b/clang/test/SemaTemplate/deduction-guide.cpp
@@ -723,3 +723,51 @@ void test() { NewDeleteAllocator abc(42); } // 
expected-error {{no viable constr
 // CHECK-NEXT:  `-ParmVarDecl {{.+}} 'T'
 
 } // namespace GH128691
+
+namespace GH132616_DeductionGuide {
+
+template <class T> struct A {
+  template <class U>
+  A(U);
+};
+
+template <typename>
+struct B : A<int> {
+  using A::A;
+};
+
+template <class T>
+B(T) -> B<T>;
+
+B b(24);
+
+// CHECK-LABEL: Dumping GH132616_DeductionGuide::<deduction guide for B>:
+// CHECK-NEXT: FunctionTemplateDecl {{.+}} implicit <deduction guide for B>
+// CHECK-NEXT: |-TemplateTypeParmDecl {{.+}} typename depth 0 index 0
+// CHECK-NEXT: |-TemplateTypeParmDecl {{.+}} class depth 0 index 1 U
+// CHECK-NEXT: `-CXXDeductionGuideDecl {{.+}} implicit <deduction guide for B> 
'auto (U) -> B<type-parameter-0-0>'
+// CHECK-NEXT:  `-ParmVarDecl {{.+}} 'U'
+
+struct C {
+  template <class U>
+  C(U);
+};
+
+template <typename>
+struct D : C {
+  using C::C;
+};
+
+template <class T>
+D(T) -> D<T>;
+
+D d(24);
+
+// CHECK-LABEL: Dumping GH132616_DeductionGuide::<deduction guide for D>:
+// CHECK-NEXT: FunctionTemplateDecl {{.+}} implicit <deduction guide for D>
+// CHECK-NEXT: |-TemplateTypeParmDecl {{.+}} typename depth 0 index 0
+// CHECK-NEXT: |-TemplateTypeParmDecl {{.+}} class depth 0 index 1 U
+// CHECK-NEXT: `-CXXDeductionGuideDecl {{.+}} implicit <deduction guide for D> 
'auto (U) -> D<type-parameter-0-0>'
+// CHECK-NEXT:  `-ParmVarDecl {{.+}} 'U'
+
+} // namespace GH132616_DeductionGuide


        
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to