1 // RUN: %clang_cc1 -std=c++14 -fexperimental-new-constant-interpreter -verify=expected,both %s 2 // RUN: %clang_cc1 -std=c++23 -fexperimental-new-constant-interpreter -verify=expected,both %s 3 // RUN: %clang_cc1 -std=c++14 -verify=ref,both %s 4 // RUN: %clang_cc1 -std=c++23 -verify=ref,both %s 5 6 namespace MemberPointers { 7 struct A { 8 constexpr A(int n) : n(n) {} 9 int n; 10 constexpr int f() const { return n + 3; } 11 }; 12 13 constexpr A a(7); 14 static_assert(A(5).*&A::n == 5, ""); 15 static_assert((&a)->*&A::n == 7, ""); 16 static_assert((A(8).*&A::f)() == 11, ""); 17 static_assert(((&a)->*&A::f)() == 10, ""); 18 19 struct B : A { 20 constexpr B(int n, int m) : A(n), m(m) {} 21 int m; 22 constexpr int g() const { return n + m + 1; } 23 }; 24 constexpr B b(9, 13); 25 static_assert(B(4, 11).*&A::n == 4, ""); 26 static_assert(B(4, 11).*&B::m == 11, ""); 27 static_assert(B(4, 11).m == 11, ""); 28 static_assert(B(4, 11).*(int(A::*))&B::m == 11, ""); 29 static_assert(B(4, 11).*&B::m == 11, ""); 30 static_assert((&b)->*&A::n == 9, ""); 31 static_assert((&b)->*&B::m == 13, ""); 32 static_assert((&b)->*(int(A::*))&B::m == 13, ""); 33 static_assert((B(4, 11).*&A::f)() == 7, ""); 34 static_assert((B(4, 11).*&B::g)() == 16, ""); 35 36 static_assert((B(4, 11).*(int(A::*)() const)&B::g)() == 16, ""); 37 38 static_assert(((&b)->*&A::f)() == 12, ""); 39 static_assert(((&b)->*&B::g)() == 23, ""); 40 static_assert(((&b)->*(int(A::*)()const)&B::g)() == 23, ""); 41 42 43 struct S { 44 constexpr S(int m, int n, int (S::*pf)() const, int S::*pn) : 45 m(m), n(n), pf(pf), pn(pn) {} 46 constexpr S() : m(), n(), pf(&S::f), pn(&S::n) {} 47 48 constexpr int f() const { return this->*pn; } 49 virtual int g() const; 50 51 int m, n; 52 int (S::*pf)() const; 53 int S::*pn; 54 }; 55 56 constexpr int S::*pm = &S::m; 57 constexpr int S::*pn = &S::n; 58 59 constexpr int (S::*pf)() const = &S::f; 60 constexpr int (S::*pg)() const = &S::g; 61 62 constexpr S s(2, 5, &S::f, &S::m); 63 64 static_assert((s.*&S::f)() == 2, ""); 65 static_assert((s.*s.pf)() == 2, ""); 66 67 static_assert(pf == &S::f, ""); 68 69 static_assert(pf == s.*&S::pf, ""); 70 71 static_assert(pm == &S::m, ""); 72 static_assert(pm != pn, ""); 73 static_assert(s.pn != pn, ""); 74 static_assert(s.pn == pm, ""); 75 static_assert(pg != nullptr, ""); 76 static_assert(pf != nullptr, ""); 77 static_assert((int S::*)nullptr == nullptr, ""); 78 static_assert(pg == pg, ""); // both-error {{constant expression}} \ 79 // both-note {{comparison of pointer to virtual member function 'g' has unspecified value}} 80 static_assert(pf != pg, ""); // both-error {{constant expression}} \ 81 // both-note {{comparison of pointer to virtual member function 'g' has unspecified value}} 82 83 template<int n> struct T : T<n-1> { const int X = n;}; 84 template<> struct T<0> { int n; char k;}; 85 template<> struct T<30> : T<29> { int m; }; 86 87 T<17> t17; 88 T<30> t30; 89 90 constexpr int (T<15>::*deepm) = (int(T<10>::*))&T<30>::m; 91 constexpr int (T<10>::*deepn) = &T<0>::n; 92 constexpr char (T<10>::*deepk) = &T<0>::k; 93 94 static_assert(&(t17.*deepn) == &t17.n, ""); 95 static_assert(&(t17.*deepk) == &t17.k, ""); 96 static_assert(deepn == &T<2>::n, ""); 97 98 constexpr int *pgood = &(t30.*deepm); 99 constexpr int *pbad = &(t17.*deepm); // both-error {{constant expression}} 100 static_assert(&(t30.*deepm) == &t30.m, ""); 101 102 static_assert(deepm == &T<50>::m, ""); 103 static_assert(deepm != deepn, ""); 104 105 constexpr T<5> *p17_5 = &t17; 106 constexpr T<13> *p17_13 = (T<13>*)p17_5; 107 constexpr T<23> *p17_23 = (T<23>*)p17_13; // both-error {{constant expression}} \ 108 // both-note {{cannot cast object of dynamic type 'T<17>' to type 'T<23>'}} 109 constexpr T<18> *p17_18 = (T<18>*)p17_13; // both-error {{constant expression}} \ 110 // both-note {{cannot cast object of dynamic type 'T<17>' to type 'T<18>'}} 111 static_assert(&(p17_5->*(int(T<0>::*))deepn) == &t17.n, ""); 112 static_assert(&(p17_5->*(int(T<0>::*))deepn), ""); 113 114 115 static_assert(&(p17_13->*deepn) == &t17.n, ""); 116 constexpr int *pbad2 = &(p17_13->*(int(T<9>::*))deepm); // both-error {{constant expression}} 117 118 constexpr T<5> *p30_5 = &t30; 119 constexpr T<23> *p30_23 = (T<23>*)p30_5; 120 constexpr T<13> *p30_13 = p30_23; 121 static_assert(&(p30_13->*deepn) == &t30.n, ""); 122 static_assert(&(p30_23->*deepn) == &t30.n, ""); 123 static_assert(&(p30_5->*(int(T<3>::*))deepn) == &t30.n, ""); 124 125 static_assert(&(p30_5->*(int(T<2>::*))deepm) == &t30.m, ""); 126 static_assert(&(((T<17>*)p30_13)->*deepm) == &t30.m, ""); 127 static_assert(&(p30_23->*deepm) == &t30.m, ""); 128 129 130 /// Added tests not from constant-expression-cxx11.cpp 131 static_assert(pm, ""); 132 static_assert(!((int S::*)nullptr), ""); 133 constexpr int S::*pk = nullptr; 134 static_assert(!pk, ""); 135 } 136 137 namespace test3 { 138 struct nsCSSRect { 139 }; 140 static int nsCSSRect::* sides; 141 nsCSSRect dimenX; 142 void ParseBoxCornerRadii(int y) { 143 switch (y) { 144 } 145 int& x = dimenX.*sides; 146 } 147 } 148 149 void foo() { 150 class X; 151 void (X::*d) (); 152 d = nullptr; /// This calls in the constant interpreter. 153 } 154 155 namespace { 156 struct A { int n; }; 157 struct B { int n; }; 158 struct C : A, B {}; 159 struct D { double d; C c; }; 160 const int &&u = static_cast<B&&>(0, ((D&&)D{}).*&D::c).n; // both-warning {{left operand of comma operator has no effect}} 161 } 162 163 /// From SemaTemplate/instantiate-member-pointers.cpp 164 namespace { 165 struct Y { 166 int x; 167 }; 168 169 template<typename T, typename Class, T Class::*Ptr> 170 struct X3 { 171 X3<T, Class, Ptr> &operator=(const T& value) { 172 return *this; 173 } 174 }; 175 176 typedef int Y::*IntMember; 177 template<IntMember Member> 178 struct X4 { 179 X3<int, Y, Member> member; 180 int &getMember(Y& y) { return y.*Member; } 181 }; 182 183 int &get_X4(X4<&Y::x> x4, Y& y) { 184 return x4.getMember(y); 185 } 186 } 187 188 /// From test/CXX/basic/basic.def.odr/p2.cpp 189 namespace { 190 void use(int); 191 struct S { int x; int f() const; }; 192 constexpr S *ps = nullptr; 193 S *const &psr = ps; 194 195 void test() { 196 use(ps->*&S::x); 197 use(psr->*&S::x); 198 } 199 } 200 201 namespace MemPtrTemporary { 202 struct A { 203 constexpr int f() const { return 5; } 204 }; 205 206 constexpr int apply(const A &a, int (A::*ff)() const) { 207 return (a.*ff)(); 208 } 209 210 static_assert(apply(A(), &A::f) == 5, ""); 211 } 212 213 namespace IndirectFields { 214 struct I { union { struct { int a, b; }; }; }; 215 216 template <typename T, int T::*F> 217 constexpr int ReadField(const T &o) { 218 return F ? o.*F : 0; 219 } 220 void ReadFields() { 221 I i; 222 ReadField<I, &I::a>(i); 223 ReadField<I, &I::b>(i); 224 } 225 226 constexpr I i{12}; 227 static_assert(ReadField<I, &I::a>(i) == 12, ""); 228 } 229