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
6 namespace MemberPointers
{
8 constexpr A(int n
) : n(n
) {}
10 constexpr int f() const { return n
+ 3; }
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, "");
20 constexpr B(int n
, int m
) : A(n
), m(m
) {}
22 constexpr int g() const { return n
+ m
+ 1; }
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, "");
36 static_assert((B(4, 11).*(int(A::*)() const)&B::g
)() == 16, "");
38 static_assert(((&b
)->*&A::f
)() == 12, "");
39 static_assert(((&b
)->*&B::g
)() == 23, "");
40 static_assert(((&b
)->*(int(A::*)()const)&B::g
)() == 23, "");
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
) {}
48 constexpr int f() const { return this->*pn
; }
49 virtual int g() const;
56 constexpr int S::*pm
= &S::m
;
57 constexpr int S::*pn
= &S::n
;
59 constexpr int (S::*pf
)() const = &S::f
;
60 constexpr int (S::*pg
)() const = &S::g
;
62 constexpr S
s(2, 5, &S::f
, &S::m
);
64 static_assert((s
.*&S::f
)() == 2, "");
65 static_assert((s
.*s
.pf
)() == 2, "");
67 static_assert(pf
== &S::f
, "");
69 static_assert(pf
== s
.*&S::pf
, "");
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}}
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
; };
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
;
94 static_assert(&(t17
.*deepn
) == &t17
.n
, "");
95 static_assert(&(t17
.*deepk
) == &t17
.k
, "");
96 static_assert(deepn
== &T
<2>::n
, "");
98 constexpr int *pgood
= &(t30
.*deepm
);
99 constexpr int *pbad
= &(t17
.*deepm
); // both-error {{constant expression}}
100 static_assert(&(t30
.*deepm
) == &t30
.m
, "");
102 static_assert(deepm
== &T
<50>::m
, "");
103 static_assert(deepm
!= deepn
, "");
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
), "");
115 static_assert(&(p17_13
->*deepn
) == &t17
.n
, "");
116 constexpr int *pbad2
= &(p17_13
->*(int(T
<9>::*))deepm
); // both-error {{constant expression}}
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
, "");
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
, "");
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
, "");
140 static int nsCSSRect::* sides
;
142 void ParseBoxCornerRadii(int y
) {
145 int& x
= dimenX
.*sides
;
152 d
= nullptr; /// This calls in the constant interpreter.
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}}
163 /// From SemaTemplate/instantiate-member-pointers.cpp
169 template<typename T
, typename Class
, T
Class::*Ptr
>
171 X3
<T
, Class
, Ptr
> &operator=(const T
& value
) {
176 typedef int Y::*IntMember
;
177 template<IntMember Member
>
179 X3
<int, Y
, Member
> member
;
180 int &getMember(Y
& y
) { return y
.*Member
; }
183 int &get_X4(X4
<&Y::x
> x4
, Y
& y
) {
184 return x4
.getMember(y
);
188 /// From test/CXX/basic/basic.def.odr/p2.cpp
191 struct S
{ int x
; int f() const; };
192 constexpr S
*ps
= nullptr;
201 namespace MemPtrTemporary
{
203 constexpr int f() const { return 5; }
206 constexpr int apply(const A
&a
, int (A::*ff
)() const) {
210 static_assert(apply(A(), &A::f
) == 5, "");
213 namespace IndirectFields
{
214 struct I
{ union { struct { int a
, b
; }; }; };
216 template <typename T
, int T::*F
>
217 constexpr int ReadField(const T
&o
) {
222 ReadField
<I
, &I::a
>(i
);
223 ReadField
<I
, &I::b
>(i
);
227 static_assert(ReadField
<I
, &I::a
>(i
) == 12, "");