Bug 60503

Summary: gcc looks for C++ attributes in the wrong place in a lambda-expression
Product: gcc Reporter: Richard Smith <richard-gccbugzilla>
Component: c++Assignee: Not yet assigned to anyone <unassigned>
Status: NEW ---    
Severity: normal CC: alvin, webrown.cpp
Priority: P3 Keywords: c++-lambda
Version: unknown   
Target Milestone: ---   
See Also: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101130
Host: Target:
Build: Known to work:
Known to fail: Last reconfirmed: 2015-03-24 00:00:00

Description Richard Smith 2014-03-11 20:19:01 UTC
GCC accepts this ill-formed code:

  void f() { []() [[ ]] mutable noexcept {}; }

... and rejects this valid code:

  void f() { []() mutable noexcept [[ ]] {}; }
Comment 1 Jason Merrill 2018-11-05 07:47:24 UTC
Author: jason
Date: Mon Nov  5 07:46:52 2018
New Revision: 265787

URL: https://gcc.gnu.org/viewcvs?rev=265787&root=gcc&view=rev
Log:
	PR c++/60503 - wrong lambda attribute syntax.

This patch fixes two issues with lambda attribute handling: First, it was in
the wrong place in the grammar.  Second, it was treating attributes as
applying to the whole declaration rather than to the function type, as
specified by the standard.

	* parser.c (cp_parser_lambda_declarator_opt): Fix attribute
	handling.

Added:
    trunk/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-attr1.C
    trunk/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-attr2.C
Modified:
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/parser.c
Comment 2 Martin Liška 2018-11-19 13:02:41 UTC
Can the bug be marked as resolved?
Comment 3 Jason Merrill 2019-03-18 19:35:22 UTC
Author: jason
Date: Mon Mar 18 19:34:47 2019
New Revision: 269775

URL: https://gcc.gnu.org/viewcvs?rev=269775&root=gcc&view=rev
Log:
	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.

Added:
    trunk/gcc/testsuite/g++.dg/ext/attr-lambda1.C
Modified:
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/parser.c
Comment 4 GCC Commits 2020-01-29 22:51:00 UTC
The master branch has been updated by Jason Merrill <jason@gcc.gnu.org>:

https://gcc.gnu.org/g:245e40af4fab5b7cf40fb310591a879355775971

commit r10-6335-g245e40af4fab5b7cf40fb310591a879355775971
Author: Jason Merrill <jason@redhat.com>
Date:   Tue Jan 28 17:41:05 2020 -0500

    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.
Comment 5 GCC Commits 2020-03-02 21:25:54 UTC
The releases/gcc-9 branch has been updated by Jason Merrill <jason@gcc.gnu.org>:

https://gcc.gnu.org/g:166c024a1969ca9e77ed450fb65ce5c926a315dc

commit r9-8318-g166c024a1969ca9e77ed450fb65ce5c926a315dc
Author: Jason Merrill <jason@redhat.com>
Date:   Mon Mar 2 14:42:47 2020 -0500

    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.
    
    gcc/cp/ChangeLog
    2020-03-02  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.
Comment 6 Alvin Wong 2022-12-07 10:25:30 UTC
Still a problem with 12.2 / trunk using GNU attributes:


$ <<EOF g++ -x c++ - -c -fsyntax-only
auto a() {
    return [](int a) __attribute__((stdcall)) noexcept { return a + 1; };
}
EOF
<stdin>: In lambda function:
<stdin>:2:47: error: expected '{' before 'noexcept'
<stdin>: In function 'auto a()':
<stdin>:2:46: error: expected ';' before 'noexcept'
<stdin>:2:56: error: expected '(' before '{' token
<stdin>:2:56: error: expected primary-expression before '{' token
<stdin>:2:55: error: expected ')' before '{' token


https://godbolt.org/z/xMrb4Pqsj