1*67e74705SXin Li // RUN: %clang_cc1 -std=c++11 -fms-compatibility -fsyntax-only -triple=i386-pc-win32 -verify -DVMB %s
2*67e74705SXin Li // RUN: %clang_cc1 -std=c++11 -fms-compatibility -fsyntax-only -triple=x86_64-pc-win32 -verify -DVMB %s
3*67e74705SXin Li // RUN: %clang_cc1 -std=c++11 -fms-compatibility -fsyntax-only -triple=x86_64-pc-win32 -verify -DVMV -fms-memptr-rep=virtual %s
4*67e74705SXin Li //
5*67e74705SXin Li // This file should also give no diagnostics when run through cl.exe from MSVS
6*67e74705SXin Li // 2012, which supports C++11 and static_assert. It should pass for both 64-bit
7*67e74705SXin Li // and 32-bit x86.
8*67e74705SXin Li //
9*67e74705SXin Li // Test the size of various member pointer combinations:
10*67e74705SXin Li // - complete and incomplete
11*67e74705SXin Li // - single, multiple, and virtual inheritance (and unspecified for incomplete)
12*67e74705SXin Li // - data and function pointers
13*67e74705SXin Li // - templated with declared specializations with annotations
14*67e74705SXin Li // - template that can be instantiated
15*67e74705SXin Li
16*67e74705SXin Li // http://llvm.org/PR12070
17*67e74705SXin Li struct Foo {
18*67e74705SXin Li typedef int Foo::*FooInt;
19*67e74705SXin Li int f;
20*67e74705SXin Li };
21*67e74705SXin Li
22*67e74705SXin Li #ifdef VMB
23*67e74705SXin Li enum {
24*67e74705SXin Li kSingleDataAlign = 1 * sizeof(int),
25*67e74705SXin Li kSingleFunctionAlign = 1 * sizeof(void *),
26*67e74705SXin Li kMultipleDataAlign = 1 * sizeof(int),
27*67e74705SXin Li // Everything with more than 1 field is 8 byte aligned, except virtual data
28*67e74705SXin Li // member pointers on x64 (ugh).
29*67e74705SXin Li kMultipleFunctionAlign = 8,
30*67e74705SXin Li #ifdef _M_X64
31*67e74705SXin Li kVirtualDataAlign = 4,
32*67e74705SXin Li #else
33*67e74705SXin Li kVirtualDataAlign = 8,
34*67e74705SXin Li #endif
35*67e74705SXin Li kVirtualFunctionAlign = 8,
36*67e74705SXin Li kUnspecifiedDataAlign = 8,
37*67e74705SXin Li kUnspecifiedFunctionAlign = 8,
38*67e74705SXin Li
39*67e74705SXin Li kSingleDataSize = 1 * sizeof(int),
40*67e74705SXin Li kSingleFunctionSize = 1 * sizeof(void *),
41*67e74705SXin Li kMultipleDataSize = 1 * sizeof(int),
42*67e74705SXin Li kMultipleFunctionSize = 2 * sizeof(void *),
43*67e74705SXin Li kVirtualDataSize = 2 * sizeof(int),
44*67e74705SXin Li kVirtualFunctionSize = 2 * sizeof(int) + 1 * sizeof(void *),
45*67e74705SXin Li kUnspecifiedDataSize = 3 * sizeof(int),
46*67e74705SXin Li kUnspecifiedFunctionSize = 2 * sizeof(int) + 2 * sizeof(void *),
47*67e74705SXin Li };
48*67e74705SXin Li #elif VMV
49*67e74705SXin Li enum {
50*67e74705SXin Li // Everything with more than 1 field is 8 byte aligned, except virtual data
51*67e74705SXin Li // member pointers on x64 (ugh).
52*67e74705SXin Li #ifdef _M_X64
53*67e74705SXin Li kVirtualDataAlign = 4,
54*67e74705SXin Li #else
55*67e74705SXin Li kVirtualDataAlign = 8,
56*67e74705SXin Li #endif
57*67e74705SXin Li kMultipleDataAlign = kVirtualDataAlign,
58*67e74705SXin Li kSingleDataAlign = kVirtualDataAlign,
59*67e74705SXin Li
60*67e74705SXin Li kUnspecifiedFunctionAlign = 8,
61*67e74705SXin Li kVirtualFunctionAlign = kUnspecifiedFunctionAlign,
62*67e74705SXin Li kMultipleFunctionAlign = kUnspecifiedFunctionAlign,
63*67e74705SXin Li kSingleFunctionAlign = kUnspecifiedFunctionAlign,
64*67e74705SXin Li
65*67e74705SXin Li kUnspecifiedDataSize = 3 * sizeof(int),
66*67e74705SXin Li kVirtualDataSize = kUnspecifiedDataSize,
67*67e74705SXin Li kMultipleDataSize = kUnspecifiedDataSize,
68*67e74705SXin Li kSingleDataSize = kUnspecifiedDataSize,
69*67e74705SXin Li
70*67e74705SXin Li kUnspecifiedFunctionSize = 2 * sizeof(int) + 2 * sizeof(void *),
71*67e74705SXin Li kVirtualFunctionSize = kUnspecifiedFunctionSize,
72*67e74705SXin Li kMultipleFunctionSize = kUnspecifiedFunctionSize,
73*67e74705SXin Li kSingleFunctionSize = kUnspecifiedFunctionSize,
74*67e74705SXin Li };
75*67e74705SXin Li #else
76*67e74705SXin Li #error "test doesn't yet support this mode!"
77*67e74705SXin Li #endif
78*67e74705SXin Li
79*67e74705SXin Li // incomplete types
80*67e74705SXin Li #ifdef VMB
81*67e74705SXin Li class __single_inheritance IncSingle;
82*67e74705SXin Li class __multiple_inheritance IncMultiple;
83*67e74705SXin Li class __virtual_inheritance IncVirtual;
84*67e74705SXin Li #else
85*67e74705SXin Li class IncSingle;
86*67e74705SXin Li class IncMultiple;
87*67e74705SXin Li class IncVirtual;
88*67e74705SXin Li #endif
89*67e74705SXin Li static_assert(sizeof(int IncSingle::*) == kSingleDataSize, "");
90*67e74705SXin Li static_assert(sizeof(int IncMultiple::*) == kMultipleDataSize, "");
91*67e74705SXin Li static_assert(sizeof(int IncVirtual::*) == kVirtualDataSize, "");
92*67e74705SXin Li static_assert(sizeof(void (IncSingle::*)()) == kSingleFunctionSize, "");
93*67e74705SXin Li static_assert(sizeof(void (IncMultiple::*)()) == kMultipleFunctionSize, "");
94*67e74705SXin Li static_assert(sizeof(void (IncVirtual::*)()) == kVirtualFunctionSize, "");
95*67e74705SXin Li
96*67e74705SXin Li static_assert(__alignof(int IncSingle::*) == __alignof(void *), "");
97*67e74705SXin Li static_assert(__alignof(int IncMultiple::*) == __alignof(void *), "");
98*67e74705SXin Li static_assert(__alignof(int IncVirtual::*) == __alignof(void *), "");
99*67e74705SXin Li static_assert(__alignof(void (IncSingle::*)()) == __alignof(void *), "");
100*67e74705SXin Li static_assert(__alignof(void (IncMultiple::*)()) == __alignof(void *), "");
101*67e74705SXin Li static_assert(__alignof(void (IncVirtual::*)()) == __alignof(void *), "");
102*67e74705SXin Li
103*67e74705SXin Li // An incomplete type with an unspecified inheritance model seems to take one
104*67e74705SXin Li // more slot than virtual.
105*67e74705SXin Li class IncUnspecified;
106*67e74705SXin Li static_assert(sizeof(int IncUnspecified::*) == kUnspecifiedDataSize, "");
107*67e74705SXin Li static_assert(sizeof(void (IncUnspecified::*)()) == kUnspecifiedFunctionSize, "");
108*67e74705SXin Li
109*67e74705SXin Li // complete types
110*67e74705SXin Li struct B1 { };
111*67e74705SXin Li struct B2 { };
112*67e74705SXin Li struct Single { };
113*67e74705SXin Li struct Multiple : B1, B2 { };
114*67e74705SXin Li struct Virtual : virtual B1 { };
115*67e74705SXin Li static_assert(sizeof(int Single::*) == kSingleDataSize, "");
116*67e74705SXin Li static_assert(sizeof(int Multiple::*) == kMultipleDataSize, "");
117*67e74705SXin Li static_assert(sizeof(int Virtual::*) == kVirtualDataSize, "");
118*67e74705SXin Li static_assert(sizeof(void (Single::*)()) == kSingleFunctionSize, "");
119*67e74705SXin Li static_assert(sizeof(void (Multiple::*)()) == kMultipleFunctionSize, "");
120*67e74705SXin Li static_assert(sizeof(void (Virtual::*)()) == kVirtualFunctionSize, "");
121*67e74705SXin Li
122*67e74705SXin Li // Test both declared and defined templates.
123*67e74705SXin Li template <typename T> class X;
124*67e74705SXin Li #ifdef VMB
125*67e74705SXin Li template <> class __single_inheritance X<IncSingle>;
126*67e74705SXin Li template <> class __multiple_inheritance X<IncMultiple>;
127*67e74705SXin Li template <> class __virtual_inheritance X<IncVirtual>;
128*67e74705SXin Li #else
129*67e74705SXin Li template <> class X<IncSingle>;
130*67e74705SXin Li template <> class X<IncMultiple>;
131*67e74705SXin Li template <> class X<IncVirtual>;
132*67e74705SXin Li #endif
133*67e74705SXin Li // Don't declare X<IncUnspecified>.
134*67e74705SXin Li static_assert(sizeof(int X<IncSingle>::*) == kSingleDataSize, "");
135*67e74705SXin Li static_assert(sizeof(int X<IncMultiple>::*) == kMultipleDataSize, "");
136*67e74705SXin Li static_assert(sizeof(int X<IncVirtual>::*) == kVirtualDataSize, "");
137*67e74705SXin Li static_assert(sizeof(int X<IncUnspecified>::*) == kUnspecifiedDataSize, "");
138*67e74705SXin Li static_assert(sizeof(void (X<IncSingle>::*)()) == kSingleFunctionSize, "");
139*67e74705SXin Li static_assert(sizeof(void (X<IncMultiple>::*)()) == kMultipleFunctionSize, "");
140*67e74705SXin Li static_assert(sizeof(void (X<IncVirtual>::*)()) == kVirtualFunctionSize, "");
141*67e74705SXin Li static_assert(sizeof(void (X<IncUnspecified>::*)()) == kUnspecifiedFunctionSize, "");
142*67e74705SXin Li
143*67e74705SXin Li template <typename T>
144*67e74705SXin Li struct Y : T { };
145*67e74705SXin Li static_assert(sizeof(int Y<Single>::*) == kSingleDataSize, "");
146*67e74705SXin Li static_assert(sizeof(int Y<Multiple>::*) == kMultipleDataSize, "");
147*67e74705SXin Li static_assert(sizeof(int Y<Virtual>::*) == kVirtualDataSize, "");
148*67e74705SXin Li static_assert(sizeof(void (Y<Single>::*)()) == kSingleFunctionSize, "");
149*67e74705SXin Li static_assert(sizeof(void (Y<Multiple>::*)()) == kMultipleFunctionSize, "");
150*67e74705SXin Li static_assert(sizeof(void (Y<Virtual>::*)()) == kVirtualFunctionSize, "");
151*67e74705SXin Li
152*67e74705SXin Li struct A { int x; void bar(); };
153*67e74705SXin Li struct B : A { virtual void foo(); };
154*67e74705SXin Li static_assert(sizeof(int B::*) == kSingleDataSize, "");
155*67e74705SXin Li // A non-primary base class uses the multiple inheritance model for member
156*67e74705SXin Li // pointers.
157*67e74705SXin Li static_assert(sizeof(void (B::*)()) == kMultipleFunctionSize, "");
158*67e74705SXin Li
159*67e74705SXin Li struct AA { int x; virtual void foo(); };
160*67e74705SXin Li struct BB : AA { void bar(); };
161*67e74705SXin Li struct CC : BB { virtual void baz(); };
162*67e74705SXin Li static_assert(sizeof(void (CC::*)()) == kSingleFunctionSize, "");
163*67e74705SXin Li
164*67e74705SXin Li // We start out unspecified.
165*67e74705SXin Li struct ForwardDecl1;
166*67e74705SXin Li struct ForwardDecl2;
167*67e74705SXin Li
168*67e74705SXin Li // Re-declare to force us to iterate decls when adding attributes.
169*67e74705SXin Li struct ForwardDecl1;
170*67e74705SXin Li struct ForwardDecl2;
171*67e74705SXin Li
172*67e74705SXin Li typedef int ForwardDecl1::*MemPtr1;
173*67e74705SXin Li typedef int ForwardDecl2::*MemPtr2;
174*67e74705SXin Li MemPtr1 variable_forces_sizing;
175*67e74705SXin Li
176*67e74705SXin Li struct ForwardDecl1 : B {
177*67e74705SXin Li virtual void foo();
178*67e74705SXin Li };
179*67e74705SXin Li struct ForwardDecl2 : B {
180*67e74705SXin Li virtual void foo();
181*67e74705SXin Li };
182*67e74705SXin Li
183*67e74705SXin Li static_assert(sizeof(variable_forces_sizing) == kUnspecifiedDataSize, "");
184*67e74705SXin Li static_assert(sizeof(MemPtr1) == kUnspecifiedDataSize, "");
185*67e74705SXin Li static_assert(sizeof(MemPtr2) == kSingleDataSize, "");
186*67e74705SXin Li
187*67e74705SXin Li struct MemPtrInBody {
188*67e74705SXin Li typedef int MemPtrInBody::*MemPtr;
189*67e74705SXin Li int a;
operator MemPtrMemPtrInBody190*67e74705SXin Li operator MemPtr() const {
191*67e74705SXin Li return a ? &MemPtrInBody::a : 0;
192*67e74705SXin Li }
193*67e74705SXin Li };
194*67e74705SXin Li
195*67e74705SXin Li static_assert(sizeof(MemPtrInBody::MemPtr) == kSingleDataSize, "");
196*67e74705SXin Li
197*67e74705SXin Li // Passing a member pointer through a template should get the right size.
198*67e74705SXin Li template<typename T>
199*67e74705SXin Li struct SingleTemplate;
200*67e74705SXin Li template<typename T>
201*67e74705SXin Li struct SingleTemplate<void (T::*)(void)> {
202*67e74705SXin Li static_assert(sizeof(int T::*) == kSingleDataSize, "");
203*67e74705SXin Li static_assert(sizeof(void (T::*)()) == kSingleFunctionSize, "");
204*67e74705SXin Li };
205*67e74705SXin Li
206*67e74705SXin Li template<typename T>
207*67e74705SXin Li struct UnspecTemplate;
208*67e74705SXin Li template<typename T>
209*67e74705SXin Li struct UnspecTemplate<void (T::*)(void)> {
210*67e74705SXin Li static_assert(sizeof(int T::*) == kUnspecifiedDataSize, "");
211*67e74705SXin Li static_assert(sizeof(void (T::*)()) == kUnspecifiedFunctionSize, "");
212*67e74705SXin Li };
213*67e74705SXin Li
214*67e74705SXin Li struct NewUnspecified;
215*67e74705SXin Li SingleTemplate<void (IncSingle::*)()> tmpl_single;
216*67e74705SXin Li UnspecTemplate<void (NewUnspecified::*)()> tmpl_unspec;
217*67e74705SXin Li
218*67e74705SXin Li struct NewUnspecified { };
219*67e74705SXin Li
220*67e74705SXin Li static_assert(sizeof(void (NewUnspecified::*)()) == kUnspecifiedFunctionSize, "");
221*67e74705SXin Li
222*67e74705SXin Li template <typename T>
223*67e74705SXin Li struct MemPtrInTemplate {
224*67e74705SXin Li // We can't require that the template arg be complete until we're
225*67e74705SXin Li // instantiated.
226*67e74705SXin Li int T::*data_ptr;
227*67e74705SXin Li void (T::*func_ptr)();
228*67e74705SXin Li };
229*67e74705SXin Li
230*67e74705SXin Li #ifdef VMB
231*67e74705SXin Li int Virtual::*CastTest = reinterpret_cast<int Virtual::*>(&AA::x);
232*67e74705SXin Li // expected-error@-1 {{cannot reinterpret_cast from member pointer type}}
233*67e74705SXin Li #endif
234*67e74705SXin Li
235*67e74705SXin Li namespace ErrorTest {
236*67e74705SXin Li template <typename T, typename U> struct __single_inheritance A;
237*67e74705SXin Li // expected-warning@-1 {{inheritance model ignored on primary template}}
238*67e74705SXin Li template <typename T> struct __multiple_inheritance A<T, T>;
239*67e74705SXin Li // expected-warning@-1 {{inheritance model ignored on partial specialization}}
240*67e74705SXin Li template <> struct __single_inheritance A<int, float>;
241*67e74705SXin Li
242*67e74705SXin Li struct B {}; // expected-note {{B defined here}}
243*67e74705SXin Li struct __multiple_inheritance B; // expected-error{{inheritance model does not match definition}}
244*67e74705SXin Li
245*67e74705SXin Li struct __multiple_inheritance C {}; // expected-error{{inheritance model does not match definition}}
246*67e74705SXin Li // expected-note@-1 {{C defined here}}
247*67e74705SXin Li
248*67e74705SXin Li struct __virtual_inheritance D;
249*67e74705SXin Li struct D : virtual B {};
250*67e74705SXin Li }
251*67e74705SXin Li #ifdef VMB
252*67e74705SXin Li
253*67e74705SXin Li namespace PR20017 {
254*67e74705SXin Li template <typename T>
255*67e74705SXin Li struct A {
256*67e74705SXin Li int T::*f();
257*67e74705SXin Li };
258*67e74705SXin Li
259*67e74705SXin Li struct B;
260*67e74705SXin Li
261*67e74705SXin Li auto a = &A<B>::f;
262*67e74705SXin Li
263*67e74705SXin Li struct B {};
264*67e74705SXin Li
q()265*67e74705SXin Li void q() {
266*67e74705SXin Li A<B> b;
267*67e74705SXin Li (b.*a)();
268*67e74705SXin Li }
269*67e74705SXin Li }
270*67e74705SXin Li
271*67e74705SXin Li #pragma pointers_to_members(full_generality, multiple_inheritance)
272*67e74705SXin Li struct TrulySingleInheritance;
273*67e74705SXin Li static_assert(sizeof(int TrulySingleInheritance::*) == kMultipleDataSize, "");
274*67e74705SXin Li #pragma pointers_to_members(best_case)
275*67e74705SXin Li // This definition shouldn't conflict with the increased generality that the
276*67e74705SXin Li // multiple_inheritance model gave to TrulySingleInheritance.
277*67e74705SXin Li struct TrulySingleInheritance {};
278*67e74705SXin Li
279*67e74705SXin Li // Even if a definition proceeds the first mention of a pointer to member, we
280*67e74705SXin Li // still give the record the fully general representation.
281*67e74705SXin Li #pragma pointers_to_members(full_generality, virtual_inheritance)
282*67e74705SXin Li struct SingleInheritanceAsVirtualAfterPragma {};
283*67e74705SXin Li static_assert(sizeof(int SingleInheritanceAsVirtualAfterPragma::*) == 12, "");
284*67e74705SXin Li
285*67e74705SXin Li #pragma pointers_to_members(best_case)
286*67e74705SXin Li
287*67e74705SXin Li // The above holds even if the pragma comes after the definition.
288*67e74705SXin Li struct SingleInheritanceAsVirtualBeforePragma {};
289*67e74705SXin Li #pragma pointers_to_members(virtual_inheritance)
290*67e74705SXin Li static_assert(sizeof(int SingleInheritanceAsVirtualBeforePragma::*) == 12, "");
291*67e74705SXin Li
292*67e74705SXin Li #pragma pointers_to_members(single) // expected-error{{unexpected 'single'}}
293*67e74705SXin Li #endif
294