Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incorrect example for member access expression with using enum in [enum.udecl] CWG2959 #7368

Open
keinflue opened this issue Nov 4, 2024 · 4 comments
Labels
cwg Issue must be reviewed by CWG. not-editorial Issue is not deemed editorial; the editorial issue is kept open for tracking.

Comments

@keinflue
Copy link

keinflue commented Nov 4, 2024

[enum.udecl]/2 contains this example:

enum class fruit { orange, apple };
struct S {
  using enum fruit;             // OK, introduces orange and apple into S
};
void f() {
  S s;
  s.orange;                     // OK, names fruit​::​orange
  S::orange;                    // OK, names fruit​::​orange
}

While it is correct that name lookup for orange in s.orange will find fruit::orange, the member access expression itself is not ok, because [expr.ref]/7.5 only specifies its behavior for member enumerators. using enum however doesn't make the enumerator a member enumerator ([class.mem.general]/3.5, [class.mem.general]/4).

Currently [expr.ref] simply lacks a statement about the behavior in this situation, but CWG issue 2902's proposed resolution would clarify that it is ill-formed.

From issue reported to Clang here.

@zygoloid
Copy link
Member

zygoloid commented Nov 4, 2024

To me it seems worth having CWG look at this to determine if accepting s.orange is intended and a non-editorial fix is preferred. Perhaps using enum fruit (and using fruit::orange;) should declare orange to be a member of class S? Though that has its own share of weirdness:

enum class fruit { orange };
struct S { using fruit::orange; } s;
auto a = s.S::orange; // OK?
auto b = s.fruit::orange; // OK?
struct T { using fruit::orange; } t;
auto c = s.T::orange; // OK?

(Treating using fruit::orange; as if it declares a new enumerator of the same type and with the same value as the original might address some of the surprising cases here. But might also introduce new problems with ambiguity if we end up with both the original and the new enumerator in a single lookup result.)

@keinflue
Copy link
Author

keinflue commented Nov 8, 2024

I just noticed that the suggested resolution of CWG 2557 would make this well-formed again, but only if the enumerator is named with unqualified name.

So I agree it currently doesn't seem clear what the intended behavior should be.

@jensmaurer jensmaurer added cwg Issue must be reviewed by CWG. not-editorial Issue is not deemed editorial; the editorial issue is kept open for tracking. labels Nov 9, 2024
@jensmaurer
Copy link
Member

CWG2959

@jensmaurer jensmaurer changed the title Incorrect example for member access expression with using enum in [enum.udecl]. Incorrect example for member access expression with using enum in [enum.udecl] CWG2959 Nov 13, 2024
@zygoloid
Copy link
Member

I just noticed that the suggested resolution of CWG 2557 would make this well-formed again, but only if the enumerator is named with unqualified name.

FWIW, the outcome we get from the suggested resolution of CWG2557 seems quite reasonable to me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cwg Issue must be reviewed by CWG. not-editorial Issue is not deemed editorial; the editorial issue is kept open for tracking.
Projects
None yet
Development

No branches or pull requests

3 participants