https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116011
--- Comment #7 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
(In reply to Hubert Tong from comment #5)
> I updated the summary title again to reflect that the issue is specific to
> declaration matching.
>
> GCC does differentiate between &(T::x) and &T::x (except that it conflates
> them when matching templated declarations.
>
> For example, the following compiles:
> ```
> struct A { int x; };
>
> char q(int *);
> short q(int A::*);
>
> template <typename T>
> constexpr int f1(char (*)[sizeof(q(&T::x))]) { return 1; }
>
> template <typename T>
> constexpr int f2(char (*)[sizeof(q(&(T::x)))]) { return 2; }
>
> constexpr int g(char (*p)[sizeof(char)] = 0) { return f2<A>(p); }
> constexpr int h(char (*p)[sizeof(short)] = 0) { return f1<A>(p); }
>
> static_assert(g() == 2, "");
> static_assert(h() == 1, "");
> ```
Those are all unevulated context.that is sizeof and decltype are both
considered unevulated context. In them, gcc does not think &(T::x) and &T::x
act differently. Gcc does the right thing outside of unevulated context though.