Here is a patch which conforms to the style requirements.
On Thu, Aug 7, 2025 at 9:30 PM Ben Wu <[email protected]> wrote:
>
> PR 120618
>
> gcc/cp/ChangeLog:
>
> * constraint.cc (tsubst_compound_requirement): Return NULL_TREE when
> t1
> is not a TEMPLATE_TYPE_PARM
> (tsubst_requires_expr): Propagate failure when the compound
> requirement has an ill-formed type-constraint
>
> gcc/testsuite/ChangeLog:
>
> * g++.dg/concepts/pr120618.C: New test.
>
> This testcase caused an ICE in mangle.cc when attempting to mangle the
> compound requirement
> `requires (!requires(T t) { { t } -> bool; })`, since
> write_type_constraint expects a TEMPLATE_TYPE_PARM.
>
> When instantiating the call `foo(b)`, the constraint `requires(T t) {
> { t } -> bool; }` seems to be
> cached as a boolean_false_node, so the constraints were met due to the
> TRUTH_NOT_EXPR even though
> the type-constraint was invalid. This was Andrew's hypothesis which we
> discussed on irc, and it seems to be correct from what I
> tried to do here.
>
> This patch attempts to bail out when building a call for a function
> with an ill-formed type-constraint in a
> compound requirement.
>
> Bootstrapped and tested with check-gcc-c++ on x86_64-linux-gnu (I did
> not see new regressions with compare_tests). Could someone help
> review?
>
> Thanks.
>
> Suggested-by: Andrew Pinski <[email protected]>
>
> ---
> gcc/cp/constraint.cc | 8 ++++++++
> gcc/testsuite/g++.dg/concepts/pr120618.C | 13 +++++++++++++
> 2 files changed, 21 insertions(+)
> create mode 100644 gcc/testsuite/g++.dg/concepts/pr120618.C
>
> diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
> index cbdfafc90c0..a9f6bcc9c69 100644
> --- a/gcc/cp/constraint.cc
> +++ b/gcc/cp/constraint.cc
> @@ -1478,6 +1478,9 @@ tsubst_compound_requirement (tree t, tree args,
> sat_info info)
> {
> tree t0 = TREE_OPERAND (t, 0);
> tree t1 = TREE_OPERAND (t, 1);
> + if (t1 && TREE_CODE (t1) != TEMPLATE_TYPE_PARM)
> + return NULL_TREE;
> +
> tree expr = tsubst_valid_expression_requirement (t0, args, info);
> if (expr == error_mark_node)
> return error_mark_node;
> @@ -1744,6 +1747,11 @@ tsubst_requires_expr (tree t, tree args, sat_info info)
> else
> break;
> }
> + else if (req == NULL_TREE)
> + {
> + result = error_mark_node;
> + break;
> + }
> else if (processing_template_decl)
> result = tree_cons (NULL_TREE, req, result);
> }
> diff --git a/gcc/testsuite/g++.dg/concepts/pr120618.C
> b/gcc/testsuite/g++.dg/concepts/pr120618.C
> new file mode 100644
> index 00000000000..13f390a7aa0
> --- /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-error "no matching function" }
> +}
> --
> 2.43.0
From 60bacf53fe23bd5da7fea98610ebe15f42e4181a Mon Sep 17 00:00:00 2001
From: benwu25 <[email protected]>
Date: Fri, 8 Aug 2025 00:07:29 -0700
Subject: [PATCH] c++: fix ICE on function call with ill-formed compound
requirement [PR120618]
PR 120618
gcc/cp/ChangeLog:
* constraint.cc (tsubst_compound_requirement): Return NULL_TREE when t1
is not a TEMPLATE_TYPE_PARM
(tsubst_requires_expr): Propagate failure when the compound
requirement has an ill-formed type-constraint
gcc/testsuite/ChangeLog:
* g++.dg/concepts/pr120618.C: New test.
This testcase caused an ICE in mangle.cc when attempting to mangle the
compound requirement
`requires (!requires(T t) { { t } -> bool; })`, since
write_type_constraint expects a TEMPLATE_TYPE_PARM.
When instantiating the call `foo(b)`, the constraint `requires(T t) { { t } -> bool; }` seems to be
cached as a boolean_false_node, so the constraints were met due to the
TRUTH_NOT_EXPR even though
the type-constraint was invalid. This was Andrew's hypothesis which we
discussed on irc, and it seems to be correct from what I
tried to do here.
This patch attempts to bail out when building a call for a function
with an ill-formed type-constraint in a
compound requirement.
Bootstrapped and tested with check-gcc-c++ on x86_64-linux-gnu (I did
not see new regressions with compare_tests). Could someone help
review?
Thanks.
Suggested-by: Andrew Pinski <[email protected]>
---
gcc/cp/constraint.cc | 8 ++++++++
gcc/testsuite/g++.dg/concepts/pr120618.C | 13 +++++++++++++
2 files changed, 21 insertions(+)
create mode 100644 gcc/testsuite/g++.dg/concepts/pr120618.C
diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index cbdfafc90c0..e360323112f 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -1478,6 +1478,9 @@ tsubst_compound_requirement (tree t, tree args, sat_info info)
{
tree t0 = TREE_OPERAND (t, 0);
tree t1 = TREE_OPERAND (t, 1);
+ if (t1 && TREE_CODE (t1) != TEMPLATE_TYPE_PARM)
+ return NULL_TREE;
+
tree expr = tsubst_valid_expression_requirement (t0, args, info);
if (expr == error_mark_node)
return error_mark_node;
@@ -1744,6 +1747,11 @@ tsubst_requires_expr (tree t, tree args, sat_info info)
else
break;
}
+ else if (req == NULL_TREE)
+ {
+ result = error_mark_node;
+ break;
+ }
else if (processing_template_decl)
result = tree_cons (NULL_TREE, req, result);
}
diff --git a/gcc/testsuite/g++.dg/concepts/pr120618.C b/gcc/testsuite/g++.dg/concepts/pr120618.C
new file mode 100644
index 00000000000..cff79b4ba49
--- /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-error "no matching function" }
+}
--
2.43.0