aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2020-01-28 17:41:05 -0500
committerJason Merrill <jason@redhat.com>2020-01-29 17:49:59 -0500
commit245e40af4fab5b7cf40fb310591a879355775971 (patch)
tree06ce229101cdb2d7663bfb2bc8784750125c8438 /gcc
parent165255c7a562e04e3be89eb1c87b4ac3c5248d77 (diff)
downloadgcc-245e40af4fab5b7cf40fb310591a879355775971.zip
gcc-245e40af4fab5b7cf40fb310591a879355775971.tar.gz
gcc-245e40af4fab5b7cf40fb310591a879355775971.tar.bz2
c++: Fix attributes with lambda and trailing return type.
My fix for 60503 fixed handling of C++11 attributes following the lambda-declarator. My patch for 89640 re-added support for GNU attributes, but attributes after the trailing return type were parsed as applying to the return type rather than to the function. This patch adjusts parsing of a trailing-return-type to ignore GNU attributes at the end of the declaration so that they will be applied to the declaration as a whole. I also considered parsing the attributes between the closing paren and the trailing-return-type, and tried a variety of approaches to implementing that, but I think it's better to stick with the documented rule that "An attribute specifier list may appear immediately before the comma, '=' or semicolon terminating the declaration of an identifier...." Anyone disagree? Meanwhile, C++ committee discussion about the lack of any way to apply attributes to a lambda op() seems to have concluded that they should go between the introducer and declarator, so I've implemented that as well. PR c++/90333 PR c++/89640 PR c++/60503 * parser.c (cp_parser_type_specifier_seq): Don't parse attributes in a trailing return type. (cp_parser_lambda_declarator_opt): Parse C++11 attributes before parens.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog10
-rw-r--r--gcc/cp/parser.c17
-rw-r--r--gcc/testsuite/g++.dg/ext/attr-trailing1.C14
3 files changed, 40 insertions, 1 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 3029714..b307583 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,13 @@
+2020-01-29 Jason Merrill <jason@redhat.com>
+
+ PR c++/90333
+ PR c++/89640
+ PR c++/60503
+ * parser.c (cp_parser_type_specifier_seq): Don't parse attributes in
+ a trailing return type.
+ (cp_parser_lambda_declarator_opt): Parse C++11 attributes before
+ parens.
+
2020-01-29 Marek Polacek <polacek@redhat.com>
PR c++/91754 - Fix template arguments comparison with class NTTP.
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index b832782..bd8e524 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -10962,6 +10962,9 @@ cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr)
++parser->num_template_parameter_lists;
}
+ /* Committee discussion supports allowing attributes here. */
+ lambda_specs.attributes = cp_parser_attributes_opt (parser);
+
/* The parameter-declaration-clause is optional (unless
template-parameter-list was given), but must begin with an
opening parenthesis if present. */
@@ -11097,7 +11100,7 @@ cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr)
fco = grokmethod (&return_type_specs,
declarator,
- gnu_attrs);
+ chainon (gnu_attrs, lambda_specs.attributes));
if (fco != error_mark_node)
{
DECL_INITIALIZED_IN_CLASS_P (fco) = 1;
@@ -22277,6 +22280,18 @@ cp_parser_type_specifier_seq (cp_parser* parser,
/* Check for attributes first. */
if (cp_next_tokens_can_be_attribute_p (parser))
{
+ /* GNU attributes at the end of a declaration apply to the
+ declaration as a whole, not to the trailing return type. So look
+ ahead to see if these attributes are at the end. */
+ if (seen_type_specifier && is_trailing_return
+ && cp_next_tokens_can_be_gnu_attribute_p (parser))
+ {
+ size_t n = cp_parser_skip_attributes_opt (parser, 1);
+ cp_token *tok = cp_lexer_peek_nth_token (parser->lexer, n);
+ if (tok->type == CPP_SEMICOLON || tok->type == CPP_COMMA
+ || tok->type == CPP_EQ || tok->type == CPP_OPEN_BRACE)
+ break;
+ }
type_specifier_seq->attributes
= attr_chainon (type_specifier_seq->attributes,
cp_parser_attributes_opt (parser));
diff --git a/gcc/testsuite/g++.dg/ext/attr-trailing1.C b/gcc/testsuite/g++.dg/ext/attr-trailing1.C
new file mode 100644
index 0000000..ff3fb90
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/attr-trailing1.C
@@ -0,0 +1,14 @@
+// PR c++/90333
+// { dg-do compile { target c++11 } }
+
+auto l = [] [[nodiscard]] () -> int { return 0; };
+auto l2 = []() -> int __attribute ((warn_unused_result)) { return 0; };
+auto f() -> int __attribute ((warn_unused_result));
+auto f() -> int { return 0; }
+
+int main()
+{
+ l(); // { dg-warning "nodiscard" }
+ l2(); // { dg-warning "unused_result" }
+ f(); // { dg-warning "unused_result" }
+}