llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Younan Zhang (zyn0217)

<details>
<summary>Changes</summary>

We copy arguments from different template parameter lists depending on the 
deducibility of the template parameters. In particular, we may lose the default 
template argument from the original alias declaration, and this patch helps 
preserve that.

Fixes https://github.com/llvm/llvm-project/issues/133132

---
Full diff: https://github.com/llvm/llvm-project/pull/147675.diff


3 Files Affected:

- (modified) clang/docs/ReleaseNotes.rst (+1-1) 
- (modified) clang/lib/Sema/SemaTemplateDeductionGuide.cpp (+25-4) 
- (modified) clang/test/SemaCXX/cxx20-ctad-type-alias.cpp (+27-6) 


``````````diff
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 96477ef6ddc9a..2562650fcc622 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -803,7 +803,7 @@ Bug Fixes to C++ Support
 - Clang no longer crashes when trying to unify the types of arrays with
   certain differences in qualifiers (this could happen during template argument
   deduction or when building a ternary operator). (#GH97005)
-- Fixed type alias CTAD issues involving default template arguments. 
(#GH134471)
+- Fixed type alias CTAD issues involving default template arguments. 
(#GH133132), (#GH134471)
 - Fixed CTAD issues when initializing anonymous fields with designated 
initializers. (#GH67173)
 - The initialization kind of elements of structured bindings
   direct-list-initialized from an array is corrected to direct-initialization.
diff --git a/clang/lib/Sema/SemaTemplateDeductionGuide.cpp 
b/clang/lib/Sema/SemaTemplateDeductionGuide.cpp
index bdc46a0115a45..9eea2cc1dad4a 100644
--- a/clang/lib/Sema/SemaTemplateDeductionGuide.cpp
+++ b/clang/lib/Sema/SemaTemplateDeductionGuide.cpp
@@ -1061,15 +1061,36 @@ BuildDeductionGuideForTypeAlias(Sema &SemaRef,
   SmallVector<DeducedTemplateArgument> DeduceResults(
       F->getTemplateParameters()->size());
 
+  // We don't have to deduce against the alias template specialization,
+  // if the source template is a synthesized alias deduction guide. This allows
+  // us to utilize the default template arguments from alias declaration.
+  //
+  //  template <class T>
+  //  using Foo = A<A<T>>;
+  //
+  //  template <class U = int>
+  //  using Bar = Foo<U>;
+  //
+  // In terms of Bar, we want U to appear in the synthesized deduction guide,
+  // but U would remain undeduced if we deduce against A<T> instead of T.
+  // Also note that since the deduced results are only used for synthesizing
+  // template parameters, they should not introduce unintended behavior in
+  // theory.
+  ArrayRef<TemplateArgument> Ps = FReturnType->template_arguments();
+  if (auto *DG = dyn_cast<CXXDeductionGuideDecl>(F->getTemplatedDecl());
+      DG && DG->getSourceDeductionGuideKind() ==
+                CXXDeductionGuideDecl::SourceDeductionGuideKind::Alias)
+    Ps = F->getInjectedTemplateArgs(Context);
+
   // FIXME: DeduceTemplateArguments stops immediately at the first
   // non-deducible template argument. However, this doesn't seem to cause
   // issues for practice cases, we probably need to extend it to continue
   // performing deduction for rest of arguments to align with the C++
   // standard.
-  SemaRef.DeduceTemplateArguments(
-      F->getTemplateParameters(), FReturnType->template_arguments(),
-      AliasRhsTemplateArgs, TDeduceInfo, DeduceResults,
-      /*NumberOfArgumentsMustMatch=*/false);
+  SemaRef.DeduceTemplateArguments(F->getTemplateParameters(), Ps,
+                                  AliasRhsTemplateArgs, TDeduceInfo,
+                                  DeduceResults,
+                                  /*NumberOfArgumentsMustMatch=*/false);
 
   SmallVector<TemplateArgument> DeducedArgs;
   SmallVector<unsigned> NonDeducedTemplateParamsInFIndex;
diff --git a/clang/test/SemaCXX/cxx20-ctad-type-alias.cpp 
b/clang/test/SemaCXX/cxx20-ctad-type-alias.cpp
index aeb02c9e4898e..6d027130ce741 100644
--- a/clang/test/SemaCXX/cxx20-ctad-type-alias.cpp
+++ b/clang/test/SemaCXX/cxx20-ctad-type-alias.cpp
@@ -207,13 +207,14 @@ namespace test15 {
 template <class T> struct Foo { Foo(T); };
 
 template<class V> using AFoo = Foo<V *>;
-template<typename> concept False = false;
+template<typename> concept False = false; // #test15_False
 template<False W>
-using BFoo = AFoo<W>; // expected-note {{candidate template ignored: 
constraints not satisfied [with V = int]}} \
-                      // expected-note {{cannot deduce template arguments for 
'BFoo' from 'Foo<int *>'}} \
-                      // expected-note {{implicit deduction guide declared as 
'template <class V> requires __is_deducible(AFoo, Foo<V *>) && 
__is_deducible(test15::BFoo, Foo<V *>) BFoo(V *) -> Foo<V *>}} \
-                      // expected-note {{candidate template ignored: could not 
match 'Foo<V *>' against 'int *'}} \
-                      // expected-note {{template <class V> requires 
__is_deducible(AFoo, Foo<V *>) && __is_deducible(test15::BFoo, Foo<V *>) 
BFoo(Foo<V *>) -> Foo<V *>}}
+using BFoo = AFoo<W>; // expected-note {{candidate template ignored: 
constraints not satisfied [with W = int]}} \
+                      // expected-note@-1 {{because 'int' does not satisfy 
'False'}} \
+                      // expected-note@#test15_False {{because 'false' 
evaluated to false}} \
+                      // expected-note {{implicit deduction guide declared as 
'template <False<> W> requires __is_deducible(AFoo, Foo<W *>) && 
__is_deducible(test15::BFoo, Foo<W *>) BFoo(W *) -> Foo<W *>}} \
+                      // expected-note {{candidate template ignored: could not 
match 'Foo<W *>' against 'int *'}} \
+                      // expected-note {{template <False<> W> requires 
__is_deducible(AFoo, Foo<W *>) && __is_deducible(test15::BFoo, Foo<W *>) 
BFoo(Foo<W *>) -> Foo<W *>}}
 int i = 0;
 AFoo a1(&i); // OK, deduce Foo<int *>
 
@@ -539,3 +540,23 @@ using C = Proxy< A<T> >;
 C test{ 42 }; // expected-error {{no viable constructor or deduction guide for 
deduction of template arguments}}
 
 } // namespace GH125821
+
+namespace GH133132 {
+
+template <class T>
+struct A {};
+
+template <class T>
+using Foo = A<A<T>>;
+
+template <class T = int>
+using Bar = Foo<T>;
+
+template <class T = int, class U = int>
+using Baz = Bar<T>;
+
+Bar a{};
+
+Baz b{};
+
+} // namespace GH133132

``````````

</details>


https://github.com/llvm/llvm-project/pull/147675
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to