From: Jakub Jelinek <jakub@redhat.com>
To: Jason Merrill <jason@redhat.com>
Cc: gcc-patches@gcc.gnu.org
Subject: [PATCH] c++: Implement P1102R2 - Down with ()!
Date: Thu, 25 Feb 2021 19:44:21 +0100 [thread overview]
Message-ID: <20210225184421.GL4020736@tucnak> (raw)
Hi!
The following patch implements P1102R2.
For attributes, we have already attribute parsing before the parameter
declarations and so when that is omitted, if the attributes are first we
already accept it.
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
Or defer for GCC 12?
2021-02-25 Jakub Jelinek <jakub@redhat.com>
P1102R2 - Down with ()!
* parser.c (cp_parser_lambda_declarator_opt): Make ()s
optional before lambda specifiers for -std={c,gnu}++2b or
with pedwarn in earlier versions.
* g++.dg/cpp23/lambda-specifiers1.C: New test.
--- gcc/cp/parser.c.jj 2021-02-12 09:58:25.341506456 +0100
+++ gcc/cp/parser.c 2021-02-25 14:28:37.525431561 +0100
@@ -11223,12 +11223,12 @@ cp_parser_lambda_introducer (cp_parser*
/* Parse the (optional) middle of a lambda expression.
lambda-declarator:
- ( parameter-declaration-clause )
- decl-specifier-seq [opt]
- noexcept-specifier [opt]
- attribute-specifier-seq [opt]
- trailing-return-type [opt]
- requires-clause [opt]
+ ( parameter-declaration-clause ) lambda-specifiers requires-clause [opt]
+ lambda-specifiers (C++23)
+
+ lambda-specifiers:
+ decl-specifier-seq [opt] noexcept-specifier [opt]
+ attribute-specifier-seq [opt] trailing-return-type [opt]
LAMBDA_EXPR is the current representation of the lambda expression. */
@@ -11248,6 +11248,8 @@ cp_parser_lambda_declarator_opt (cp_pars
tree tx_qual = NULL_TREE;
tree return_type = NULL_TREE;
tree trailing_requires_clause = NULL_TREE;
+ bool has_param_list = false;
+ location_t lambda_specifiers_loc = UNKNOWN_LOCATION;
cp_decl_specifier_seq lambda_specs;
clear_decl_specs (&lambda_specs);
/* A lambda op() is const unless explicitly 'mutable'. */
@@ -11334,47 +11336,88 @@ cp_parser_lambda_declarator_opt (cp_pars
"default argument specified for lambda parameter");
parens.require_close (parser);
+ has_param_list = true;
+ }
+ else if (cxx_dialect < cxx23)
+ lambda_specifiers_loc = cp_lexer_peek_token (parser->lexer)->location;
- /* In the decl-specifier-seq of the lambda-declarator, each
- decl-specifier shall either be mutable or constexpr. */
- int declares_class_or_enum;
- if (cp_lexer_next_token_is_decl_specifier_keyword (parser->lexer)
- && !cp_next_tokens_can_be_gnu_attribute_p (parser))
- cp_parser_decl_specifier_seq (parser,
- CP_PARSER_FLAGS_ONLY_MUTABLE_OR_CONSTEXPR,
- &lambda_specs, &declares_class_or_enum);
- if (lambda_specs.storage_class == sc_mutable)
- {
- LAMBDA_EXPR_MUTABLE_P (lambda_expr) = 1;
- quals = TYPE_UNQUALIFIED;
- if (lambda_specs.conflicting_specifiers_p)
- error_at (lambda_specs.locations[ds_storage_class],
- "duplicate %<mutable%>");
- }
+ /* In the decl-specifier-seq of the lambda-declarator, each
+ decl-specifier shall either be mutable or constexpr. */
+ int declares_class_or_enum;
+ if (cp_lexer_next_token_is_decl_specifier_keyword (parser->lexer)
+ && !cp_next_tokens_can_be_gnu_attribute_p (parser))
+ cp_parser_decl_specifier_seq (parser,
+ CP_PARSER_FLAGS_ONLY_MUTABLE_OR_CONSTEXPR,
+ &lambda_specs, &declares_class_or_enum);
+
+ if (lambda_specifiers_loc
+ && (lambda_specs.storage_class == sc_mutable
+ || lambda_specs.locations[ds_constexpr]
+ || lambda_specs.locations[ds_consteval]))
+ {
+ pedwarn (lambda_specifiers_loc, 0,
+ "parameter declaration before lambda declaration "
+ "specifiers only optional with %<-std=c++2b%> or "
+ "%<-std=gnu++2b%>");
+ lambda_specifiers_loc = UNKNOWN_LOCATION;
+ }
+
+ if (lambda_specs.storage_class == sc_mutable)
+ {
+ LAMBDA_EXPR_MUTABLE_P (lambda_expr) = 1;
+ quals = TYPE_UNQUALIFIED;
+ if (lambda_specs.conflicting_specifiers_p)
+ error_at (lambda_specs.locations[ds_storage_class],
+ "duplicate %<mutable%>");
+ }
+
+ tx_qual = cp_parser_tx_qualifier_opt (parser);
+ if (lambda_specifiers_loc && tx_qual)
+ {
+ pedwarn (lambda_specifiers_loc, 0,
+ "parameter declaration before lambda transaction "
+ "qualifier only optional with %<-std=c++2b%> or "
+ "%<-std=gnu++2b%>");
+ lambda_specifiers_loc = UNKNOWN_LOCATION;
+ }
+
+ /* Parse optional exception specification. */
+ exception_spec
+ = cp_parser_exception_specification_opt (parser, CP_PARSER_FLAGS_NONE);
+
+ if (lambda_specifiers_loc && exception_spec)
+ {
+ pedwarn (lambda_specifiers_loc, 0,
+ "parameter declaration before lambda exception "
+ "specification only optional with %<-std=c++2b%> or "
+ "%<-std=gnu++2b%>");
+ lambda_specifiers_loc = UNKNOWN_LOCATION;
+ }
- tx_qual = cp_parser_tx_qualifier_opt (parser);
+ std_attrs = cp_parser_std_attribute_spec_seq (parser);
- /* Parse optional exception specification. */
- exception_spec
- = cp_parser_exception_specification_opt (parser, CP_PARSER_FLAGS_NONE);
-
- std_attrs = cp_parser_std_attribute_spec_seq (parser);
-
- /* Parse optional trailing return type. */
- if (cp_lexer_next_token_is (parser->lexer, CPP_DEREF))
- {
- cp_lexer_consume_token (parser->lexer);
- return_type = cp_parser_trailing_type_id (parser);
- }
+ /* Parse optional trailing return type. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_DEREF))
+ {
+ if (lambda_specifiers_loc)
+ pedwarn (lambda_specifiers_loc, 0,
+ "parameter declaration before lambda trailing "
+ "return type only optional with %<-std=c++2b%> or "
+ "%<-std=gnu++2b%>");
+ cp_lexer_consume_token (parser->lexer);
+ return_type = cp_parser_trailing_type_id (parser);
+ }
- if (cp_next_tokens_can_be_gnu_attribute_p (parser))
- gnu_attrs = cp_parser_gnu_attributes_opt (parser);
+ if (cp_next_tokens_can_be_gnu_attribute_p (parser))
+ gnu_attrs = cp_parser_gnu_attributes_opt (parser);
+ if (has_param_list)
+ {
/* Parse optional trailing requires clause. */
trailing_requires_clause = cp_parser_requires_clause_opt (parser, false);
- /* The function parameters must be in scope all the way until after the
- trailing-return-type in case of decltype. */
+ /* The function parameters must be in scope all the way until after
+ the trailing-return-type in case of decltype. */
pop_bindings_and_leave_scope ();
}
--- gcc/testsuite/g++.dg/cpp23/lambda-specifiers1.C.jj 2021-02-25 14:55:14.719567663 +0100
+++ gcc/testsuite/g++.dg/cpp23/lambda-specifiers1.C 2021-02-25 15:00:36.608082855 +0100
@@ -0,0 +1,18 @@
+// P1102R2 - Down with ()!
+// { dg-do compile { target c++11 } }
+// { dg-options "" }
+
+void
+foo ()
+{
+ auto a = [] mutable {}; // { dg-warning "parameter declaration before lambda declaration specifiers only optional with" "" { target c++20_down } }
+#if __cpp_constexpr >= 201603L
+ auto b = [] constexpr {}; // { dg-warning "parameter declaration before lambda declaration specifiers only optional with" "" { target { c++17 && c++20_down } } }
+#endif
+#if __cpp_consteval >= 201811L
+ auto c = [] consteval {}; // { dg-warning "parameter declaration before lambda declaration specifiers only optional with" "" { target c++20_only } }
+#endif
+ auto d = [] throw() {}; // { dg-warning "parameter declaration before lambda exception specification only optional with" "" { target c++20_down } }
+ auto e = [] noexcept {}; // { dg-warning "parameter declaration before lambda exception specification only optional with" "" { target c++20_down } }
+ auto f = [] -> int { return 0; }; // { dg-warning "parameter declaration before lambda trailing return type only optional with" "" { target c++20_down } }
+}
Jakub
next reply other threads:[~2021-02-25 18:44 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-02-25 18:44 Jakub Jelinek [this message]
2021-02-25 21:22 ` Jason Merrill
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210225184421.GL4020736@tucnak \
--to=jakub@redhat.com \
--cc=gcc-patches@gcc.gnu.org \
--cc=jason@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).