]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++: normalizing ttp constraints [PR115656]
authorPatrick Palka <ppalka@redhat.com>
Tue, 23 Jul 2024 17:16:14 +0000 (13:16 -0400)
committerPatrick Palka <ppalka@redhat.com>
Tue, 23 Jul 2024 17:16:14 +0000 (13:16 -0400)
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>
gcc/cp/constraint.cc
gcc/cp/cp-tree.h
gcc/cp/pt.cc
gcc/testsuite/g++.dg/cpp2a/concepts-ttp7.C [new file with mode: 0644]

index afd5435cc3ed93f329719b09f2039040bf843f43..7fce78f508e9d8890d1fd3330d28ab56ff434ba0 100644 (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);
index 76ac9c31763c2e55f3bc8f88df4cc92e98e0e210..856699de82f29ed743408d09fc61fe8e4ace4dfc 100644 (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);
index 8cc5e21c520dc164149f667defb0b6bec11a3b18..393913294b504b81752385a65a68730bc044e57a 100644 (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
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-ttp7.C b/gcc/testsuite/g++.dg/cpp2a/concepts-ttp7.C
new file mode 100644 (file)
index 0000000..2ce884b
--- /dev/null
@@ -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" }