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 <jason@redhat.com>
This commit is contained in:
Patrick Palka 2024-07-23 13:16:14 -04:00
parent f70281222d
commit 2861eb34e3
4 changed files with 19 additions and 6 deletions

View file

@ -3328,13 +3328,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);

View file

@ -8609,7 +8609,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);

View file

@ -8482,7 +8482,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

View file

@ -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" }