llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: AZero13 (AZero13) <details> <summary>Changes</summary> This patch addresses a regression in C++17 relaxed template template parameter matching (P0522 / CWG2398). When partial ordering template template parameters, Clang attempts to match synthesized arguments from the parameter template against the argument template. When dealing with non-type template parameters, standard function deduction rules require strictly matching the parameter's type against the argument's type. If the argument template has a dependent non-type template parameter (e.g., `template<typename T, T v>`) and the parameter template expects a non-dependent type (e.g., `template<typename U, int v>`), Clang would match `T` against `int` and incorrectly deduce `T = int`. This spurious deduction conflicts with the prior deduction of `T = U` from the type parameter, resulting in a premature substitution failure (`conflicting deduction 'U' against 'int' for parameter T`). This patch fixes this by extending the `TDF_SkipNonDependent` relaxation check during template template partial ordering. By skipping deduction when *either* the parameter or argument type is non-dependent, we prevent this spurious conflict and allow `T` to remain deduced as `U`. The final validity of the substituted value is then correctly deferred to SFINAE evaluation in `CheckTemplateArgumentList`. Fixes #<!-- -->207395 --- Full diff: https://github.com/llvm/llvm-project/pull/207626.diff 2 Files Affected: - (modified) clang/lib/Sema/SemaTemplateDeduction.cpp (+12-2) - (modified) clang/test/SemaTemplate/temp_arg_template_p0522.cpp (+10) ``````````diff diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index d93b528facbcc..91f282e487179 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -1833,10 +1833,20 @@ static TemplateDeductionResult DeduceTemplateArgumentsByTypeMatch( } } + // In the context of partial ordering (where TDF_SkipNonDependent is set), + // we may be matching a dependent parameter type (like `T` from `template<typename T, T V>`) + // against a non-dependent argument type (like `int` from `template<typename U, int>`). + // If we try to deduce `T` from `int`, we'll incorrectly deduce `T = int`, which + // conflicts with the deduction of `T = U` from the type parameter. By skipping + // deduction when either type is non-dependent, we prevent this spurious conflict + // and allow CheckTemplateArgumentList to perform the final validity check. + if (TDF & TDF_SkipNonDependent) { + if (!P->isDependentType() || !A->isDependentType()) + return TemplateDeductionResult::Success; + } + // If the parameter type is not dependent, there is nothing to deduce. if (!P->isDependentType()) { - if (TDF & TDF_SkipNonDependent) - return TemplateDeductionResult::Success; if ((TDF & TDF_IgnoreQualifiers) ? S.Context.hasSameUnqualifiedType(P, A) : S.Context.hasSameType(P, A)) return TemplateDeductionResult::Success; diff --git a/clang/test/SemaTemplate/temp_arg_template_p0522.cpp b/clang/test/SemaTemplate/temp_arg_template_p0522.cpp index bde811c3bf685..fe250e2ceeb69 100644 --- a/clang/test/SemaTemplate/temp_arg_template_p0522.cpp +++ b/clang/test/SemaTemplate/temp_arg_template_p0522.cpp @@ -175,3 +175,13 @@ namespace GH181166 { template <class ...Ts> struct B {}; using T = decltype(f<B>()); } // namespace GH181166 + +namespace CWG2398_DependentNonType { + template<typename T, T V> struct my_constant {}; + template <template<typename U, int> class Constant> void f(Constant<int, 1>); + using go = decltype(f(my_constant<int, 1>())); + + template<typename T, int V> struct my_constant2 {}; + template <template<typename U, U> class Constant> void f2(Constant<int, 1>); + using go2 = decltype(f2(my_constant2<int, 1>())); +} `````````` </details> https://github.com/llvm/llvm-project/pull/207626 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
