1 // RUN: %clang_cc1 -std=c++11 -fms-compatibility -fsyntax-only -triple=i386-pc-win32 -verify -DVMB %s
2 // RUN: %clang_cc1 -std=c++11 -fms-compatibility -fsyntax-only -triple=x86_64-pc-win32 -verify -DVMB %s
3 // RUN: %clang_cc1 -std=c++11 -fms-compatibility -fsyntax-only -triple=x86_64-pc-win32 -verify -DVMV -fms-memptr-rep=virtual %s
5 // This file should also give no diagnostics when run through cl.exe from MSVS
6 // 2012, which supports C++11 and static_assert. It should pass for both 64-bit
9 // Test the size of various member pointer combinations:
10 // - complete and incomplete
11 // - single, multiple, and virtual inheritance (and unspecified for incomplete)
12 // - data and function pointers
13 // - templated with declared specializations with annotations
14 // - template that can be instantiated
16 // http://llvm.org/PR12070
18 typedef int Foo::*FooInt
;
24 kSingleDataAlign
= 1 * sizeof(int),
25 kSingleFunctionAlign
= 1 * sizeof(void *),
26 kMultipleDataAlign
= 1 * sizeof(int),
27 // Everything with more than 1 field is 8 byte aligned, except virtual data
28 // member pointers on x64 (ugh).
29 kMultipleFunctionAlign
= 8,
31 kVirtualDataAlign
= 4,
33 kVirtualDataAlign
= 8,
35 kVirtualFunctionAlign
= 8,
36 kUnspecifiedDataAlign
= 8,
37 kUnspecifiedFunctionAlign
= 8,
39 kSingleDataSize
= 1 * sizeof(int),
40 kSingleFunctionSize
= 1 * sizeof(void *),
41 kMultipleDataSize
= 1 * sizeof(int),
42 kMultipleFunctionSize
= 2 * sizeof(void *),
43 kVirtualDataSize
= 2 * sizeof(int),
44 kVirtualFunctionSize
= 2 * sizeof(int) + 1 * sizeof(void *),
45 kUnspecifiedDataSize
= 3 * sizeof(int),
46 kUnspecifiedFunctionSize
= 2 * sizeof(int) + 2 * sizeof(void *),
50 // Everything with more than 1 field is 8 byte aligned, except virtual data
51 // member pointers on x64 (ugh).
53 kVirtualDataAlign
= 4,
55 kVirtualDataAlign
= 8,
57 kMultipleDataAlign
= kVirtualDataAlign
,
58 kSingleDataAlign
= kVirtualDataAlign
,
60 kUnspecifiedFunctionAlign
= 8,
61 kVirtualFunctionAlign
= kUnspecifiedFunctionAlign
,
62 kMultipleFunctionAlign
= kUnspecifiedFunctionAlign
,
63 kSingleFunctionAlign
= kUnspecifiedFunctionAlign
,
65 kUnspecifiedDataSize
= 3 * sizeof(int),
66 kVirtualDataSize
= kUnspecifiedDataSize
,
67 kMultipleDataSize
= kUnspecifiedDataSize
,
68 kSingleDataSize
= kUnspecifiedDataSize
,
70 kUnspecifiedFunctionSize
= 2 * sizeof(int) + 2 * sizeof(void *),
71 kVirtualFunctionSize
= kUnspecifiedFunctionSize
,
72 kMultipleFunctionSize
= kUnspecifiedFunctionSize
,
73 kSingleFunctionSize
= kUnspecifiedFunctionSize
,
76 #error "test doesn't yet support this mode!"
81 class __single_inheritance IncSingle
;
82 class __multiple_inheritance IncMultiple
;
83 class __virtual_inheritance IncVirtual
;
89 static_assert(sizeof(int IncSingle::*) == kSingleDataSize
, "");
90 static_assert(sizeof(int IncMultiple::*) == kMultipleDataSize
, "");
91 static_assert(sizeof(int IncVirtual::*) == kVirtualDataSize
, "");
92 static_assert(sizeof(void (IncSingle::*)()) == kSingleFunctionSize
, "");
93 static_assert(sizeof(void (IncMultiple::*)()) == kMultipleFunctionSize
, "");
94 static_assert(sizeof(void (IncVirtual::*)()) == kVirtualFunctionSize
, "");
96 static_assert(__alignof(int IncSingle::*) == __alignof(void *), "");
97 static_assert(__alignof(int IncMultiple::*) == __alignof(void *), "");
98 static_assert(__alignof(int IncVirtual::*) == __alignof(void *), "");
99 static_assert(__alignof(void (IncSingle::*)()) == __alignof(void *), "");
100 static_assert(__alignof(void (IncMultiple::*)()) == __alignof(void *), "");
101 static_assert(__alignof(void (IncVirtual::*)()) == __alignof(void *), "");
103 // An incomplete type with an unspecified inheritance model seems to take one
104 // more slot than virtual.
105 class IncUnspecified
;
106 static_assert(sizeof(int IncUnspecified::*) == kUnspecifiedDataSize
, "");
107 static_assert(sizeof(void (IncUnspecified::*)()) == kUnspecifiedFunctionSize
, "");
113 struct Multiple
: B1
, B2
{ };
114 struct Virtual
: virtual B1
{ };
115 static_assert(sizeof(int Single::*) == kSingleDataSize
, "");
116 static_assert(sizeof(int Multiple::*) == kMultipleDataSize
, "");
117 static_assert(sizeof(int Virtual::*) == kVirtualDataSize
, "");
118 static_assert(sizeof(void (Single::*)()) == kSingleFunctionSize
, "");
119 static_assert(sizeof(void (Multiple::*)()) == kMultipleFunctionSize
, "");
120 static_assert(sizeof(void (Virtual::*)()) == kVirtualFunctionSize
, "");
122 // Test both declared and defined templates.
123 template <typename T
> class X
;
125 template <> class __single_inheritance X
<IncSingle
>;
126 template <> class __multiple_inheritance X
<IncMultiple
>;
127 template <> class __virtual_inheritance X
<IncVirtual
>;
129 template <> class X
<IncSingle
>;
130 template <> class X
<IncMultiple
>;
131 template <> class X
<IncVirtual
>;
133 // Don't declare X<IncUnspecified>.
134 static_assert(sizeof(int X
<IncSingle
>::*) == kSingleDataSize
, "");
135 static_assert(sizeof(int X
<IncMultiple
>::*) == kMultipleDataSize
, "");
136 static_assert(sizeof(int X
<IncVirtual
>::*) == kVirtualDataSize
, "");
137 static_assert(sizeof(int X
<IncUnspecified
>::*) == kUnspecifiedDataSize
, "");
138 static_assert(sizeof(void (X
<IncSingle
>::*)()) == kSingleFunctionSize
, "");
139 static_assert(sizeof(void (X
<IncMultiple
>::*)()) == kMultipleFunctionSize
, "");
140 static_assert(sizeof(void (X
<IncVirtual
>::*)()) == kVirtualFunctionSize
, "");
141 static_assert(sizeof(void (X
<IncUnspecified
>::*)()) == kUnspecifiedFunctionSize
, "");
143 template <typename T
>
145 static_assert(sizeof(int Y
<Single
>::*) == kSingleDataSize
, "");
146 static_assert(sizeof(int Y
<Multiple
>::*) == kMultipleDataSize
, "");
147 static_assert(sizeof(int Y
<Virtual
>::*) == kVirtualDataSize
, "");
148 static_assert(sizeof(void (Y
<Single
>::*)()) == kSingleFunctionSize
, "");
149 static_assert(sizeof(void (Y
<Multiple
>::*)()) == kMultipleFunctionSize
, "");
150 static_assert(sizeof(void (Y
<Virtual
>::*)()) == kVirtualFunctionSize
, "");
152 struct A
{ int x
; void bar(); };
153 struct B
: A
{ virtual void foo(); };
154 static_assert(sizeof(int B::*) == kSingleDataSize
, "");
155 // A non-primary base class uses the multiple inheritance model for member
157 static_assert(sizeof(void (B::*)()) == kMultipleFunctionSize
, "");
159 struct AA
{ int x
; virtual void foo(); };
160 struct BB
: AA
{ void bar(); };
161 struct CC
: BB
{ virtual void baz(); };
162 static_assert(sizeof(void (CC::*)()) == kSingleFunctionSize
, "");
164 // We start out unspecified.
168 // Re-declare to force us to iterate decls when adding attributes.
172 typedef int ForwardDecl1::*MemPtr1
;
173 typedef int ForwardDecl2::*MemPtr2
;
174 MemPtr1 variable_forces_sizing
;
176 struct ForwardDecl1
: B
{
179 struct ForwardDecl2
: B
{
183 static_assert(sizeof(variable_forces_sizing
) == kUnspecifiedDataSize
, "");
184 static_assert(sizeof(MemPtr1
) == kUnspecifiedDataSize
, "");
185 static_assert(sizeof(MemPtr2
) == kSingleDataSize
, "");
187 struct MemPtrInBody
{
188 typedef int MemPtrInBody::*MemPtr
;
190 operator MemPtr() const {
191 return a
? &MemPtrInBody::a
: 0;
195 static_assert(sizeof(MemPtrInBody::MemPtr
) == kSingleDataSize
, "");
197 // Passing a member pointer through a template should get the right size.
199 struct SingleTemplate
;
201 struct SingleTemplate
<void (T::*)(void)> {
202 static_assert(sizeof(int T::*) == kSingleDataSize
, "");
203 static_assert(sizeof(void (T::*)()) == kSingleFunctionSize
, "");
207 struct UnspecTemplate
;
209 struct UnspecTemplate
<void (T::*)(void)> {
210 static_assert(sizeof(int T::*) == kUnspecifiedDataSize
, "");
211 static_assert(sizeof(void (T::*)()) == kUnspecifiedFunctionSize
, "");
214 struct NewUnspecified
;
215 SingleTemplate
<void (IncSingle::*)()> tmpl_single
;
216 UnspecTemplate
<void (NewUnspecified::*)()> tmpl_unspec
;
218 struct NewUnspecified
{ };
220 static_assert(sizeof(void (NewUnspecified::*)()) == kUnspecifiedFunctionSize
, "");
222 template <typename T
>
223 struct MemPtrInTemplate
{
224 // We can't require that the template arg be complete until we're
227 void (T::*func_ptr
)();
231 int Virtual::*CastTest
= reinterpret_cast<int Virtual::*>(&AA::x
);
232 // expected-error@-1 {{cannot reinterpret_cast from member pointer type}}
235 namespace ErrorTest
{
236 template <typename T
, typename U
> struct __single_inheritance A
;
237 // expected-warning@-1 {{inheritance model ignored on primary template}}
238 template <typename T
> struct __multiple_inheritance A
<T
, T
>;
239 // expected-warning@-1 {{inheritance model ignored on partial specialization}}
240 template <> struct __single_inheritance A
<int, float>;
242 struct B
{}; // expected-note {{'B' defined here}}
243 struct __multiple_inheritance B
; // expected-error{{inheritance model does not match definition}}
245 struct __multiple_inheritance C
{}; // expected-error{{inheritance model does not match definition}}
246 // expected-note@-1 {{'C' defined here}}
248 struct __virtual_inheritance D
;
249 struct D
: virtual B
{};
254 template <typename T
>
271 #pragma pointers_to_members(full_generality, multiple_inheritance)
272 struct TrulySingleInheritance
;
273 static_assert(sizeof(int TrulySingleInheritance::*) == kMultipleDataSize
, "");
274 #pragma pointers_to_members(best_case)
275 // This definition shouldn't conflict with the increased generality that the
276 // multiple_inheritance model gave to TrulySingleInheritance.
277 struct TrulySingleInheritance
{};
279 // Even if a definition proceeds the first mention of a pointer to member, we
280 // still give the record the fully general representation.
281 #pragma pointers_to_members(full_generality, virtual_inheritance)
282 struct SingleInheritanceAsVirtualAfterPragma
{};
283 static_assert(sizeof(int SingleInheritanceAsVirtualAfterPragma::*) == 12, "");
285 #pragma pointers_to_members(best_case)
287 // The above holds even if the pragma comes after the definition.
288 struct SingleInheritanceAsVirtualBeforePragma
{};
289 #pragma pointers_to_members(virtual_inheritance)
290 static_assert(sizeof(int SingleInheritanceAsVirtualBeforePragma::*) == 12, "");
292 #pragma pointers_to_members(single) // expected-error{{unexpected 'single'}}
296 struct __single_inheritance S
;
297 struct __single_inheritance S
;
299 struct __single_inheritance M
; // expected-note{{previous inheritance model specified here}}
300 struct __multiple_inheritance M
; // expected-error{{inheritance model does not match previous declaration}}