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