https://gcc.gnu.org/bugzilla/show_bug.cgi?id=123691
Jakub Jelinek <jakub at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Blocks| |123615
CC| |jakub at gcc dot gnu.org,
| |mpolacek at gcc dot gnu.org
--- Comment #1 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Dunno, the situation with expansion statements is complicated.
One thing is the expansion-stmt paper, that is implemented, but then there are
CWG issues.
There is https://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#3044
which has been voted in, but is not implemented in GCC,
parts of it are implemented in
https://gcc.gnu.org/pipermail/gcc-patches/2025-November/700703.html
pending review, but the removal of static can't be implemented until the second
half of
https://wg21.link/P2686R4 is implemented.
Then there is https://cplusplus.github.io/CWG/issues/3131.html which is still
open,
and is implemented in
https://gcc.gnu.org/pipermail/gcc-patches/2025-November/700762.html
patch pending review but not in gcc trunk.
And then there is https://cplusplus.github.io/CWG/issues/3140.html , not
implemented and still open.
With the above two mentioned patches, the error is
pr123691.C: In instantiation of ‘constexpr auto enum_to_string(E) [with E =
Enum]’:
required from here
pr123691.C:18:42:
18 | std::println("{}", enum_to_string(Enum::ONE));
| ~~~~~~~~~~~~~~^~~~~~~~~~~
pr123691.C:9:9: error: ‘std::meta::enumerators_of(^^Enum)’ is not a constant
expression because it refers to a result of ‘operator new’
9 | template for (constexpr auto e :
std::meta::enumerators_of(^^E)) {
| ^~~~~~~~
In file included from
/home/jakub/src/gcc/obj56i/usr/local/include/c++/16.0.1/string:46,
from
/home/jakub/src/gcc/obj56i/usr/local/include/c++/16.0.1/bits/stdexcept_throw.h:57,
from
/home/jakub/src/gcc/obj56i/usr/local/include/c++/16.0.1/array:44,
from
/home/jakub/src/gcc/obj56i/usr/local/include/c++/16.0.1/meta:41,
from pr123691.C:1:
/home/jakub/src/gcc/obj56i/usr/local/include/c++/16.0.1/bits/allocator.h:200:52:
note: allocated here
200 | return static_cast<_Tp*>(::operator new(__n));
| ~~~~~~~~~~~~~~^~~~~
pr123691.C: In function ‘int main()’:
pr123691.C:18:42: error: call to consteval function ‘enum_to_string<Enum>(ONE)’
is not a constant expression
18 | std::println("{}", enum_to_string(Enum::ONE));
| ~~~~~~~~~~~~~~^~~~~~~~~~~
pr123691.C:18:42: error: ‘constexpr auto enum_to_string(E) [with E = Enum]’
called in a constant expression
pr123691.C:18:42: note: ‘constexpr auto enum_to_string(E) [with E = Enum]’ was
promoted to an immediate function
and I believe that will be the case even when the rest of CWG3044 will be
implemented, so I think
this is a bug in your testcase.
You should have used std::define_static_array around the
std::meta::enumerators_of call (for the reasons
mentioned in
https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3491r3.html#with-expansion-statements
;
though that will not work until the CWG3131 patch is in), or what will work
until then [:std::meta::reflect_constant_array( and ):]
around the std::meta::enumerators_of call.
Referenced Bugs:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=123615
[Bug 123615] (c++-reflection) - [meta-bug] reflection issue