https://gcc.gnu.org/bugzilla/show_bug.cgi?id=125725
Bug ID: 125725
Summary: [contracts] attribute with a postcondition result
binding is rejected
Product: gcc
Version: 17.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: lahvuun at gmail dot com
Target Milestone: ---
Using an attribute with a postcondition result binding doesn't compile.
A file with a single line is enough to trigger it:
```
int g() post(r [[maybe_unused]]: r > 0);
```
Compile with:
```
$ ./g++ -std=c++26 -c foo.cpp -o foo.o
foo.cpp:1:14: error: ‘r’ was not declared in this scope
1 | int g() post(r [[maybe_unused]]: r > 0);
| ^
foo.cpp:1:16: error: two consecutive ‘[’ shall only introduce an attribute
before ‘[’ token
1 | int g() post(r [[maybe_unused]]: r > 0);
| ^
foo.cpp:1:15: error: expected ‘)’ before ‘[’ token
1 | int g() post(r [[maybe_unused]]: r > 0);
| ~ ^~
| )
foo.cpp:1:16: error: attributes are not allowed on a function-definition
1 | int g() post(r [[maybe_unused]]: r > 0);
| ^
foo.cpp: In function ‘int g()’:
foo.cpp:1:34: error: only constructors take member initializers
1 | int g() post(r [[maybe_unused]]: r > 0);
| ^
foo.cpp:1:36: error: expected ‘(’ before ‘>’ token
1 | int g() post(r [[maybe_unused]]: r > 0);
| ^
| (
foo.cpp:1:36: error: expected ‘{’ before ‘>’ token
foo.cpp:1:36: warning: no return statement in function returning non-void
[-Wreturn-type]
foo.cpp: At global scope:
foo.cpp:1:36: error: expected unqualified-id before ‘>’ token
```
Output of ./g++ -v:
```
Using built-in specs.
COLLECT_GCC=./g++
COLLECT_LTO_WRAPPER=/usr/local/libexec/gcc/x86_64-pc-linux-gnu/17.0.0/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: /home/lahvuun/git/gcc/configure --enable-languages=c,c++
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 17.0.0 20260610 (experimental) (GCC)
```
Standard draft seems to allow it:
https://eel.is/c++draft/dcl.contract.res#1
> The optional attribute-specifier-seq of the attributed-identifier in the
> result-name-introducer appertains to the result binding so introduced.
The contracts proposal includes this example at the top of page 20 and says it
is "explicitly allowed":
https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2025/p2900r14.pdf
> int g()
> post (r [[maybe_unused]]: r > 0);