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