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