// P0466R5 // { dg-do run { target c++20 } } namespace std { template <class S, class M> constexpr bool is_pointer_interconvertible_with_class (M S::*m) noexcept { return __builtin_is_pointer_interconvertible_with_class (m); } } struct A; struct B { int b; double b2; }; struct C : virtual B { int c; }; struct D {}; struct E {}; struct F : public B, D, E {}; struct G : public D, E { int g; }; struct H {}; struct I : public G, H {}; struct J { int j1; private: int j2; public: int j3; }; struct K : public J {}; struct L : public B, D, E {}; struct M { D d [[no_unique_address]]; E e [[no_unique_address]]; int f; }; union U { int a; double b; long long c; }; struct V { union { int a; long b; }; int c; }; union X { int a; union { short b; long c; }; long long d; }; struct Y { void foo () {} }; union Z { int a; private: int b; protected: int c; public: int d; }; int main () { auto t1 = &B::b; if (!std::is_pointer_interconvertible_with_class (t1)) __builtin_abort (); auto t2 = &B::b2; if (std::is_pointer_interconvertible_with_class (t2)) __builtin_abort (); auto t3 = &C::b; if (!std::is_pointer_interconvertible_with_class (t3)) __builtin_abort (); auto t4 = &F::b; if (!std::is_pointer_interconvertible_with_class (t4)) __builtin_abort (); int F::*t5 = &F::b; if (!std::is_pointer_interconvertible_with_class (t5)) __builtin_abort (); auto t6 = &G::g; if (!std::is_pointer_interconvertible_with_class (t6)) __builtin_abort (); int G::*t7 = &G::g; if (!std::is_pointer_interconvertible_with_class (t7)) __builtin_abort (); auto t8 = &I::g; if (!std::is_pointer_interconvertible_with_class (t8)) __builtin_abort (); int I::*t9 = &I::g; if (!std::is_pointer_interconvertible_with_class (t9)) __builtin_abort (); auto t10 = &J::j1; if (std::is_pointer_interconvertible_with_class (t10)) __builtin_abort (); auto t11 = &J::j3; if (std::is_pointer_interconvertible_with_class (t11)) __builtin_abort (); auto t12 = &K::j1; if (std::is_pointer_interconvertible_with_class (t12)) __builtin_abort (); auto t13 = &K::j3; if (std::is_pointer_interconvertible_with_class (t13)) __builtin_abort (); auto t14 = &L::b; if (!std::is_pointer_interconvertible_with_class (t14)) __builtin_abort (); int L::*t15 = &L::b; if (!std::is_pointer_interconvertible_with_class (t15)) __builtin_abort (); auto t16 = &L::b; if (!std::is_pointer_interconvertible_with_class (t16)) __builtin_abort (); auto t17 = &M::d; if (!std::is_pointer_interconvertible_with_class (t17)) __builtin_abort (); auto t18 = &M::e; if (std::is_pointer_interconvertible_with_class (t18)) __builtin_abort (); auto t19 = &M::f; if (std::is_pointer_interconvertible_with_class (t19)) __builtin_abort (); auto t20 = &U::a; if (!std::is_pointer_interconvertible_with_class (t20)) __builtin_abort (); auto t21 = &U::b; if (!std::is_pointer_interconvertible_with_class (t21)) __builtin_abort (); auto t22 = &U::c; if (!std::is_pointer_interconvertible_with_class (t22)) __builtin_abort (); auto t23 = &V::a; if (!std::is_pointer_interconvertible_with_class (t23)) __builtin_abort (); auto t24 = &V::b; if (!std::is_pointer_interconvertible_with_class (t24)) __builtin_abort (); auto t25 = &V::c; if (std::is_pointer_interconvertible_with_class (t25)) __builtin_abort (); auto t26 = &X::a; if (!std::is_pointer_interconvertible_with_class (t26)) __builtin_abort (); auto t27 = &X::b; if (!std::is_pointer_interconvertible_with_class (t27)) __builtin_abort (); auto t28 = &X::c; if (!std::is_pointer_interconvertible_with_class (t28)) __builtin_abort (); auto t29 = &X::d; if (!std::is_pointer_interconvertible_with_class (t29)) __builtin_abort (); auto t30 = (int B::*) nullptr; if (std::is_pointer_interconvertible_with_class (t30)) __builtin_abort (); auto t31 = &Y::foo; if (std::is_pointer_interconvertible_with_class (t31)) __builtin_abort (); auto t32 = &Z::a; if (!std::is_pointer_interconvertible_with_class (t32)) __builtin_abort (); auto t33 = &Z::d; if (!std::is_pointer_interconvertible_with_class (t33)) __builtin_abort (); }