diff options
author | Ben Wu <soggysocks206@gmail.com> | 2025-08-19 13:49:41 -0400 |
---|---|---|
committer | Jason Merrill <jason@redhat.com> | 2025-08-19 13:49:50 -0400 |
commit | 54bf72ebfe983c611673bcc4368b5834773fcc7d (patch) | |
tree | 6aece3ea562175fa05c6d01e65b45e9b26a33669 | |
parent | 6ece2d7274059265468833fb491db44bd90de72a (diff) | |
download | gcc-54bf72ebfe983c611673bcc4368b5834773fcc7d.zip gcc-54bf72ebfe983c611673bcc4368b5834773fcc7d.tar.gz gcc-54bf72ebfe983c611673bcc4368b5834773fcc7d.tar.bz2 |
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.
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 <jason@redhat.com>
-rw-r--r-- | gcc/cp/parser.cc | 9 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/concepts/pr120618.C | 13 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp2a/concepts-requires5.C | 2 |
3 files changed, 20 insertions, 4 deletions
diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc index d66b658..40223be 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 0000000..85d2532 --- /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 524eadb..3c5a913 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" } } |