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