Clang Project

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