https://gcc.gnu.org/g:241f710c851aa6a8627c3ddba1e126d8e503e1b0
commit r14-10545-g241f710c851aa6a8627c3ddba1e126d8e503e1b0 Author: Patrick Palka <ppa...@redhat.com> Date: Tue Jul 23 13:16:14 2024 -0400 c++: normalizing ttp constraints [PR115656] Here we normalize the constraint same_as<T, bool> for the first time during ttp coercion of B / UU, specifically constraint subsumption checking. During this normalization the set of in-scope template parameters i.e. current_template_parms is empty, which we rely on during normalization of the ttp constraints since we pass in_decl=NULL_TREE to norm_info. And this tricks the satisfaction cache into thinking that the satisfaction value of same_as<T, bool> is independent of its template parameters, and we incorrectly conflate the satisfaction value with T = bool vs T = long and accept the specialization A<long, B>. Since is_compatible_template_arg rewrites the ttp's constraints to be in terms of the argument template's parameters, and since it's the only caller of weakly_subsumes, the latter funcion can instead pass in_decl=tmpl to avoid relying on current_template_parms. This patch implements this, and in turns renames weakly_subsumes to ttp_subsumes to reflect that this predicate is now hardcoded for this one caller. PR c++/115656 gcc/cp/ChangeLog: * constraint.cc (weakly_subsumes): Pass in_decl=tmpl to get_normalized_constraints_from_info. Rename to ... (ttp_subsumes): ... this. * cp-tree.h (weakly_subsumes): Rename to ... (ttp_subsumes): ... this. * pt.cc (is_compatible_template_arg): Adjust after renaming. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/concepts-ttp7.C: New test. Reviewed-by: Jason Merrill <ja...@redhat.com> (cherry picked from commit 2861eb34e30973cb991a7964af7cfeae014a98b0) Diff: --- gcc/cp/constraint.cc | 9 +++++---- gcc/cp/cp-tree.h | 2 +- gcc/cp/pt.cc | 2 +- gcc/testsuite/g++.dg/cpp2a/concepts-ttp7.C | 12 ++++++++++++ 4 files changed, 19 insertions(+), 6 deletions(-) diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc index 8a3b5d80ba7c..b6c6a5e23306 100644 --- a/gcc/cp/constraint.cc +++ b/gcc/cp/constraint.cc @@ -3610,13 +3610,14 @@ strictly_subsumes (tree ci, tree tmpl) return subsumes (n1, n2) && !subsumes (n2, n1); } -/* Returns true when the constraints in CI subsume the - associated constraints of TMPL. */ +/* Returns true when the template template parameter constraints in CI + subsume the associated constraints of the template template argument + TMPL. */ bool -weakly_subsumes (tree ci, tree tmpl) +ttp_subsumes (tree ci, tree tmpl) { - tree n1 = get_normalized_constraints_from_info (ci, NULL_TREE); + tree n1 = get_normalized_constraints_from_info (ci, tmpl); tree n2 = get_normalized_constraints_from_decl (tmpl); return subsumes (n1, n2); diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index ed637015a931..3f607313db61 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -8606,7 +8606,7 @@ extern tree find_template_parameters (tree, tree); extern bool equivalent_constraints (tree, tree); extern bool equivalently_constrained (tree, tree); extern bool strictly_subsumes (tree, tree); -extern bool weakly_subsumes (tree, tree); +extern bool ttp_subsumes (tree, tree); extern int more_constrained (tree, tree); extern bool at_least_as_constrained (tree, tree); extern bool constraints_equivalent_p (tree, tree); diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index 13907858273e..ea4a6c9bf530 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -8504,7 +8504,7 @@ is_compatible_template_arg (tree parm, tree arg, tree args) return false; } - return weakly_subsumes (parm_cons, arg); + return ttp_subsumes (parm_cons, arg); } // Convert a placeholder argument into a binding to the original diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-ttp7.C b/gcc/testsuite/g++.dg/cpp2a/concepts-ttp7.C new file mode 100644 index 000000000000..2ce884b995c7 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-ttp7.C @@ -0,0 +1,12 @@ +// PR c++/115656 +// { dg-do compile { target c++20 } } + +template<class T, class U> concept same_as = __is_same(T, U); + +template<same_as<bool> T, template<same_as<bool>> class UU> +struct A { }; + +template<same_as<bool>> class B; + +A<bool, B> a1; +A<long, B> a2; // { dg-error "constraint failure" }