diff mbox series

[C++] Disallow type specifiers among lambda-declarator decl-specifier-seq (PR c++/86550)

Message ID 20180717185731.GS7166@tucnak
State New
Headers show
Series [C++] Disallow type specifiers among lambda-declarator decl-specifier-seq (PR c++/86550) | expand

Commit Message

Jakub Jelinek July 17, 2018, 6:57 p.m. UTC
Hi!

The standard says:
"In the decl-specifier-seq of the lambda-declarator, each decl-specifier shall
either be mutable or constexpr."
and the C++ FE has CP_PARSER_FLAGS_ONLY_MUTABLE_OR_CONSTEXPR flag for that.
But as implemented, it is actually
CP_PARSER_FLAGS_ONLY_TYPE_OR_MUTABLE_OR_CONSTEXPR
as it allows mutable, constexpr and type specifiers.

Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, ok for
trunk?

2018-07-17  Jakub Jelinek  <jakub@redhat.com>

	PR c++/86550
	* parser.c (cp_parser_decl_specifier_seq): Don't parse a type specifier
	if CP_PARSER_FLAGS_ONLY_MUTABLE_OR_CONSTEXPR.

	* g++.dg/cpp0x/lambda/lambda-86550.C: New test.


	Jakub

Comments

Jason Merrill July 18, 2018, 1:34 a.m. UTC | #1
On Wed, Jul 18, 2018 at 4:57 AM, Jakub Jelinek <jakub@redhat.com> wrote:
> The standard says:
> "In the decl-specifier-seq of the lambda-declarator, each decl-specifier shall
> either be mutable or constexpr."
> and the C++ FE has CP_PARSER_FLAGS_ONLY_MUTABLE_OR_CONSTEXPR flag for that.
> But as implemented, it is actually
> CP_PARSER_FLAGS_ONLY_TYPE_OR_MUTABLE_OR_CONSTEXPR
> as it allows mutable, constexpr and type specifiers.
>
> Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, ok for
> trunk?
>
> 2018-07-17  Jakub Jelinek  <jakub@redhat.com>
>
>         PR c++/86550
>         * parser.c (cp_parser_decl_specifier_seq): Don't parse a type specifier
>         if CP_PARSER_FLAGS_ONLY_MUTABLE_OR_CONSTEXPR.

I think the diagnostic would be better if we parse the type-specifier
and then give an error about it being invalid in this context, rather
than not parse it and therefore give a syntax error; the constraint is
semantic rather than syntactic.

Jason
Jakub Jelinek July 18, 2018, 8:20 a.m. UTC | #2
On Wed, Jul 18, 2018 at 11:34:30AM +1000, Jason Merrill wrote:
> On Wed, Jul 18, 2018 at 4:57 AM, Jakub Jelinek <jakub@redhat.com> wrote:
> > The standard says:
> > "In the decl-specifier-seq of the lambda-declarator, each decl-specifier shall
> > either be mutable or constexpr."
> > and the C++ FE has CP_PARSER_FLAGS_ONLY_MUTABLE_OR_CONSTEXPR flag for that.
> > But as implemented, it is actually
> > CP_PARSER_FLAGS_ONLY_TYPE_OR_MUTABLE_OR_CONSTEXPR
> > as it allows mutable, constexpr and type specifiers.
> >
> > Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, ok for
> > trunk?
> >
> > 2018-07-17  Jakub Jelinek  <jakub@redhat.com>
> >
> >         PR c++/86550
> >         * parser.c (cp_parser_decl_specifier_seq): Don't parse a type specifier
> >         if CP_PARSER_FLAGS_ONLY_MUTABLE_OR_CONSTEXPR.
> 
> I think the diagnostic would be better if we parse the type-specifier
> and then give an error about it being invalid in this context, rather
> than not parse it and therefore give a syntax error; the constraint is
> semantic rather than syntactic.

So like this?
It will diagnose each bool and int separately, but that is similar to how it
will diagnose
[] () static extern thread_local inline virtual virtual explicit {}
too.

2018-07-18  Jakub Jelinek  <jakub@redhat.com>

	PR c++/86550
	* parser.c (cp_parser_decl_specifier_seq): Diagnose invalid type
	specifier if CP_PARSER_FLAGS_ONLY_MUTABLE_OR_CONSTEXPR.

	* g++.dg/cpp0x/lambda/lambda-86550.C: New test.

--- gcc/cp/parser.c.jj	2018-07-17 20:08:07.630224343 +0200
+++ gcc/cp/parser.c	2018-07-18 10:09:10.655030931 +0200
@@ -13797,6 +13797,9 @@ cp_parser_decl_specifier_seq (cp_parser*
 	      found_decl_spec = true;
 	      if (!is_cv_qualifier)
 		decl_specs->any_type_specifiers_p = true;
+
+	      if ((flags & CP_PARSER_FLAGS_ONLY_MUTABLE_OR_CONSTEXPR) != 0)
+		error_at (token->location, "type-specifier invalid in lambda");
 	    }
 	}
 
