https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96215

--- Comment #2 from Arthur O'Dwyer <arthur.j.odwyer at gmail dot com> ---
WG21's commentary on CWG 1273 (which is now
http://cwg-issue-browser.herokuapp.com/cwg1172
) seems completely bizarre to me. Sure, `decltype(g.x)` could theoretically
refer to a private member of `g`; but so could `decltype(g+1)` or
`decltype(*g)` or any other expression that might involve a private member.

(In `g+1`, there might be a private member `S::operator+(int)`.)

https://godbolt.org/z/ehd9fr
GCC happily accepts
    template <class U> constexpr decltype (a.i) f() { return 1; }
    template <class U> constexpr decltype (b.i) f() { return 2; }
as an overload set, but rejects
    template <class U> constexpr decltype (a+1) g() { return 3; }
    template <class U> constexpr decltype (b+1) g() { return 4; }
and also rejects
    template <class U> constexpr decltype (&A::i, 0) h() { return 5; }
    template <class U> constexpr decltype (&B::i, 0) h() { return 6; }

Clang sensibly rejects all three, all for the same reason.

Normally I'd be all for GCC injecting some implementation divergence into this
poorly specified area of the standard; but since this affects name-mangling and
thus causes GCC to be unable to link against (hypothetical) code compiled with
Clang and vice versa, I think it might be worth trying to reconcile.

To be clear: This name-mangling issue doesn't affect any real-world codebase
AFAIK. I discovered it purely by accident while messing around in Godbolt.

Reply via email to