aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Wu <soggysocks206@gmail.com>2025-08-19 13:49:41 -0400
committerJason Merrill <jason@redhat.com>2025-08-19 13:49:50 -0400
commit54bf72ebfe983c611673bcc4368b5834773fcc7d (patch)
tree6aece3ea562175fa05c6d01e65b45e9b26a33669
parent6ece2d7274059265468833fb491db44bd90de72a (diff)
downloadgcc-54bf72ebfe983c611673bcc4368b5834773fcc7d.zip
gcc-54bf72ebfe983c611673bcc4368b5834773fcc7d.tar.gz
gcc-54bf72ebfe983c611673bcc4368b5834773fcc7d.tar.bz2
c++: Fix ICE on mangling invalid compound requirement [PR120618]
This testcase caused an ICE when mangling the invalid type-constraint in write_requirement since write_type_constraint expects a TEMPLATE_TYPE_PARM. Setting the trailing return type to NULL_TREE when a return-type-requirement is found in place of a type-constraint prevents the failed assertion in write_requirement. It also allows the invalid constraint to be satisfied in some contexts to prevent redundant errors, e.g. in concepts-requires5.C. Bootstrapped and tested on x86_64-linux-gnu. PR c++/120618 gcc/cp/ChangeLog: * parser.cc (cp_parser_compound_requirement): Set type to NULL_TREE for invalid type-constraint. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/concepts-requires5.C: Don't require redundant diagnostic in static assertion. * g++.dg/concepts/pr120618.C: New test. Suggested-by: Jason Merrill <jason@redhat.com>
-rw-r--r--gcc/cp/parser.cc9
-rw-r--r--gcc/testsuite/g++.dg/concepts/pr120618.C13
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/concepts-requires5.C2
3 files changed, 20 insertions, 4 deletions
diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index d66b658..40223be 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -33403,9 +33403,12 @@ cp_parser_compound_requirement (cp_parser *parser)
}
}
else
- /* P1452R2 removed the trailing-return-type option. */
- error_at (type_loc,
- "return-type-requirement is not a type-constraint");
+ {
+ /* P1452R2 removed the trailing-return-type option. */
+ error_at (type_loc,
+ "return-type-requirement is not a type-constraint");
+ type = NULL_TREE;
+ }
}
location_t loc = make_location (expr_token->location,
diff --git a/gcc/testsuite/g++.dg/concepts/pr120618.C b/gcc/testsuite/g++.dg/concepts/pr120618.C
new file mode 100644
index 0000000..85d2532
--- /dev/null
+++ b/gcc/testsuite/g++.dg/concepts/pr120618.C
@@ -0,0 +1,13 @@
+// { dg-do compile { target c++17 } }
+// { dg-options "-fconcepts" }
+
+class B{};
+
+template <typename T>
+requires (!requires(T t) { { t } -> bool; }) // { dg-error "return-type-requirement is not a type-constraint" }
+void foo(T t) {}
+
+int main() {
+ B b;
+ foo(b); // { dg-prune-output "no matching function" }
+}
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-requires5.C b/gcc/testsuite/g++.dg/cpp2a/concepts-requires5.C
index 524eadb..3c5a913 100644
--- a/gcc/testsuite/g++.dg/cpp2a/concepts-requires5.C
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-requires5.C
@@ -41,5 +41,5 @@ class D : /*private*/ B { };
void driver_2()
{
static_assert(ConvertibleTo<D, B>()); // { dg-error "cannot call" }
- static_assert(ConvertibleTo<D, B>); // { dg-error "static assertion failed" }
+ static_assert(ConvertibleTo<D, B>); // { dg-prune-output "static assertion failed" }
}