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

2021-04-22 Thread Patrick Palka via Gcc-patches
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

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 000..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 
+struct lit {
+  lit(T) { }
+};
+
+template 
+int operator+(lit, lit) {
+  return 0;
+}
+
+auto r2 = (lit(0)) + lit(0);
+
+static_assert(sizeof(lit(0)));
-- 
2.31.1.362.g311531c9de



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

2021-04-22 Thread Jason Merrill via Gcc-patches

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 000..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 
+struct lit {
+  lit(T) { }
+};
+
+template 
+int operator+(lit, lit) {
+  return 0;
+}
+
+auto r2 = (lit(0)) + lit(0);
+
+static_assert(sizeof(lit(0)));