https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109576
Bug ID: 109576 Summary: Incorrect rejection of constexpr local var due to private member even with visible conversion operator Product: gcc Version: 12.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: ts826848 at gmail dot com Target Milestone: --- My apologies in advance for the title. I'm honestly not sure how to summarize this. GCC appears to incorrectly flag the creation of a constexpr local variable when a conversion operator is used that accesses a private member of a class. According to Godbolt, the code compiles under Clang 5.0.0-16.0.0 and the MSVC 19.14-19.latest, but GCC 7.1 and up rejects the code. (For a little bit of context, I ran into this when using Neargye/magic_enum for some enum reflection, and I create some constexpr local variables to hold stringified enum names) Here is the heavily reduced code ([Godbolt](https://godbolt.org/z/hGTMWvPrz)): struct static_string { constexpr operator const char*() const { return {&chars_}; } private: char chars_{'\0'}; }; constexpr static_string enum_name_v{}; constexpr const char* nonlocal_name = enum_name_v; template<auto V> constexpr auto enum_name() { constexpr const char* local_name = enum_name_v; return local_name; } auto n = enum_name<0>(); GCC complains about local_name: <source>: In instantiation of 'constexpr auto enum_name() [with auto V = 0]': <source>:17:22: required from here <source>:13:40: error: 'char static_string::chars_' is private within this context 13 | constexpr const char* local_name = enum_name_v; | ^~~~~~~~~~~ <source>:4:10: note: declared private here 4 | char chars_{'\0'}; | ^~~~~~ Compiler returned: 1 This seems like valid C++ to me. enum_name_v should be convertible via the operator string_view, and I'm not sure why the visibility of chars_ is relevant at all. In addition, some non-visibility-related changes gets the code to compile, which seems inconsistent with this being a visibility issue: - Making `local_name` a non-local variable (e.g., `nonlocal_name`) - Making `local_name` non-`constexpr` - Making `enum_name` a non-template function