Looks like I mispelled "Merrill". Here is the corrected patch.

-Ben

On Mon, Aug 18, 2025 at 7:31 PM Ben Wu <soggysocks...@gmail.com> wrote:

> Sorry about that, I'm not sure why the formatting issues are there.
> Gmail seems to remove tabs from the patch as well. I attached the
> revised patch in case this patch still has some formatting problems like
> the indentation for error_at.
>
> I have adjusted the testcases to use dg-prune-output and bootstrapped and
> tested on x86_64-linux-gnu.
>
> Thanks,
> -Ben
>
>
> 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.
>
> Could someone help review and commit?
> Thanks.
>
>         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 Merril <ja...@redhat.com>
> ---
>  gcc/cp/parser.cc                                |  9 ++++++---
>  gcc/testsuite/g++.dg/concepts/pr120618.C        | 13 +++++++++++++
>  gcc/testsuite/g++.dg/cpp2a/concepts-requires5.C |  2 +-
>  3 files changed, 20 insertions(+), 4 deletions(-)
>  create mode 100644 gcc/testsuite/g++.dg/concepts/pr120618.C
>
> diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
> index d66b658b748..40223bedcc1 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 00000000000..85d2532a9d6
> --- /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 524eadbf5dd..3c5a9135c18 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" }
>  }
> --
> 2.43.0
>
From 30b1cea7e42b1af4856fea286ec4db9ef22a3fb6 Mon Sep 17 00:00:00 2001
From: Ben Wu <soggysocks...@gmail.com>
Date: Mon, 18 Aug 2025 17:00:17 -0700
Subject: [PATCH v3] 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. 

Could someone help review and commit?
Thanks.

	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 <ja...@redhat.com>
---
 gcc/cp/parser.cc                                |  9 ++++++---
 gcc/testsuite/g++.dg/concepts/pr120618.C        | 13 +++++++++++++
 gcc/testsuite/g++.dg/cpp2a/concepts-requires5.C |  2 +-
 3 files changed, 20 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/concepts/pr120618.C

diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index d66b658b748..40223bedcc1 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 00000000000..85d2532a9d6
--- /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 524eadbf5dd..3c5a9135c18 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" }
 }
-- 
2.43.0

Reply via email to