diff mbox series

c++: Hard error with tentative parse and CTAD [PR87709]

Message ID 20210422153433.3038330-1-ppalka@redhat.com
State New
Headers show
Series c++: Hard error with tentative parse and CTAD [PR87709] | expand

Commit Message

Patrick Palka April 22, 2021, 3:34 p.m. UTC
As described in detail in comment #4 of this PR, when tentatively
parsing a construct that can either be a type or an expression, if
during the type parse we encounter an unexpected template placeholder,
we need to simulate an error rather than issue a real error because the
subsequent expression parse can still succeed.

Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for
trunk?

gcc/cp/ChangeLog:

	PR c++/87709
	* parser.c (cp_parser_type_id_1): If we see a template
	placeholder, first try simulating an error before issuing a real
	error.

gcc/testsuite/ChangeLog:

	PR c++/87709
	* g++.dg/cpp1z/class-deduction86.C: New test.
---
 gcc/cp/parser.c                                | 11 +++++++----
 gcc/testsuite/g++.dg/cpp1z/class-deduction86.C | 16 ++++++++++++++++
 2 files changed, 23 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp1z/class-deduction86.C

Comments

Jason Merrill April 22, 2021, 10:16 p.m. UTC | #1
On 4/22/21 11:34 AM, Patrick Palka wrote:
> As described in detail in comment #4 of this PR, when tentatively
> parsing a construct that can either be a type or an expression, if
> during the type parse we encounter an unexpected template placeholder,
> we need to simulate an error rather than issue a real error because the
> subsequent expression parse can still succeed.
> 
> Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for
> trunk?

OK.

> gcc/cp/ChangeLog:
> 
> 	PR c++/87709
> 	* parser.c (cp_parser_type_id_1): If we see a template
> 	placeholder, first try simulating an error before issuing a real
> 	error.
> 
> gcc/testsuite/ChangeLog:
> 
> 	PR c++/87709
> 	* g++.dg/cpp1z/class-deduction86.C: New test.
> ---
>   gcc/cp/parser.c                                | 11 +++++++----
>   gcc/testsuite/g++.dg/cpp1z/class-deduction86.C | 16 ++++++++++++++++
>   2 files changed, 23 insertions(+), 4 deletions(-)
>   create mode 100644 gcc/testsuite/g++.dg/cpp1z/class-deduction86.C
> 
> diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
> index fba516efa23..e1b1617da68 100644
> --- a/gcc/cp/parser.c
> +++ b/gcc/cp/parser.c
> @@ -23270,10 +23270,13 @@ cp_parser_type_id_1 (cp_parser *parser, cp_parser_flags flags,
>   	    location_t loc = type_specifier_seq.locations[ds_type_spec];
>   	    if (tree tmpl = CLASS_PLACEHOLDER_TEMPLATE (auto_node))
>   	      {
> -		error_at (loc, "missing template arguments after %qT",
> -			  auto_node);
> -		inform (DECL_SOURCE_LOCATION (tmpl), "%qD declared here",
> -			tmpl);
> +		if (!cp_parser_simulate_error (parser))
> +		  {
> +		    error_at (loc, "missing template arguments after %qT",
> +			      auto_node);
> +		    inform (DECL_SOURCE_LOCATION (tmpl), "%qD declared here",
> +			    tmpl);
> +		  }
>   	      }
>   	    else if (parser->in_template_argument_list_p)
>   	      error_at (loc, "%qT not permitted in template argument",
> diff --git a/gcc/testsuite/g++.dg/cpp1z/class-deduction86.C b/gcc/testsuite/g++.dg/cpp1z/class-deduction86.C
> new file mode 100644
> index 00000000000..a198ed24ec6
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/cpp1z/class-deduction86.C
> @@ -0,0 +1,16 @@
> +// PR c++/87709
> +// { dg-do compile { target c++17 } }
> +
> +template <class T>
> +struct lit {
> +  lit(T) { }
> +};
> +
> +template <class T>
> +int operator+(lit<T>, lit<T>) {
> +  return 0;
> +}
> +
> +auto r2 = (lit(0)) + lit(0);
> +
> +static_assert(sizeof(lit(0)));
>
diff mbox series

Patch

diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index fba516efa23..e1b1617da68 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -23270,10 +23270,13 @@  cp_parser_type_id_1 (cp_parser *parser, cp_parser_flags flags,
 	    location_t loc = type_specifier_seq.locations[ds_type_spec];
 	    if (tree tmpl = CLASS_PLACEHOLDER_TEMPLATE (auto_node))
 	      {
-		error_at (loc, "missing template arguments after %qT",
-			  auto_node);
-		inform (DECL_SOURCE_LOCATION (tmpl), "%qD declared here",
-			tmpl);
+		if (!cp_parser_simulate_error (parser))
+		  {
+		    error_at (loc, "missing template arguments after %qT",
+			      auto_node);
+		    inform (DECL_SOURCE_LOCATION (tmpl), "%qD declared here",
+			    tmpl);
+		  }
 	      }
 	    else if (parser->in_template_argument_list_p)
 	      error_at (loc, "%qT not permitted in template argument",
diff --git a/gcc/testsuite/g++.dg/cpp1z/class-deduction86.C b/gcc/testsuite/g++.dg/cpp1z/class-deduction86.C
new file mode 100644
index 00000000000..a198ed24ec6
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/class-deduction86.C
@@ -0,0 +1,16 @@ 
+// PR c++/87709
+// { dg-do compile { target c++17 } }
+
+template <class T>
+struct lit {
+  lit(T) { }
+};
+
+template <class T>
+int operator+(lit<T>, lit<T>) {
+  return 0;
+}
+
+auto r2 = (lit(0)) + lit(0);
+
+static_assert(sizeof(lit(0)));