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
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); } | ^~~~~~~
r13-766-g6209009df65ff68482ef66951856f50cf362d990
The referenced change explictly added the check for this so closing as fixed. It includes a testcase already too.