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)));


Reply via email to