[Bug c++/109576] access checking done on constexpr even if the access was done in the class itself when used inside a template

2023-04-20 Thread ts826848 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109576

--- Comment #4 from Alex Wang  ---
Just realized my previous searches were only searching the summary.

Is this bug a duplicate of either
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96716 and/or
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97740?

[Bug c++/109576] New: Incorrect rejection of constexpr local var due to private member even with visible conversion operator

2023-04-20 Thread ts826848 at gmail dot com via Gcc-bugs
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 {_}; }
private:
char chars_{'\0'};
};

constexpr static_string enum_name_v{};

constexpr const char* nonlocal_name = enum_name_v;

template
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:

: In instantiation of 'constexpr auto enum_name() [with auto V =
0]':
:17:22:   required from here
:13:40: error: 'char static_string::chars_' is private within this
context
   13 | constexpr const char* local_name = enum_name_v;
  |^~~
: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