Here is a patch which conforms to the style requirements.

On Thu, Aug 7, 2025 at 9:30 PM Ben Wu <soggysocks...@gmail.com> 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 <quic_apin...@quicinc.com>
>
> ---
>  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 <soggysocks...@gmail.com>
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 <quic_apin...@quicinc.com>

---
 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

Reply via email to