--- gcc/testsuite/g++.dg/cpp0x/lambda/lambda-86550.C.jj	2018-07-18 10:05:02.894767883 +0200
+++ gcc/testsuite/g++.dg/cpp0x/lambda/lambda-86550.C	2018-07-18 10:13:41.373318350 +0200
@@ -0,0 +1,9 @@
+// PR c++/86550
+// { dg-do compile { target c++11 } }
+
+void
+foo ()
+{
+  auto a = []() bool {};			// { dg-error "type-specifier invalid in lambda" }
+  auto b = []() bool bool bool bool int {};	// { dg-error "type-specifier invalid in lambda" }
+}


	Jakub
Jason Merrill July 18, 2018, 12:29 p.m. UTC | #3
OK.

On Wed, Jul 18, 2018 at 6:20 PM, Jakub Jelinek <jakub@redhat.com> wrote:
> On Wed, Jul 18, 2018 at 11:34:30AM +1000, Jason Merrill wrote:
>> On Wed, Jul 18, 2018 at 4:57 AM, Jakub Jelinek <jakub@redhat.com> wrote:
>> > The standard says:
>> > "In the decl-specifier-seq of the lambda-declarator, each decl-specifier shall
>> > either be mutable or constexpr."
>> > and the C++ FE has CP_PARSER_FLAGS_ONLY_MUTABLE_OR_CONSTEXPR flag for that.
>> > But as implemented, it is actually
>> > CP_PARSER_FLAGS_ONLY_TYPE_OR_MUTABLE_OR_CONSTEXPR
>> > as it allows mutable, constexpr and type specifiers.
>> >
>> > Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, ok for
>> > trunk?
>> >
>> > 2018-07-17  Jakub Jelinek  <jakub@redhat.com>
>> >
>> >         PR c++/86550
>> >         * parser.c (cp_parser_decl_specifier_seq): Don't parse a type specifier
>> >         if CP_PARSER_FLAGS_ONLY_MUTABLE_OR_CONSTEXPR.
>>
>> I think the diagnostic would be better if we parse the type-specifier
>> and then give an error about it being invalid in this context, rather
>> than not parse it and therefore give a syntax error; the constraint is
>> semantic rather than syntactic.
>
> So like this?
> It will diagnose each bool and int separately, but that is similar to how it
> will diagnose
> [] () static extern thread_local inline virtual virtual explicit {}
> too.
>
> 2018-07-18  Jakub Jelinek  <jakub@redhat.com>
>
>         PR c++/86550
>         * parser.c (cp_parser_decl_specifier_seq): Diagnose invalid type
>         specifier if CP_PARSER_FLAGS_ONLY_MUTABLE_OR_CONSTEXPR.
>
>         * g++.dg/cpp0x/lambda/lambda-86550.C: New test.
>
> --- gcc/cp/parser.c.jj  2018-07-17 20:08:07.630224343 +0200
> +++ gcc/cp/parser.c     2018-07-18 10:09:10.655030931 +0200
> @@ -13797,6 +13797,9 @@ cp_parser_decl_specifier_seq (cp_parser*
>               found_decl_spec = true;
>               if (!is_cv_qualifier)
>                 decl_specs->any_type_specifiers_p = true;
> +
> +             if ((flags & CP_PARSER_FLAGS_ONLY_MUTABLE_OR_CONSTEXPR) != 0)
> +               error_at (token->location, "type-specifier invalid in lambda");
>             }
>         }
>
> --- gcc/testsuite/g++.dg/cpp0x/lambda/lambda-86550.C.jj 2018-07-18 10:05:02.894767883 +0200
> +++ gcc/testsuite/g++.dg/cpp0x/lambda/lambda-86550.C    2018-07-18 10:13:41.373318350 +0200
> @@ -0,0 +1,9 @@
> +// PR c++/86550
> +// { dg-do compile { target c++11 } }
> +
> +void
> +foo ()
> +{
> +  auto a = []() bool {};                       // { dg-error "type-specifier invalid in lambda" }
> +  auto b = []() bool bool bool bool int {};    // { dg-error "type-specifier invalid in lambda" }
> +}
>
>
>         Jakub
diff mbox series

Patch

--- gcc/cp/parser.c.jj	2018-07-16 09:42:24.534984748 +0200
+++ gcc/cp/parser.c	2018-07-17 16:22:03.208497718 +0200
@@ -13738,7 +13738,9 @@  cp_parser_decl_specifier_seq (cp_parser*
 
       /* If we don't have a DECL_SPEC yet, then we must be looking at
 	 a type-specifier.  */
-      if (!found_decl_spec && !constructor_p)
+      if (!found_decl_spec
+	  && !constructor_p
+	  && !(flags & CP_PARSER_FLAGS_ONLY_MUTABLE_OR_CONSTEXPR))
 	{
 	  int decl_spec_declares_class_or_enum;
 	  bool is_cv_qualifier;
--- gcc/testsuite/g++.dg/cpp0x/lambda/lambda-86550.C.jj	2018-07-17 16:24:09.966665292 +0200
+++ gcc/testsuite/g++.dg/cpp0x/lambda/lambda-86550.C	2018-07-17 16:29:22.558078546 +0200
@@ -0,0 +1,9 @@ 
+// PR c++/86550
+// { dg-do compile { target c++11 } }
+
+void
+foo ()
+{
+  auto a = []() bool {};			// { dg-error "expected" }
+  auto b = []() bool bool bool bool int {};	// { dg-error "expected" }
+}