xref: /aosp_15_r20/external/clang/test/CodeGenCXX/pod-member-memcpys.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -std=c++03 -fexceptions -fcxx-exceptions -o - %s | FileCheck %s
2*67e74705SXin Li // RUN: %clang_cc1 -triple i386-apple-darwin10 -emit-llvm -std=c++03 -o - %s | FileCheck --check-prefix=CHECK-2 %s
3*67e74705SXin Li 
4*67e74705SXin Li struct POD {
5*67e74705SXin Li   int w, x, y, z;
6*67e74705SXin Li };
7*67e74705SXin Li 
8*67e74705SXin Li struct PODLike {
9*67e74705SXin Li   int w, x, y, z;
10*67e74705SXin Li   PODLike();
11*67e74705SXin Li   ~PODLike();
12*67e74705SXin Li };
13*67e74705SXin Li 
14*67e74705SXin Li struct NonPOD {
15*67e74705SXin Li   NonPOD();
16*67e74705SXin Li   NonPOD(const NonPOD&);
17*67e74705SXin Li   NonPOD& operator=(const NonPOD&);
18*67e74705SXin Li };
19*67e74705SXin Li 
20*67e74705SXin Li struct Basic {
21*67e74705SXin Li   int a, b, c, d;
22*67e74705SXin Li   NonPOD np;
23*67e74705SXin Li   int w, x, y, z;
24*67e74705SXin Li };
25*67e74705SXin Li 
26*67e74705SXin Li struct PODMember {
27*67e74705SXin Li   int a, b, c, d;
28*67e74705SXin Li   POD p;
29*67e74705SXin Li   NonPOD np;
30*67e74705SXin Li   int w, x, y, z;
31*67e74705SXin Li };
32*67e74705SXin Li 
33*67e74705SXin Li struct PODLikeMember {
34*67e74705SXin Li   int a, b, c, d;
35*67e74705SXin Li   PODLike pl;
36*67e74705SXin Li   NonPOD np;
37*67e74705SXin Li   int w, x, y, z;
38*67e74705SXin Li };
39*67e74705SXin Li 
40*67e74705SXin Li struct ArrayMember {
41*67e74705SXin Li   int a, b, c, d;
42*67e74705SXin Li   int e[12];
43*67e74705SXin Li   NonPOD np;
44*67e74705SXin Li   int f[12];
45*67e74705SXin Li   int w, x, y, z;
46*67e74705SXin Li };
47*67e74705SXin Li 
48*67e74705SXin Li struct VolatileMember {
49*67e74705SXin Li   int a, b, c, d;
50*67e74705SXin Li   volatile int v;
51*67e74705SXin Li   NonPOD np;
52*67e74705SXin Li   int w, x, y, z;
53*67e74705SXin Li };
54*67e74705SXin Li 
55*67e74705SXin Li struct BitfieldMember {
56*67e74705SXin Li   int a, b, c, d;
57*67e74705SXin Li   NonPOD np;
58*67e74705SXin Li   int w : 6;
59*67e74705SXin Li   int x : 6;
60*67e74705SXin Li   int y : 6;
61*67e74705SXin Li   int z : 6;
62*67e74705SXin Li };
63*67e74705SXin Li 
64*67e74705SXin Li struct BitfieldMember2 {
65*67e74705SXin Li   unsigned a : 1;
66*67e74705SXin Li   unsigned b, c, d;
67*67e74705SXin Li   NonPOD np;
68*67e74705SXin Li };
69*67e74705SXin Li 
70*67e74705SXin Li struct BitfieldMember3 {
71*67e74705SXin Li   virtual void f();
72*67e74705SXin Li   int   : 8;
73*67e74705SXin Li   int x : 1;
74*67e74705SXin Li   int y;
75*67e74705SXin Li };
76*67e74705SXin Li 
77*67e74705SXin Li struct InnerClassMember {
78*67e74705SXin Li   struct {
79*67e74705SXin Li     int a, b, c, d;
80*67e74705SXin Li   } a;
81*67e74705SXin Li   int b, c, d, e;
82*67e74705SXin Li   NonPOD np;
83*67e74705SXin Li   int w, x, y, z;
84*67e74705SXin Li };
85*67e74705SXin Li 
86*67e74705SXin Li struct ReferenceMember {
ReferenceMemberReferenceMember87*67e74705SXin Li   ReferenceMember(int &a, int &b, int &c, int &d)
88*67e74705SXin Li     : a(a), b(b), c(c), d(d) {}
89*67e74705SXin Li   int &a;
90*67e74705SXin Li   int &b;
91*67e74705SXin Li   NonPOD np;
92*67e74705SXin Li   int &c;
93*67e74705SXin Li   int &d;
94*67e74705SXin Li };
95*67e74705SXin Li 
96*67e74705SXin Li struct __attribute__((packed)) PackedMembers {
97*67e74705SXin Li   char c;
98*67e74705SXin Li   NonPOD np;
99*67e74705SXin Li   int w, x, y, z;
100*67e74705SXin Li };
101*67e74705SXin Li 
102*67e74705SXin Li // COPY-ASSIGNMENT OPERATORS:
103*67e74705SXin Li 
104*67e74705SXin Li // Assignment operators are output in the order they're encountered.
105*67e74705SXin Li 
106*67e74705SXin Li #define CALL_AO(T) void callAO##T(T& a, const T& b) { a = b; }
107*67e74705SXin Li 
108*67e74705SXin Li CALL_AO(Basic)
109*67e74705SXin Li CALL_AO(PODMember)
110*67e74705SXin Li CALL_AO(PODLikeMember)
111*67e74705SXin Li CALL_AO(ArrayMember)
112*67e74705SXin Li CALL_AO(VolatileMember)
113*67e74705SXin Li CALL_AO(BitfieldMember)
114*67e74705SXin Li CALL_AO(InnerClassMember)
115*67e74705SXin Li CALL_AO(PackedMembers)
116*67e74705SXin Li 
117*67e74705SXin Li // Basic copy-assignment:
118*67e74705SXin Li // CHECK-LABEL: define linkonce_odr dereferenceable({{[0-9]+}}) %struct.Basic* @_ZN5BasicaSERKS_(%struct.Basic* %this, %struct.Basic* dereferenceable({{[0-9]+}}))
119*67e74705SXin Li // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
120*67e74705SXin Li // CHECK: call dereferenceable({{[0-9]+}}) %struct.NonPOD* @_ZN6NonPODaSERKS_
121*67e74705SXin Li // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
122*67e74705SXin Li // CHECK: ret %struct.Basic*
123*67e74705SXin Li 
124*67e74705SXin Li // PODMember copy-assignment:
125*67e74705SXin Li // CHECK-LABEL: define linkonce_odr dereferenceable({{[0-9]+}}) %struct.PODMember* @_ZN9PODMemberaSERKS_(%struct.PODMember* %this, %struct.PODMember* dereferenceable({{[0-9]+}}))
126*67e74705SXin Li // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 32, i32 4{{.*}})
127*67e74705SXin Li // CHECK: call dereferenceable({{[0-9]+}}) %struct.NonPOD* @_ZN6NonPODaSERKS_
128*67e74705SXin Li // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
129*67e74705SXin Li // CHECK: ret %struct.PODMember*
130*67e74705SXin Li 
131*67e74705SXin Li // PODLikeMember copy-assignment:
132*67e74705SXin Li // CHECK-LABEL: define linkonce_odr dereferenceable({{[0-9]+}}) %struct.PODLikeMember* @_ZN13PODLikeMemberaSERKS_(%struct.PODLikeMember* %this, %struct.PODLikeMember* dereferenceable({{[0-9]+}}))
133*67e74705SXin Li // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 32, i32 4{{.*}})
134*67e74705SXin Li // CHECK: call dereferenceable({{[0-9]+}}) %struct.NonPOD* @_ZN6NonPODaSERKS_
135*67e74705SXin Li // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
136*67e74705SXin Li // CHECK: ret %struct.PODLikeMember*
137*67e74705SXin Li 
138*67e74705SXin Li // ArrayMember copy-assignment:
139*67e74705SXin Li // CHECK-LABEL: define linkonce_odr dereferenceable({{[0-9]+}}) %struct.ArrayMember* @_ZN11ArrayMemberaSERKS_(%struct.ArrayMember* %this, %struct.ArrayMember* dereferenceable({{[0-9]+}}))
140*67e74705SXin Li // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 64, i32 4{{.*}})
141*67e74705SXin Li // CHECK: call dereferenceable({{[0-9]+}}) %struct.NonPOD* @_ZN6NonPODaSERKS_
142*67e74705SXin Li // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 64, i32 4{{.*}})
143*67e74705SXin Li // CHECK: ret %struct.ArrayMember*
144*67e74705SXin Li 
145*67e74705SXin Li // VolatileMember copy-assignment:
146*67e74705SXin Li // CHECK-LABEL: define linkonce_odr dereferenceable({{[0-9]+}}) %struct.VolatileMember* @_ZN14VolatileMemberaSERKS_(%struct.VolatileMember* %this, %struct.VolatileMember* dereferenceable({{[0-9]+}}))
147*67e74705SXin Li // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
148*67e74705SXin Li // CHECK: load volatile i32, i32* {{.*}}, align 4
149*67e74705SXin Li // CHECK: store volatile i32 {{.*}}, align 4
150*67e74705SXin Li // CHECK: call dereferenceable({{[0-9]+}}) %struct.NonPOD* @_ZN6NonPODaSERKS_
151*67e74705SXin Li // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
152*67e74705SXin Li // CHECK: ret %struct.VolatileMember*
153*67e74705SXin Li 
154*67e74705SXin Li // BitfieldMember copy-assignment:
155*67e74705SXin Li // CHECK-LABEL: define linkonce_odr dereferenceable({{[0-9]+}}) %struct.BitfieldMember* @_ZN14BitfieldMemberaSERKS_(%struct.BitfieldMember* %this, %struct.BitfieldMember* dereferenceable({{[0-9]+}}))
156*67e74705SXin Li // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
157*67e74705SXin Li // CHECK: call dereferenceable({{[0-9]+}}) %struct.NonPOD* @_ZN6NonPODaSERKS_
158*67e74705SXin Li // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 3, i32 1{{.*}})
159*67e74705SXin Li // CHECK: ret %struct.BitfieldMember*
160*67e74705SXin Li 
161*67e74705SXin Li // InnerClass copy-assignment:
162*67e74705SXin Li // CHECK-LABEL: define linkonce_odr dereferenceable({{[0-9]+}}) %struct.InnerClassMember* @_ZN16InnerClassMemberaSERKS_(%struct.InnerClassMember* %this, %struct.InnerClassMember* dereferenceable({{[0-9]+}}))
163*67e74705SXin Li // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 32, i32 4{{.*}})
164*67e74705SXin Li // CHECK: call dereferenceable({{[0-9]+}}) %struct.NonPOD* @_ZN6NonPODaSERKS_
165*67e74705SXin Li // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
166*67e74705SXin Li // CHECK: ret %struct.InnerClassMember*
167*67e74705SXin Li 
168*67e74705SXin Li // PackedMembers copy-assignment:
169*67e74705SXin Li // CHECK-LABEL: define linkonce_odr dereferenceable({{[0-9]+}}) %struct.PackedMembers* @_ZN13PackedMembersaSERKS_(%struct.PackedMembers* %this, %struct.PackedMembers* dereferenceable({{[0-9]+}}))
170*67e74705SXin Li // CHECK: call dereferenceable({{[0-9]+}}) %struct.NonPOD* @_ZN6NonPODaSERKS_
171*67e74705SXin Li // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 1{{.*}})
172*67e74705SXin Li // CHECK: ret %struct.PackedMembers*
173*67e74705SXin Li 
174*67e74705SXin Li // COPY-CONSTRUCTORS:
175*67e74705SXin Li 
176*67e74705SXin Li // Clang outputs copy-constructors in the reverse of the order that
177*67e74705SXin Li // copy-constructor calls are encountered. Add functions that call the copy
178*67e74705SXin Li // constructors of the classes above in reverse order here.
179*67e74705SXin Li 
180*67e74705SXin Li #define CALL_CC(T) T callCC##T(const T& b) { return b; }
181*67e74705SXin Li 
182*67e74705SXin Li CALL_CC(PackedMembers)
183*67e74705SXin Li // PackedMembers copy-assignment:
184*67e74705SXin Li // CHECK-LABEL: define linkonce_odr void @_ZN13PackedMembersC2ERKS_(%struct.PackedMembers* %this, %struct.PackedMembers* dereferenceable({{[0-9]+}}))
185*67e74705SXin Li // CHECK: call void @_ZN6NonPODC1ERKS_
186*67e74705SXin Li // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 1{{.*}})
187*67e74705SXin Li // CHECK: ret void
188*67e74705SXin Li 
189*67e74705SXin Li CALL_CC(BitfieldMember2)
190*67e74705SXin Li // BitfieldMember2 copy-constructor:
191*67e74705SXin Li // CHECK-2-LABEL: define linkonce_odr void @_ZN15BitfieldMember2C2ERKS_(%struct.BitfieldMember2* %this, %struct.BitfieldMember2* dereferenceable({{[0-9]+}}))
192*67e74705SXin Li // CHECK-2: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4, i1 false)
193*67e74705SXin Li // CHECK-2: call void @_ZN6NonPODC1ERKS_
194*67e74705SXin Li // CHECK-2: ret void
195*67e74705SXin Li 
196*67e74705SXin Li CALL_CC(BitfieldMember3)
197*67e74705SXin Li // BitfieldMember3 copy-constructor:
198*67e74705SXin Li // CHECK-LABEL: define linkonce_odr void @_ZN15BitfieldMember3C2ERKS_(%struct.BitfieldMember3* %this, %struct.BitfieldMember3* dereferenceable({{[0-9]+}}))
199*67e74705SXin Li // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 8, i32 8, i1 false)
200*67e74705SXin Li // CHECK: ret void
201*67e74705SXin Li 
202*67e74705SXin Li CALL_CC(ReferenceMember)
203*67e74705SXin Li // ReferenceMember copy-constructor:
204*67e74705SXin Li // CHECK-LABEL: define linkonce_odr void @_ZN15ReferenceMemberC2ERKS_(%struct.ReferenceMember* %this, %struct.ReferenceMember* dereferenceable({{[0-9]+}}))
205*67e74705SXin Li // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 8{{.*}})
206*67e74705SXin Li // CHECK: call void @_ZN6NonPODC1ERKS_
207*67e74705SXin Li // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 8{{.*}})
208*67e74705SXin Li // CHECK: ret void
209*67e74705SXin Li 
210*67e74705SXin Li CALL_CC(InnerClassMember)
211*67e74705SXin Li // InnerClass copy-constructor:
212*67e74705SXin Li // CHECK-LABEL: define linkonce_odr void @_ZN16InnerClassMemberC2ERKS_(%struct.InnerClassMember* %this, %struct.InnerClassMember* dereferenceable({{[0-9]+}}))
213*67e74705SXin Li // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 32, i32 4{{.*}})
214*67e74705SXin Li // CHECK: call void @_ZN6NonPODC1ERKS_
215*67e74705SXin Li // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
216*67e74705SXin Li // CHECK: ret void
217*67e74705SXin Li 
218*67e74705SXin Li CALL_CC(BitfieldMember)
219*67e74705SXin Li // BitfieldMember copy-constructor:
220*67e74705SXin Li // CHECK-LABEL: define linkonce_odr void @_ZN14BitfieldMemberC2ERKS_(%struct.BitfieldMember* %this, %struct.BitfieldMember* dereferenceable({{[0-9]+}}))
221*67e74705SXin Li // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
222*67e74705SXin Li // CHECK: call void @_ZN6NonPODC1ERKS_
223*67e74705SXin Li // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 3, i32 1{{.*}})
224*67e74705SXin Li // CHECK: ret void
225*67e74705SXin Li 
226*67e74705SXin Li CALL_CC(VolatileMember)
227*67e74705SXin Li // VolatileMember copy-constructor:
228*67e74705SXin Li // CHECK-LABEL: define linkonce_odr void @_ZN14VolatileMemberC2ERKS_(%struct.VolatileMember* %this, %struct.VolatileMember* dereferenceable({{[0-9]+}}))
229*67e74705SXin Li // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
230*67e74705SXin Li // CHECK: load volatile i32, i32* {{.*}}, align 4
231*67e74705SXin Li // CHECK: store volatile i32 {{.*}}, align 4
232*67e74705SXin Li // CHECK: call void @_ZN6NonPODC1ERKS_
233*67e74705SXin Li // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
234*67e74705SXin Li // CHECK: ret void
235*67e74705SXin Li 
236*67e74705SXin Li CALL_CC(ArrayMember)
237*67e74705SXin Li // ArrayMember copy-constructor:
238*67e74705SXin Li // CHECK-LABEL: define linkonce_odr void @_ZN11ArrayMemberC2ERKS_(%struct.ArrayMember* %this, %struct.ArrayMember* dereferenceable({{[0-9]+}}))
239*67e74705SXin Li // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 64, i32 4{{.*}})
240*67e74705SXin Li // CHECK: call void @_ZN6NonPODC1ERKS_
241*67e74705SXin Li // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 64, i32 4{{.*}})
242*67e74705SXin Li // CHECK: ret void
243*67e74705SXin Li 
244*67e74705SXin Li CALL_CC(PODLikeMember)
245*67e74705SXin Li // PODLikeMember copy-constructor:
246*67e74705SXin Li // CHECK-LABEL: define linkonce_odr void @_ZN13PODLikeMemberC2ERKS_(%struct.PODLikeMember* %this, %struct.PODLikeMember* dereferenceable({{[0-9]+}}))
247*67e74705SXin Li // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 32, i32 4{{.*}})
248*67e74705SXin Li // CHECK: invoke void @_ZN6NonPODC1ERKS_
249*67e74705SXin Li // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
250*67e74705SXin Li // CHECK: ret void
251*67e74705SXin Li // CHECK: landingpad
252*67e74705SXin Li // CHECK: invoke void @_ZN7PODLikeD1Ev
253*67e74705SXin Li 
254*67e74705SXin Li CALL_CC(PODMember)
255*67e74705SXin Li // PODMember copy-constructor:
256*67e74705SXin Li // CHECK-LABEL: define linkonce_odr void @_ZN9PODMemberC2ERKS_(%struct.PODMember* %this, %struct.PODMember* dereferenceable({{[0-9]+}}))
257*67e74705SXin Li // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 32, i32 4{{.*}})
258*67e74705SXin Li // CHECK: call void @_ZN6NonPODC1ERKS_
259*67e74705SXin Li // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
260*67e74705SXin Li // CHECK: ret void
261*67e74705SXin Li 
262*67e74705SXin Li CALL_CC(Basic)
263*67e74705SXin Li // Basic copy-constructor:
264*67e74705SXin Li // CHECK-LABEL: define linkonce_odr void @_ZN5BasicC2ERKS_(%struct.Basic* %this, %struct.Basic* dereferenceable({{[0-9]+}}))
265*67e74705SXin Li // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
266*67e74705SXin Li // CHECK: call void @_ZN6NonPODC1ERKS_
267*67e74705SXin Li // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
268*67e74705SXin Li // CHECK: ret void
269