aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Palka <ppalka@redhat.com>2023-03-16 14:22:54 -0400
committerPatrick Palka <ppalka@redhat.com>2023-03-16 14:22:54 -0400
commitc630157fd01140dbce120c1409c413a97dc17104 (patch)
treeb8ef90a8836d0a675f0799cf3f33314dafe9c018
parent8da8c7d337123b28fdeb539a283d00732118712e (diff)
downloadgcc-c630157fd01140dbce120c1409c413a97dc17104.zip
gcc-c630157fd01140dbce120c1409c413a97dc17104.tar.gz
gcc-c630157fd01140dbce120c1409c413a97dc17104.tar.bz2
c++: checking ICE with diagnosed constraint recursion [PR100288]
When satisfaction_cache::get detects constraint recursion, it asserts that entry->result is empty. This makes sense when we're initially detecting/diagnosing recursion from the inner recursive call, but afterwards from the outer recursive call the recursion error is treated like any other unrelated constraint failure encountered during satisfaction, and we set entry->result to whatever the satisfaction value ended up being. Perhaps we should keep entry->result cleared in this case, but that'd require the inner recursive call to communicate to the outer recursive call that constraint recursion occurred, likely via setting entry->result to some sentinel value, which doesn't seem to be worth the complexity. So this patch just relaxes the problematic assert to accept non-empty entry->result as long as we've already issued an error. PR c++/100288 gcc/cp/ChangeLog: * constraint.cc (satisfaction_cache::get): Relax overly strict checking assert in the constraint recursion case. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/concepts-recursive-sat5.C: New test.
-rw-r--r--gcc/cp/constraint.cc2
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/concepts-recursive-sat5.C13
2 files changed, 14 insertions, 1 deletions
diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index a28c851..273d15a 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -2705,7 +2705,7 @@ satisfaction_cache::get ()
if (entry->evaluating)
{
/* If we get here, it means satisfaction is self-recursive. */
- gcc_checking_assert (!entry->result);
+ gcc_checking_assert (!entry->result || seen_error ());
if (info.noisy ())
error_at (EXPR_LOCATION (ATOMIC_CONSTR_EXPR (entry->atom)),
"satisfaction of atomic constraint %qE depends on itself",
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-recursive-sat5.C b/gcc/testsuite/g++.dg/cpp2a/concepts-recursive-sat5.C
new file mode 100644
index 0000000..ba56487
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-recursive-sat5.C
@@ -0,0 +1,13 @@
+// PR c++/100288
+// { dg-do compile { target c++20 } }
+
+struct A { };
+
+template<typename T> concept pipeable = requires(A a, T t) { a | t; }; // { dg-error "depends on itself" }
+
+template<pipeable T> void operator|(A, T);
+
+void f(A tab) {
+ tab | 1; // { dg-error "no match" }
+ tab | 1; // { dg-error "no match" }
+}