[clang] [clang] Fix template template parameter deduction for dependent non-type template parameters (CWG2398) (PR #207626)
via cfe-commits
cfe-commits at lists.llvm.org
Sun Jul 5 17:33:22 PDT 2026
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
More information about the cfe-commits
mailing list