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>
}
}
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,
--- /dev/null
+// { 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" }
+}
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" }
}