[PATCH] c++: Diagnose when "requires" is used instead of "requires requires" [PR94306]
Jason Merrill
jason@redhat.com
Thu Mar 26 21:46:56 GMT 2020
On 3/26/20 5:28 PM, Patrick Palka wrote:
> This adds support to detect and recover from the case where an opening brace
> immediately follows the start of a requires-clause. So rather than emitting the
> error
>
> error: expected primary-expression before '{' token
>
> followed by a slew of irrevelant errors, we now assume the user had intended to
> write "requires requires {" and diagnose and recover accordingly.
>
> Tested on x86_64-pc-linux-gnu, does this look OK?
>
> gcc/cp/ChangeLog:
>
> PR c++/94306
> * parser.c (cp_parser_requires_clause_opt): Diagnose and recover from
> "requires {" when "requires requires {" was probably intended.
>
> gcc/testsuite/ChangeLog:
>
> PR c++/94306
> * g++.dg/concepts/diagnostic8.C: New test.
> ---
> gcc/cp/parser.c | 17 ++++++++++++++++-
> gcc/testsuite/g++.dg/concepts/diagnostic8.C | 6 ++++++
> 2 files changed, 22 insertions(+), 1 deletion(-)
> create mode 100644 gcc/testsuite/g++.dg/concepts/diagnostic8.C
>
> diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
> index 05363653691..73c2c2cb010 100644
> --- a/gcc/cp/parser.c
> +++ b/gcc/cp/parser.c
> @@ -27639,7 +27639,22 @@ cp_parser_requires_clause_opt (cp_parser *parser, bool lambda_p)
> }
> return NULL_TREE;
> }
> - cp_lexer_consume_token (parser->lexer);
> +
> + cp_token *tok2 = cp_lexer_peek_nth_token (parser->lexer, 2);
> + if (tok2->type == CPP_OPEN_BRACE)
Do we want to handle an open paren the same way?
> + {
> + /* An opening brace following the start of a requires-clause is
> + ill-formed; the user likely forgot the second `requires' that
> + would start a requires-expression. */
> + gcc_rich_location richloc (tok2->location);
> + richloc.add_fixit_insert_before (" requires");
> + error_at (&richloc, "missing additional %<requires%> to start "
> + "a requires-expression");
> + /* Don't consume the `requires', so that it's reused as the start of a
> + requires-expression. */
> + }
> + else
> + cp_lexer_consume_token (parser->lexer);
>
> if (!flag_concepts_ts)
> return cp_parser_requires_clause_expression (parser, lambda_p);
> diff --git a/gcc/testsuite/g++.dg/concepts/diagnostic8.C b/gcc/testsuite/g++.dg/concepts/diagnostic8.C
> new file mode 100644
> index 00000000000..70d7e4a9cc1
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/concepts/diagnostic8.C
> @@ -0,0 +1,6 @@
> +// PR c++/94306
> +// { dg-do compile { target c++2a } }
> +
> +template<typename T> struct S { };
> +template<typename T> requires { typename T::type; } struct S<T> { };
> +// { dg-error "missing additional .requires." "" { target *-*-* } .-1 }
>
More information about the Gcc-patches
mailing list