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. For some reason, compare_tests
indicates that 19 libitm tests have disappeared and 19 new libitm tests,
though the tests are identical and behave the same.

compare_tests also indicates that gcc.dg/macro-fusion-1.c and
gcc.dg/macro-fusion-2.c now pass, though I do not know why this would be
the case.

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: Avoid redundant error
    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..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" }
+}
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-requires5.C
b/gcc/testsuite/g++.dg/cpp2a/concepts-requires5.C
index 524eadbf5dd..1c68cca52ac 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>);
 }
-- 
2.43.0

Reply via email to