| Summary: | constexprs involving non-literal const variables are incorrectly accepted | ||
|---|---|---|---|
| Product: | gcc | Reporter: | Richard Sandiford <rsandifo> |
| Component: | c++ | Assignee: | Not yet assigned to anyone <unassigned> |
| Status: | RESOLVED FIXED | ||
| Severity: | normal | CC: | fchelnokov, jakub, webrown.cpp |
| Priority: | P3 | Keywords: | accepts-invalid |
| Version: | 8.2.1 | ||
| Target Milestone: | 13.0 | ||
| Host: | Target: | ||
| Build: | Known to work: | 13.0 | |
| Known to fail: | 12.2.0 | Last reconfirmed: | 2021-07-23 00:00:00 |
| Bug Depends on: | |||
| Bug Blocks: | 55004 | ||
Confirmed. Seems to be fixed on the trunk.
I get now:
<source>: In function 'void g()':
<source>:3:63: in 'constexpr' expansion of 'foo(local_s)'
<source>:3:71: error: the value of 'local_s' is not usable in a constant expression
3 | void g () { const s local_s = { 1, 2 }; constexpr int a = foo (local_s); }
| ^
<source>:3:21: note: 'local_s' was not declared 'constexpr'
3 | void g () { const s local_s = { 1, 2 }; constexpr int a = foo (local_s); }
| ^~~~~~~
The referenced change explictly added the check for this so closing as fixed. It includes a testcase already too. |
G++ accepts: struct s { volatile int x; int y; }; constexpr int foo (const s &s1) { return s1.y; } void g () { const s local_s = { 1, 2 }; constexpr int a = foo (local_s); } even though "local_s" is only const, not constexpr (and couldn't be constexpr due to having a non-literal type). From Jonathan on IRC: I think for foo(local_s) to be a constant expression, local_s needs to be a constexpr variable, or a non-volatile const-qualified integer, or a reference http://eel.is/c++draft/expr.const#8.7