Bug 90333 - [9/10/11 Regression] Can't apply attributes to lambdas with trailing returns
Summary: [9/10/11 Regression] Can't apply attributes to lambdas with trailing returns
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 9.1.0
: P2 normal
Target Milestone: 9.4
Assignee: Jason Merrill
URL:
Keywords: rejects-valid
: 90489 90818 95883 96485 (view as bug list)
Depends on:
Blocks:
 
Reported: 2019-05-03 18:53 UTC by Patrick Moran
Modified: 2022-03-05 21:04 UTC (History)
6 users (show)

See Also:
Host:
Target:
Build:
Known to work: 10.0, 8.3.0
Known to fail: 9.1.0
Last reconfirmed: 2019-05-15 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Patrick Moran 2019-05-03 18:53:49 UTC
In 8.3.0 we could do either one of these:

> []() __attribute__((always_inline)) -> int { return 0; }
> []() [[gnu::always_inline]] -> int { return 0; }

I understand that __attribute__ is a GCC extension, but it's my understanding that the second one is standard behavior.

As of 9.1.0, the __attribute__ variant both fails with "expected '{' before '->' token", and the [[gnu::always_inline]] variant fails because it's applying the attribute to the trailing return type rather than the lambda.

I tried every possible position, but each fails
  * __attribute__((always_inline)) []() -> int { return 0; }
  * [[gnu::always_inline]] []() -> int { return 0; }
    * These fail with "attributes at the beginning of statement are ignored"
    * IE, it's not actually applying to the lambda.
  * [] __attribute__((always_inline)) () -> int { return 0; }
  * [] [[gnu::always_inline]] () -> int { return 0; }
    * These fail with "expected '{' before '[' token" (or "__attribute__")
  * []() __attribute__((always_inline)) -> int { return 0; }
    * This fails with "expected '{' before '->' token
  * []() [[gnu::always_inline]] -> int { return 0; }
    * This fails with "attribute ignored"
    * It is applying the attribute as an attribute of the return type
  * []() -> __attribute__((always_inline)) int { return 0; }
  * []() -> [[gnu::always_inline]] int { return 0; }
    * This fails with "attribute does not apply to types"
    * It is applying the attribute as an attribute of the return type
  * []() -> int [[gnu::always_inline]] { return 0; }
  * []() -> int __attribute__((always_inline)) { return 0; }
    * This fails with "attribute does not apply to types"
    * It is applying the attribute as an attribute of the return type
  * []() -> int { return 0; } __attribute__((always_inline))
    * Fails with "expected ';' before '__attribute__'"
  * []() -> int { return 0; } [[gnu::always_inline]]
    * Fails with "two consecutive '[' shall only introduce an attribute before '[' token

It would appear that in 9.1.0 there's no way to specify attributes for a lambda that has a trailing return type?
Comment 1 Jonathan Wakely 2019-05-15 15:55:22 UTC
*** Bug 90489 has been marked as a duplicate of this bug. ***
Comment 2 Jonathan Wakely 2019-05-15 15:58:25 UTC
Started to be rejected with r265787:

            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.
Comment 3 Jonathan Wakely 2019-06-10 19:11:09 UTC
*** Bug 90818 has been marked as a duplicate of this bug. ***
Comment 4 Jakub Jelinek 2019-08-12 08:56:17 UTC
GCC 9.2 has been released.
Comment 5 CVS 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 6 Jason Merrill 2020-01-30 01:18:06 UTC
Fixed for GCC 10 so far.
Comment 7 CVS 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 8 Jason Merrill 2020-03-02 21:28:54 UTC
Fixed for 9.3.
Comment 9 Timothee Besset 2020-06-25 23:34:09 UTC
First test case is still a problem in 9.3 and 10:

[]() __attribute__((always_inline)) -> int { return 0; }

Fix proposed in https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95883
Comment 10 Jason Merrill 2021-02-26 04:12:47 UTC
Reopening.
Comment 11 Jason Merrill 2021-02-26 04:13:21 UTC
*** Bug 96485 has been marked as a duplicate of this bug. ***
Comment 12 Jason Merrill 2021-02-26 04:15:12 UTC
*** Bug 95883 has been marked as a duplicate of this bug. ***
Comment 13 CVS Commits 2021-02-27 20:43:10 UTC
The releases/gcc-10 branch has been updated by Jason Merrill <jason@gcc.gnu.org>:

https://gcc.gnu.org/g:f6b1c08e3783bbc3420d95a0357935250d61a29d

commit r10-9394-gf6b1c08e3783bbc3420d95a0357935250d61a29d
Author: Jason Merrill <jason@redhat.com>
Date:   Fri Feb 26 05:45:02 2021 -0500

    c++: Allow GNU attributes before lambda -> [PR90333]
    
    In my 9.3/10 patch for 90333 I allowed attributes between [] and (), and
    after the trailing return type, but not in the place that GCC 8 expected
    them, and we've gotten several bug reports about that.  So let's allow them
    there, as well.
    
    gcc/cp/ChangeLog:
    
            PR c++/90333
            * parser.c (cp_parser_lambda_declarator_opt): Accept GNU attributes
            between () and ->.
    
    gcc/testsuite/ChangeLog:
    
            PR c++/90333
            * g++.dg/ext/attr-lambda3.C: New test.
Comment 14 CVS Commits 2021-02-27 20:43:24 UTC
The releases/gcc-9 branch has been updated by Jason Merrill <jason@gcc.gnu.org>:

https://gcc.gnu.org/g:74d34ca781cf94c8b4979c524dbbfbe95863678a

commit r9-9254-g74d34ca781cf94c8b4979c524dbbfbe95863678a
Author: Jason Merrill <jason@redhat.com>
Date:   Fri Feb 26 05:45:02 2021 -0500

    c++: Allow GNU attributes before lambda -> [PR90333]
    
    In my 9.3/10 patch for 90333 I allowed attributes between [] and (), and
    after the trailing return type, but not in the place that GCC 8 expected
    them, and we've gotten several bug reports about that.  So let's allow them
    there, as well.
    
    gcc/cp/ChangeLog:
    
            PR c++/90333
            * parser.c (cp_parser_lambda_declarator_opt): Accept GNU attributes
            between () and ->.
    
    gcc/testsuite/ChangeLog:
    
            PR c++/90333
            * g++.dg/ext/attr-lambda3.C: New test.
Comment 15 CVS Commits 2021-02-27 20:44:36 UTC
The master branch has been updated by Jason Merrill <jason@gcc.gnu.org>:

https://gcc.gnu.org/g:5d9d6c1cd8d9f0e057b4a7a849bc765e2109137c

commit r11-7430-g5d9d6c1cd8d9f0e057b4a7a849bc765e2109137c
Author: Jason Merrill <jason@redhat.com>
Date:   Fri Feb 26 05:45:02 2021 -0500

    c++: Allow GNU attributes before lambda -> [PR90333]
    
    In my 9.3/10 patch for 90333 I allowed attributes between [] and (), and
    after the trailing return type, but not in the place that GCC 8 expected
    them, and we've gotten several bug reports about that.  So let's allow them
    there, as well.
    
    gcc/cp/ChangeLog:
    
            PR c++/90333
            * parser.c (cp_parser_lambda_declarator_opt): Accept GNU attributes
            between () and ->.
    
    gcc/testsuite/ChangeLog:
    
            PR c++/90333
            * g++.dg/ext/attr-lambda3.C: New test.
Comment 16 Jason Merrill 2021-02-28 05:39:56 UTC
Fixed better for 9.4/10.3/11.