On Tue, Nov 19, 2019 at 11:35:02PM -0500, Jason Merrill wrote:
> It would seem better to break after consuming the token, so we just skip the
> extra processing and still give the same error.
> 
> And instead of this, maybe set CP_PARSER_FLAGS_NO_TYPE_DEFINITIONS so we
> keep the same diagnostic for other type-specifiers?

That seems to work well.
So like this if it passes bootstrap/regtest?

2019-11-20  Jakub Jelinek  <ja...@redhat.com>
            Jason Merrill  <ja...@redhat.com>

        PR c++/90842
        * parser.c (cp_parser_decl_specifier_seq): For concept or typedef
        break early if CP_PARSER_FLAGS_ONLY_MUTABLE_OR_CONSTEXPR.
        For type specifiers, set CP_PARSER_FLAGS_NO_TYPE_DEFINITIONS
        if CP_PARSER_FLAGS_ONLY_MUTABLE_OR_CONSTEXPR is set.

        * g++.dg/cpp1y/lambda-generic-90842.C: New test.

--- gcc/cp/parser.c.jj  2019-11-19 22:26:46.171295670 +0100
+++ gcc/cp/parser.c     2019-11-20 10:05:27.243333499 +0100
@@ -14097,6 +14097,9 @@ cp_parser_decl_specifier_seq (cp_parser*
           ds = ds_concept;
           cp_lexer_consume_token (parser->lexer);
 
+         if (flags & CP_PARSER_FLAGS_ONLY_MUTABLE_OR_CONSTEXPR)
+           break;
+
           /* Warn for concept as a decl-specifier. We'll rewrite these as
              concept declarations later.  */
           if (!flag_concepts_ts)
@@ -14139,6 +14142,10 @@ cp_parser_decl_specifier_seq (cp_parser*
          ds = ds_typedef;
          /* Consume the token.  */
          cp_lexer_consume_token (parser->lexer);
+
+         if (flags & CP_PARSER_FLAGS_ONLY_MUTABLE_OR_CONSTEXPR)
+           break;
+
          /* A constructor declarator cannot appear in a typedef.  */
          constructor_possible_p = false;
          /* The "typedef" keyword can only occur in a declaration; we
@@ -14235,6 +14242,9 @@ cp_parser_decl_specifier_seq (cp_parser*
          bool is_cv_qualifier;
          tree type_spec;
 
+         if (flags & CP_PARSER_FLAGS_ONLY_MUTABLE_OR_CONSTEXPR)
+           flags |= CP_PARSER_FLAGS_NO_TYPE_DEFINITIONS;
+
          type_spec
            = cp_parser_type_specifier (parser, flags,
                                        decl_specs,
--- gcc/testsuite/g++.dg/cpp1y/lambda-generic-90842.C.jj        2019-11-20 
09:36:32.434390276 +0100
+++ gcc/testsuite/g++.dg/cpp1y/lambda-generic-90842.C   2019-11-20 
10:08:18.037769485 +0100
@@ -0,0 +1,10 @@
+// PR c++/90842
+// { dg-do compile { target c++14 } }
+
+auto a = [](auto x) struct C { void foo (); } {};      // { dg-error 
"expected" }
+                                                       // { dg-error 
"type-specifier invalid in lambda" "" { target *-*-* } .-1 }
+auto b = [](auto x) mutable typedef {};                        // { dg-error 
"'typedef' invalid in lambda" }
+#if __cpp_concepts >= 201907L
+auto c = [](auto x) constexpr concept {};              // { dg-error 
"'concept' invalid in lambda" "" { target c++2a } }
+#endif
+auto d = [](auto x) mutable friend {};                 // { dg-error "'friend' 
invalid in lambda" }


        Jakub

Reply via email to