From 6e3587dbbcefd4d4bdafaea0aa1cb8eb9495bd9c Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Mon, 18 Mar 2019 15:34:47 -0400 Subject: [PATCH] PR c++/89640 - GNU attributes on lambda. My patch for PR 60503 to fix C++11 attribute parsing on lambdas accidentally removed support for GNU attributes. * parser.c (cp_parser_lambda_declarator_opt): Allow GNU attributes. From-SVN: r269775 --- gcc/cp/ChangeLog | 3 +++ gcc/cp/parser.c | 15 ++++++++++----- gcc/testsuite/g++.dg/ext/attr-lambda1.C | 9 +++++++++ 3 files changed, 22 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/g++.dg/ext/attr-lambda1.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index bc3850d3aff..a3341bd9672 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,8 @@ 2019-03-18 Jason Merrill + PR c++/89640 - GNU attributes on lambda. + * parser.c (cp_parser_lambda_declarator_opt): Allow GNU attributes. + PR c++/89682 - wrong access error in default argument. * pt.c (tsubst_default_argument): Don't defer access checks. diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index b8a0245ce57..81aff35cad9 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -10790,7 +10790,8 @@ cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr) This means an empty parameter list, no attributes, and no exception specification. */ tree param_list = void_list_node; - tree attributes = NULL_TREE; + tree std_attrs = NULL_TREE; + tree gnu_attrs = NULL_TREE; tree exception_spec = NULL_TREE; tree template_param_list = NULL_TREE; tree tx_qual = NULL_TREE; @@ -10849,7 +10850,8 @@ cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr) /* 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)) + 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); @@ -10866,7 +10868,7 @@ cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr) /* Parse optional exception specification. */ exception_spec = cp_parser_exception_specification_opt (parser); - attributes = cp_parser_std_attribute_spec_seq (parser); + std_attrs = cp_parser_std_attribute_spec_seq (parser); /* Parse optional trailing return type. */ if (cp_lexer_next_token_is (parser->lexer, CPP_DEREF)) @@ -10875,6 +10877,9 @@ cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr) 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); + /* 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 (); @@ -10922,11 +10927,11 @@ cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr) exception_spec, return_type, /*requires_clause*/NULL_TREE); - declarator->std_attributes = attributes; + declarator->std_attributes = std_attrs; fco = grokmethod (&return_type_specs, declarator, - NULL_TREE); + gnu_attrs); if (fco != error_mark_node) { DECL_INITIALIZED_IN_CLASS_P (fco) = 1; diff --git a/gcc/testsuite/g++.dg/ext/attr-lambda1.C b/gcc/testsuite/g++.dg/ext/attr-lambda1.C new file mode 100644 index 00000000000..01470c32233 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/attr-lambda1.C @@ -0,0 +1,9 @@ +// PR c++/89640 +// { dg-options "" } +// { dg-do compile { target c++11 } } + +void test() { + []() __attribute__((noinline,cold)) { + asm volatile(""); + }(); +} -- 2.30.2