xref: /llvm-project/clang/test/CodeGen/paren-list-agg-init.cpp (revision 94473f4db6a6f5f12d7c4081455b5b596094eac5)
1 // RUN: %clang_cc1 -std=c++20 %s -emit-llvm -triple x86_64-unknown-linux-gnu -o - | FileCheck %s
2 
3 template <typename T>
4 struct IsChar {
5   constexpr operator bool() const { return false; }
6 };
7 
8 template<>
9 struct IsChar<char> {
10   constexpr operator bool() const { return true; }
11 };
12 
13 template <typename T>
14 concept SameAsChar = (bool)IsInt<T>();
15 
16 // CHECK-DAG: [[STRUCT_A:%.*]] = type { i8, double }
17 struct A {
18   char i;
19   double j;
20 
21   template <SameAsChar T>
22   operator T() const { return i; };
23 };
24 
25 // CHECK-DAG: [[STRUCT_B:%.*]] = type { [[STRUCT_A]], i32 }
26 struct B {
27   A a;
28   int b;
29 };
30 
31 // CHECK-DAG: [[STRUCT_C:%.*]] = type <{ [[STRUCT_B]], [[STRUCT_A]], i32, [4 x i8] }>
32 struct C : public B, public A {
33   int c;
34 };
35 
36 // CHECK-DAG: [[STRUCT_D:%.*]] = type { [[STRUCT_A]], [[STRUCT_A]], i8, [[STRUCT_A]] }
37 struct D {
38   A a;
39   A b = A{2, 2.0};
40   unsigned : 2;
41   A c;
42 };
43 
44 // CHECK-DAG: [[STRUCT_E:%.*]] = type { i32, ptr }
45 struct E {
46   int a;
47   const char* fn = __builtin_FUNCTION();
48   ~E() {};
49 };
50 
51 struct F {
52   F (int i = 1);
53   F (const F &f) = delete;
54   F (F &&f) = default;
55 };
56 
57 // CHECK-DAG: [[STRUCT_G:%.*]] = type <{ i32, [4 x i8] }>
58 struct G {
59   int a;
60   F f;
61 };
62 
63 // CHECK-DAG: [[UNION_U:%.*]] = type { [[STRUCT_A]] }
64 // CHECK-DAG: [[STR:@.*]] = private unnamed_addr constant [6 x i8] {{.*}}foo18{{.*}}, align 1
65 union U {
66   unsigned : 1;
67   A a;
68   char b;
69 };
70 
71 
72 namespace gh61145 {
73   // CHECK-DAG: [[STRUCT_VEC:%.*]] = type { i8 }
74   struct Vec {
75     Vec();
76     Vec(Vec&&);
77     ~Vec();
78   };
79 
80   // CHECK-DAG: [[STRUCT_S1:%.*]] = type { i8 }
81   struct S1 {
82     Vec v;
83   };
84 
85   // CHECK-DAG: [[STRUCT_S2:%.*]] = type { i8, i8 }
86   struct S2 {
87     Vec v;
88     char c;
89   };
90 }
91 
92 namespace gh62266 {
93   // CHECK-DAG: [[STRUCT_H:%.*H.*]] = type { i32, i32 }
94   template <int J>
95   struct H {
96     int i;
97     int j = J;
98   };
99 }
100 
101 namespace gh61567 {
102   // CHECK-DAG: [[STRUCT_I:%.*I.*]] = type { i32, ptr }
103   struct I {
104     int a;
105     int&& r = 2;
106   };
107 }
108 
109 // CHECK-DAG: [[A1:@.*a1.*]] = internal constant [[STRUCT_A]] { i8 3, double 2.000000e+00 }, align 8
110 constexpr A a1(3.1, 2.0);
111 // CHECK-DAG: [[A2:@.*a2.*]] = internal constant [[STRUCT_A]] { i8 99, double 0.000000e+00 }, align 8
112 constexpr auto a2 = static_cast<A>('c');
113 // CHECK-DAG: [[B1:@.*b1.*]] = internal constant [[STRUCT_B]] { [[STRUCT_A]] { i8 99, double 0.000000e+00 }, i32 0 }, align 8
114 constexpr B b1(A('c'));
115 // CHECK-DAG: [[C1:@.*c1.*]] = internal constant { [[STRUCT_A]], i32, [4 x i8], i8, double, i32 } { [[STRUCT_A]] { i8 99, double 0.000000e+00 }, i32 0, [4 x i8] undef, i8 3, double 2.000000e+00, i32 0 }, align
116 constexpr C c1(b1, a1);
117 // CHECK-DAG: [[U1:@.*u1.*]] = internal constant [[UNION_U]] { [[STRUCT_A]] { i8 1, double 1.000000e+00 } }, align 8
118 constexpr U u1(A(1, 1));
119 // CHECK-DAG: [[D1:@.*d1.*]] = internal constant { [[STRUCT_A]], [[STRUCT_A]], [8 x i8], [[STRUCT_A]] } { [[STRUCT_A]] { i8 2, double 2.000000e+00 }, [[STRUCT_A]] { i8 2, double 2.000000e+00 }, [8 x i8] undef, [[STRUCT_A]] zeroinitializer }, align 8
120 constexpr D d1(A(2, 2));
121 // CHECK-DAG: [[ARR1:@.*arr1.*]] = internal constant [3 x i32] [i32 1, i32 2, i32 0], align 4
122 constexpr int arr1[3](1, 2);
123 // CHECK-DAG: [[ARR4:@.*arr4.*]] = internal constant [1 x i32] [i32 1], align 4
124 constexpr int arr4[](1);
125 // CHECK-DAG: [[ARR5:@.*arr5.*]] = internal constant [2 x i32] [i32 2, i32 0], align 4
126 constexpr int arr5[2](2);
127 
128 // CHECK: define dso_local { i8, double } @{{.*foo1.*}}
129 // CHECK-NEXT: entry:
130 // CHECK-NEXT: [[RETVAL:%.*]] = alloca [[STRUCT_A]], align 8
131 // CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[RETVAL]], ptr align 8 [[A1]], i64 16, i1 false)
132 // CHECK-NEXT: [[TMP_0:%.*]] = load { i8, double }, ptr [[RETVAL]], align 8
133 // CHECK-NEXT: ret { i8, double } [[TMP_0]]
134 A foo1() {
135   return a1;
136 }
137 
138 // CHECK: define dso_local void @{{.*foo2.*}}(ptr dead_on_unwind noalias writable sret([[STRUCT_B]]) align 8 [[AGG_RESULT:%.*]])
139 // CHECK-NEXT: entry:
140 // CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[AGG_RESULT]], ptr align 8 [[B1]], i64 24, i1 false)
141 // CHECK-NEXT: ret void
142 B foo2() {
143   return b1;
144 }
145 
146 // CHECK: define dso_local void @{{.*foo3.*}}(ptr dead_on_unwind noalias writable sret([[STRUCT_C]]) align 8 [[AGG_RESULT:%.*]])
147 // CHECK-NEXT: entry:
148 // CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[AGG_RESULT]], ptr align 8 [[C1]], i64 48, i1 false)
149 // CHECK-NEXT: ret void
150 C foo3() {
151   return c1;
152 }
153 
154 // CHECK: define dso_local void @{{.*foo4.*}}
155 // CHECK-NEXT: entry:
156 // CHECK-NEXT: [[C2:%.*]] = alloca [[STRUCT_C:%.*]], align 8
157 // CHECK-NEXT: [[REF_TMP:%.*]] = alloca [[STRUCT_B:%.*]], align 8
158 // CHECK-NEXT: [[REF_TMP_1:%.*]] = alloca [[STRUCT_A:%.*]], align 8
159 // CHECK-NEXT: [[A:%.*]] = getelementptr inbounds nuw [[STRUCT_B]], ptr [[REF_TMP]], i32 0, i32 0
160 // CHECK-NEXT: [[I:%.*]] = getelementptr inbounds nuw [[STRUCT_A]], ptr [[A]], i32 0, i32 0
161 // CHECK-NEXT: store i8 1, ptr [[I]], align 8
162 // CHECK-NEXT: [[J:%.*]] = getelementptr inbounds nuw [[STRUCT_A]], ptr [[A]], i32 0, i32 1
163 // CHECK-NEXT: store double 1.000000e+00, ptr [[J]], align 8
164 // CHECK-NEXT: [[B:%.*]] = getelementptr inbounds nuw [[STRUCT_B]], ptr [[REF_TMP]], i32 0, i32 1
165 // CHECK-NEXT: store i32 1, ptr [[B]], align 8
166 // CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[C2]], ptr align 8 [[REF_TMP]], i64 24, i1 false)
167 // CHECK-NEXT: [[TMP_0:%.*]] = getelementptr inbounds i8, ptr [[C2]], i64 24
168 // CHECK-NEXT: [[I2:%.*]] = getelementptr inbounds nuw [[STRUCT_A]], ptr [[REF_TMP_1]], i32 0, i32 0
169 // CHECK-NEXT: store i8 97, ptr [[I2]], align 8
170 // CHECK-NEXT: [[J3:%.*]] = getelementptr inbounds nuw [[STRUCT_A]], ptr [[REF_TMP_1]], i32 0, i32 1
171 // CHECK-NEXT: store double 0.000000e+00, ptr [[J3]], align 8
172 // CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[TMP_0]], ptr align 8 [[REF_TMP_1]], i64 16, i1 false)
173 // CHECK-NEXT: [[C:%.*]] = getelementptr inbounds nuw %struct.C, ptr %c2, i32 0, i32 2
174 // CHECK-NEXT: store i32 2, ptr %c, align 8
175 // CHECK-NEXT: ret void
176 void foo4() {
177   C c2(B(A(1, 1), 1), A('a'), 2);
178 }
179 
180 // CHECK: define dso_local { i64, double } @{{.*foo5.*}}
181 // CHECK-NEXT: entry:
182 // CHECK-NEXT [[RETVAL:%.*]] = alloca [[UNION_U]], align 8
183 // CHECK-NEXT call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[RETVAL]], ptr align 8 [[U1]], i64 16, i1 false)
184 // CHECK-NEXT [[COERCE_DIVE:%.*]] = getelementptr inbounds nuw [[UNION_U]], ptr %retval, i32 0, i32 0
185 // CHECK-NEXT [[TMP_0:%.*]] = load { i64, double }, ptr [[COERCE_DIVE]], align 8
186 // CHECK-NEXT ret { i64, double } [[TMP_0]]
187 U foo5() {
188   return u1;
189 }
190 
191 
192 // CHECK: define dso_local { i64, double } @{{.*foo6.*}}(i8 [[A_COERCE_0:%.*]], double [[A_COERCE_1:%.*]])
193 // CHECK-NEXT: entry:
194 // CHECK-NEXT:   [[RETVAL:%.*]] = alloca [[UNION_U]], align 8
195 // CHECK-NEXT:   [[A:%.*]] = alloca [[STRUCT_A]], align 8
196 // CHECK-NEXT:   [[TMP_0:%.*]] = getelementptr inbounds nuw { i8, double }, ptr [[A]], i32 0, i32 0
197 // CHECK-NEXT:   store i8 [[A_COERCE_0]], ptr [[TMP_0]], align 8
198 // CHECK-NEXT:   [[TMP_1:%.*]] = getelementptr inbounds nuw { i8, double }, ptr [[A]], i32 0, i32 1
199 // CHECK-NEXT:   store double [[A_COERCE_1]], ptr [[TMP_1]], align 8
200 // CHECK-NEXT:   call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[RETVAL]], ptr align 8 [[A]], i64 16, i1 false)
201 // CHECK-NEXT:   [[COERCE_DIVE:%.*]] = getelementptr inbounds nuw [[UNION_U]], ptr [[RETVAL]], i32 0, i32 0
202 // CHECK-NEXT:   [[TMP_2:%.*]] = load { i64, double }, ptr [[COERCE_DIVE:%.*]], align 8
203 // CHECK-NEXT:   ret { i64, double } [[TMP_2]]
204 U foo6(A a) {
205   return U(a);
206 }
207 
208 // CHECK: define dso_local void @{{.*foo7.*}}
209 // CHECK-NEXT: entry:
210 // CHECK-NEXT: [[D:%.*]] = alloca [[STRUCT_D:%.*]], align 8
211 // CHECK-NEXT: [[A:%.*]] = getelementptr inbounds nuw [[STRUCT_D]], ptr [[D]], i32 0, i32 0
212 // CHECK-NEXT: [[I]] = getelementptr inbounds nuw [[STRUCT_A:%.*]], ptr [[A]], i32 0, i32 0
213 // CHECK-NEXT: store i8 1, ptr [[I]], align 8
214 // CHECK-NEXT: [[J:%.*]] = getelementptr inbounds nuw [[STRUCT_A]], ptr [[A]], i32 0, i32 1
215 // CHECK-NEXT: store double 1.000000e+00, ptr [[J]], align 8
216 // CHECK-NEXT: [[B:%.*]] = getelementptr inbounds nuw [[STRUCT_D]], ptr [[D]], i32 0, i32 1
217 // CHECK-NEXT: [[I1:%.*]] = getelementptr inbounds nuw [[STRUCT_A]], ptr [[B]], i32 0, i32 0
218 // CHECK-NEXT: store i8 11, ptr [[I1]], align 8
219 // CHECK-NEXT: [[J2:%.*]] = getelementptr inbounds nuw [[STRUCT_A]], ptr [[B]], i32 0, i32 1
220 // CHECK-NEXT: store double 1.100000e+01, ptr [[J2]], align 8
221 // CHECK-NEXT: [[C:%.*]] = getelementptr inbounds nuw [[STRUCT_D]], ptr [[D]], i32 0, i32 3
222 // CHECK-NEXT: [[I3:%.*]] = getelementptr inbounds nuw [[STRUCT_A]], ptr [[C]], i32 0, i32 0
223 // CHECK-NEXT: store i8 111, ptr [[I3]], align 8
224 // CHECK-NEXT: [[J4:%.*]] = getelementptr inbounds nuw [[STRUCT_A]], ptr [[C]], i32 0, i32 1
225 // CHECK-NEXT: store double 1.110000e+02, ptr [[J4]], align 8
226 // CHECK-NEXT: ret void
227 void foo7() {
228   D d(A(1, 1), A(11, 11), A(111, 111));
229 }
230 
231 // CHECK: dso_local void @{{.*foo8.*}}(ptr dead_on_unwind noalias writable sret([[STRUCT_D]]) align 8 [[AGG_RESULT:%.*]])
232 // CHECK-NEXT: entry:
233 // CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[AGG_RESULT]], ptr align 8 [[D1]], i64 56, i1 false)
234 // CHECK-NEXT: ret void
235 D foo8() {
236   return d1;
237 }
238 
239 // CHECK: define dso_local void @{{.*foo9.*}}
240 // CHECK-NEXT: entry:
241 // CHECK-NEXT: [[D:%.*]] = alloca [[STRUCT_D:%.*]], align 8
242 // CHECK-NEXT: [[A:%.*]] = getelementptr inbounds nuw [[STRUCT_D]], ptr [[D]], i32 0, i32 0
243 // CHECK-NEXT: [[I]] = getelementptr inbounds nuw [[STRUCT_A:%.*]], ptr [[A]], i32 0, i32 0
244 // CHECK-NEXT: store i8 1, ptr [[I]], align 8
245 // CHECK-NEXT: [[J:%.*]] = getelementptr inbounds nuw [[STRUCT_A]], ptr [[A]], i32 0, i32 1
246 // CHECK-NEXT: store double 1.000000e+00, ptr [[J]], align 8
247 // CHECK-NEXT: [[B:%.*]] = getelementptr inbounds nuw [[STRUCT_D]], ptr [[D]], i32 0, i32 1
248 // CHECK-NEXT: [[I1:%.*]] = getelementptr inbounds nuw [[STRUCT_A]], ptr [[B]], i32 0, i32 0
249 // CHECK-NEXT: store i8 2, ptr [[I1]], align 8
250 // CHECK-NEXT: [[J2:%.*]] = getelementptr inbounds nuw [[STRUCT_A]], ptr [[B]], i32 0, i32 1
251 // CHECK-NEXT: store double 2.000000e+00, ptr [[J2]], align 8
252 // CHECK-NEXT: [[C:%.*]] = getelementptr inbounds nuw [[STRUCT_D]], ptr [[D]], i32 0, i32 3
253 // CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 8 [[C]], i8 0, i64 16, i1 false)
254 // CHECK-NEXT: ret void
255 void foo9() {
256   D d(A(1, 1));
257 }
258 
259 // CHECK: define dso_local noundef ptr @{{.*foo10.*}}()
260 // CHECK-NEXT: entry:
261 // CHECK-NEXT: ret ptr [[ARR1]]
262 const int* foo10() {
263   return arr1;
264 }
265 
266 // CHECK: define dso_local void @{{.*foo11.*}}
267 // CHECK-NEXT: entry:
268 // CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
269 // CHECK-NEXT: [[B_ADDR:%.*]] = alloca i32, align 4
270 // CHECK-NEXT: [[ARR_2:%.*]] = alloca [4 x i32], align 16
271 // CHECK-NEXT: store i32 [[A:%.*]], ptr [[A_ADDR]], align 4
272 // CHECK-NEXT: store i32 [[B:%.*]], ptr [[B_ADDR]], align 4
273 // CHECK-NEXT: [[TMP_0:%.*]] = load i32, ptr [[A_ADDR]], align 4
274 // CHECK-NEXT: store i32 [[TMP_0]], ptr [[ARR_2]], align 4
275 // CHECK-NEXT: [[ARRINIT_ELEM:%.*]] = getelementptr inbounds i32, ptr [[ARR_2]], i64 1
276 // CHECK-NEXT: [[TMP_1:%.*]] = load i32, ptr [[B_ADDR]], align 4
277 // CHECK-NEXT: store i32 [[TMP_1]], ptr [[ARRINIT_ELEM]], align 4
278 // CHECK-NEXT: [[ARRINIT_START:%.*]] = getelementptr inbounds i32, ptr [[ARR_2]], i64 2
279 // CHECK-NEXT: [[ARRINIT_END:%.*]] = getelementptr inbounds i32, ptr [[ARR_2]], i64 4
280 // CHECK-NEXT: br label [[ARRINIT_BODY:%.*]]
281 // CHECK: [[ARRINIT_CUR:%.*]] = phi ptr [ [[ARRINIT_START]], %entry ], [ [[ARRINIT_NEXT:%.*]], [[ARRINIT_BODY]] ]
282 // CHECK-NEXT: store i32 0, ptr [[ARRINIT_CUR]], align 4
283 // CHECK-NEXT: [[ARRINIT_NEXT]] = getelementptr inbounds i32, ptr [[ARRINIT_CUR]], i64 1
284 // CHECK-NEXT: [[ARRINIT_DONE:%.*]] = icmp eq ptr [[ARRINIT_NEXT]], [[ARRINIT_END:%.*]]
285 // CHECK-NEXT: br i1 [[ARRINIT_DONE]], label [[ARRINIT_END1:%.*]], label [[ARRINIT_BODY]]
286 // CHECK: ret void
287 void foo11(int a, int b) {
288   int arr2[4](a, b);
289 }
290 
291 // CHECK: define dso_local void @{{.*foo12.*}}
292 // CHECK-NEXT: entry:
293 // CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
294 // CHECK-NEXT: [[B_ADDR:%.*]] = alloca i32, align 4
295 // CHECK-NEXT: [[ARR_3:%.*]] = alloca [2 x i32], align 4
296 // CHECK-NEXT: store i32 [[A:%.*]], ptr [[A_ADDR]], align 4
297 // CHECK-NEXT: store i32 [[B:%.*]], ptr [[B_ADDR]], align 4
298 // CHECK-NEXT: [[TMP_0:%.*]] = load i32, ptr [[A_ADDR]], align 4
299 // CHECK-NEXT: store i32 [[TMP_0]], ptr [[ARR_3]], align 4
300 // CHECK-NEXT: [[ARRINIT_ELEMENT:%.*]] = getelementptr inbounds i32, ptr [[ARR_3]], i64 1
301 // CHECK-NEXT: [[TMP_1:%.*]] = load i32, ptr [[B_ADDR]], align 4
302 // CHECK-NEXT: store i32 [[TMP_1]], ptr [[ARRINIT_ELEMENT]], align 4
303 // CHECK-NEXT: ret void
304 void foo12(int a, int b) {
305   int arr3[](a, b);
306 }
307 
308 // CHECK: define dso_local { i8, double } @{{.*foo13.*}}
309 // CHECK-NEXT: entry:
310 // CHECK-NEXT: [[RETVAL:%.*]] = alloca [[STRUCT_A]], align 8
311 // CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[RETVAL]], ptr align 8 [[A2]], i64 16, i1 false)
312 // CHECK-NEXT: [[TMP_0:%.*]] = load { i8, double }, ptr [[RETVAL]], align 8
313 // CHECK-NEXT: ret { i8, double } [[TMP_0]]
314 A foo13() {
315   return a2;
316 }
317 
318 // CHECK: define dso_local noundef ptr @{{.*foo14.*}}()
319 // CHECK-NEXT: entry:
320 // CHECK-NEXT: ret ptr [[ARR4]]
321 const int* foo14() {
322   return arr4;
323 }
324 
325 // CHECK: define dso_local noundef ptr @{{.*foo15.*}}()
326 // CHECK-NEXT: entry:
327 // CHECK-NEXT: ret ptr [[ARR5]]
328 const int* foo15() {
329   return arr5;
330 }
331 
332 // CHECK: define dso_local void @{{.*foo16.*}}
333 // CHECK-NEXT: entry:
334 // CHECK-NEXT: [[ARR_6:%.*arr6.*]] = alloca ptr, align 8
335 // CHECK-NEXT: [[REF_TMP:%.*]] = alloca [1 x i32], align 4
336 // CHECK-NEXT: store i32 3, ptr [[REF_TMP]], align 4
337 // CHECK-NEXT: store ptr [[REF_TMP]], ptr [[ARR_6]], align 8
338 // CHECK-NEXT: ret void
339 void foo16() {
340   int (&&arr6)[] = static_cast<int[]>(3);
341 }
342 
343 // CHECK: define dso_local void @{{.*foo17.*}}
344 // CHECK-NEXT: entry:
345 // CHECK-NEXT: [[ARR_7:%.*arr7.*]] = alloca ptr, align 8
346 // CHECK-NEXT: [[REF_TMP:%.*]] = alloca [2 x i32], align 4
347 // CHECK-NEXT: store i32 4, ptr [[REF_TMP]], align 4
348 // CHECK-NEXT: [[ARRINIT_START:%.*]] = getelementptr inbounds i32, ptr [[REF_TMP]], i64 1
349 // CHECK-NEXT: [[ARRINIT_END:%.*]] = getelementptr inbounds i32, ptr [[REF_TMP]], i64 2
350 // CHECK-NEXT: br label [[ARRINIT_BODY]]
351 // CHECK: [[ARRINIT_CUR:%.*]] = phi ptr [ [[ARRINIT_START]], %entry ], [ [[ARRINIT_NEXT:%.*]], [[ARRINIT_BODY]] ]
352 // CHECK-NEXT: store i32 0, ptr [[ARRINIT_CUR]], align 4
353 // CHECK-NEXT: [[ARRINIT_NEXT]] = getelementptr inbounds i32, ptr [[ARRINIT_CUR]], i64 1
354 // CHECK-NEXT: [[ARRINIT_DONE:%.*]] = icmp eq ptr [[ARRINIT_NEXT]], [[ARRINIT_END:%.*]]
355 // CHECK-NEXT: br i1 [[ARRINIT_DONE]], label [[ARRINIT_END1:%.*]], label [[ARRINIT_BODY]]
356 // CHECK: store ptr [[REF_TMP]], ptr [[ARR_7]], align 8
357 // CHECK: ret void
358 void foo17() {
359   int (&&arr7)[2] = static_cast<int[2]>(4);
360 }
361 
362 // CHECK: define dso_local void @{{.*foo18.*}}
363 // CHECK-NEXT: entry:
364 // CHECK-NEXT: [[E:%.*e.*]] = alloca [[STRUCT_E]], align 8
365 // CHECK-NEXT: [[A:%.*a.*]] = getelementptr inbounds nuw [[STRUCT_E]], ptr [[E]], i32 0, i32 0
366 // CHECK-NEXT: store i32 1, ptr [[A]], align 8
367 // CHECK-NEXT: [[FN:%.*fn.*]] = getelementptr inbounds nuw [[STRUCT_E]], ptr [[E]], i32 0, i32 1
368 // CHECK-NEXT: store ptr [[STR]], ptr [[FN]], align 8
369 // CHECK: ret void
370 void foo18() {
371   E e(1);
372 }
373 
374 // CHECK: define dso_local void @{{.*foo19.*}}
375 // CHECK-NEXT: entry:
376 // CHECK-NEXT: [[G:%.*g.*]] = alloca [[STRUCT_G]], align 4
377 // CHECK-NEXT: [[A:%.*a.*]] = getelementptr inbounds nuw [[STRUCT_G]], ptr [[G]], i32 0, i32 0
378 // CHECK-NEXT: store i32 2, ptr [[A]], align 4
379 // CHECK-NEXT: [[F:%.*]] = getelementptr inbounds i8, ptr [[G]], i64 4
380 // CHECk-NEXT: call void @{{.*F.*}}(ptr noundef nonnull align 1 dereferenceable(1)) [[F]], ie32 noundef 1)
381 // CHECK: ret void
382 void foo19() {
383   G g(2);
384 }
385 
386 namespace gh61145 {
387   // a.k.a. void make1<0>()
388   // CHECK: define {{.*}} void @_ZN7gh611455make1ILi0EEEvv
389   // CHECK-NEXT: entry:
390   // CHECK-NEXT: [[V:%.*v.*]] = alloca [[STRUCT_VEC]], align 1
391   // CHECK-NEXT: [[AGG_TMP_ENSURED:%.*agg.tmp.ensured.*]] = alloca [[STRUCT_S1]], align 1
392   // a.k.a. Vec::Vec()
393   // CHECK-NEXT: call void @_ZN7gh611453VecC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[V]])
394   // a.k.a. Vec::Vec(Vec&&)
395   // CHECK-NEXT: call void @_ZN7gh611453VecC1EOS0_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_TMP_ENSURED]], ptr noundef nonnull align 1 dereferenceable(1) [[V]])
396   // a.k.a. S1::~S1()
397   // CHECK-NEXT: call void @_ZN7gh611452S1D1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_TMP_ENSURED]])
398   // a.k.a.Vec::~Vec()
399   // CHECK-NEXT: call void @_ZN7gh611453VecD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[V]])
400   // CHECK-NEXT: ret void
401   template <int I>
402   void make1() {
403     Vec v;
404     S1((Vec&&) v);
405   }
406 
407   // a.k.a. void make1<0>()
408   // CHECK: define {{.*}} void @_ZN7gh611455make2ILi0EEEvv
409   // CHECK-NEXT: entry:
410   // CHECK-NEXT: [[V:%.*v.*]] = alloca [[STRUCT_VEC]], align 1
411   // CHECK-NEXT: [[AGG_TMP_ENSURED:%.*agg.tmp.ensured.*]] = alloca [[STRUCT_S2]], align 1
412   // a.k.a. Vec::Vec()
413   // CHECK-NEXT: call void @_ZN7gh611453VecC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[V]])
414   // a.k.a. Vec::Vec(Vec&&)
415   // CHECK-NEXT: call void @_ZN7gh611453VecC1EOS0_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_TMP_ENSURED]], ptr noundef nonnull align 1 dereferenceable(1) [[V]])
416   // CHECK-NEXT: [[C:%.*c.*]] = getelementptr inbounds nuw [[STRUCT_S2]], ptr [[AGG_TMP_ENSURED]], i32 0, i32
417   // CHECK-NEXT: store i8 0, ptr [[C]], align 1
418   // a.k.a. S2::~S2()
419   // CHECK-NEXT: call void @_ZN7gh611452S2D1Ev(ptr noundef nonnull align 1 dereferenceable(2) [[AGG_TMP_ENSURED]])
420   // a.k.a. Vec::~Vec()
421   // CHECK-NEXT: call void @_ZN7gh611453VecD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[V]])
422   // CHECK-NEXT: ret void
423   template <int I>
424   void make2() {
425     Vec v;
426     S2((Vec&&) v, 0);
427   }
428 
429   void foo() {
430     make1<0>();
431     make2<0>();
432   }
433 }
434 
435 namespace gh62266 {
436   // CHECK: define {{.*}} void {{.*foo20.*}}
437   // CHECK-NEXT: entry:
438   // CHECK-NEXT: [[H:%.*h.*]] = alloca [[STRUCT_H]], align 4
439   // CHECK-NEXT: [[I:%.*i.*]] = getelementptr inbounds nuw [[STRUCT_H]], ptr [[H]], i32 0, i32 0
440   // CHECK-NEXT: store i32 1, ptr [[I]], align 4
441   // CHECK-NEXT: [[J:%.*j.*]] = getelementptr inbounds nuw [[STRUCT_H]], ptr [[H]], i32 0, i32 1
442   // CHECK-NEXT: store i32 2, ptr [[J]], align 4
443   // CHECK-NEXT: ret void
444   void foo20() {
445     H<2> h(1);
446   }
447 }
448 
449 namespace gh61567 {
450   int foo20();
451 
452   // CHECK: define {{.*}} void @{{.*foo21.*}} {
453   // CHECK-NEXT: entry
454   // CHECK-NEXT: [[AGG_TMP_ENSURED:%.*]] = alloca [[STRUCT_I]], align 8
455   // CHECK-NEXT: [[REF_TMP:%.*]] = alloca i32, align 4
456   // CHECK-NEXT: [[A:%.*a.*]] = getelementptr inbounds nuw [[STRUCT_I]], ptr [[AGG_TMP_ENSURED]], i32 0, i32 0
457   // CHECK-NEXT: store i32 0, ptr [[A]], align 8
458   // CHECK-NEXT: [[R:%.*r.*]] = getelementptr inbounds nuw [[STRUCT_I]], ptr [[AGG_TMP_ENSURED]], i32 0, i32 1
459   // CHECK-NEXT: store i32 1, ptr [[REF_TMP]], align 4
460   // CHECK-NEXT: store ptr [[REF_TMP]], ptr [[R]], align 8
461   // CHECK-NEXT: ret void
462   void foo21() {
463     I(0, 1);
464   }
465 
466   // CHECK: define {{.*}} void @{{.*foo22.*}} {
467   // CHECK-NEXT: entry
468   // CHECK-NEXT: [[AGG_TMP_ENSURED:%.*]] = alloca [[STRUCT_I]], align 8
469   // CHECK-NEXT: [[REF_TMP:%.*]] = alloca i32, align 4
470   // CHECK-NEXT: [[A:%.*a.*]] = getelementptr inbounds nuw [[STRUCT_I]], ptr [[AGG_TMP_ENSURED]], i32 0, i32 0
471   // CHECK-NEXT: store i32 0, ptr [[A]], align 8
472   // CHECK-NEXT: [[R:%.*r.*]] = getelementptr inbounds nuw [[STRUCT_I]], ptr [[AGG_TMP_ENSURED]], i32 0, i32 1
473   // CHECK-NEXT: [[CALL:%.*call*]] = call noundef i32 @{{.*foo20.*}}
474   // CHECK-NEXT: store i32 [[CALL]], ptr [[REF_TMP]], align 4
475   // CHECK-NEXT: store ptr [[REF_TMP]], ptr [[R]], align 8
476   // CHECK-NEXT: ret void
477   void foo22() {
478     I(0, foo20());
479   }
480 
481   // CHECK: define {{.*}} void @{{.*foo23.*}}(i32 noundef [[I:%.*i.*]])
482   // CHECK-NEXT: entry
483   // CHECK-NEXT: [[I_ADDR:%.*i.*]] = alloca i32, align 4
484   // CHECK-NEXT: [[AGG_TMP_ENSURED:%.*]] = alloca [[STRUCT_I]], align 8
485   // CHECK-NEXT: store i32 [[I]], ptr [[I_ADDR]], align 4
486   // CHECK-NEXT: [[A:%.*a.*]] = getelementptr inbounds nuw [[STRUCT_I]], ptr [[AGG_TMP_ENSURED]], i32 0, i32 0
487   // CHECK-NEXT: store i32 0, ptr [[A]], align 8
488   // CHECK-NEXT: [[R:%.*r.*]] = getelementptr inbounds nuw [[STRUCT_I]], ptr [[AGG_TMP_ENSURED]], i32 0, i32 1
489   // CHECK-NEXT: store ptr [[I_ADDR]], ptr [[R]], align 8
490   // CHECK-NEXT: ret void
491   void foo23(int i) {
492     I(0, static_cast<int&&>(i));
493   }
494 
495   // CHECK: define {{.*}} void @{{.*foo24.*}} {
496   // CHECK-NEXT: entry
497   // CHECK-NEXT: [[AGG_TMP_ENSURED:%.*]] = alloca [[STRUCT_I]], align 8
498   // CHECK-NEXT: [[REF_TMP:%.*]] = alloca i32, align 4
499   // CHECK-NEXT: [[A:%.*a.*]] = getelementptr inbounds nuw [[STRUCT_I]], ptr [[AGG_TMP_ENSURED]], i32 0, i32 0
500   // CHECK-NEXT: store i32 0, ptr [[A]], align 8
501   // CHECK-NEXT: [[R:%.*r.*]] = getelementptr inbounds nuw [[STRUCT_I]], ptr [[AGG_TMP_ENSURED]], i32 0, i32 1
502   // CHECK-NEXT: store i32 2, ptr [[REF_TMP]], align 4
503   // CHECK-NEXT: store ptr [[REF_TMP]], ptr [[R]], align 8
504   // CHECK-NEXT: ret void
505   void foo24() {
506     I(0);
507   }
508 }
509 
510 namespace gh68198 {
511   // CHECK: define {{.*}} void @{{.*foo25.*}} {
512   // CHECK-NEXT: entry
513   // CHECK-NEXT: [[ARR_8:%.*arr8.*]] = alloca ptr, align 8
514   // CHECK-NEXT: [[CALL_PTR:%.*]] = call noalias noundef nonnull ptr @_Znam(i64 noundef 8)
515   // CHECK-NEXT: store i32 1, ptr [[CALL_PTR]], align 4
516   // CHECK-NEXT: [[ARRAY_EXP_NEXT:%.*]] = getelementptr inbounds i32, ptr [[CALL_PTR]], i64 1
517   // CHECK-NEXT: store i32 2, ptr [[ARRAY_EXP_NEXT]], align 4
518   // CHECK-NEXT: [[ARRAY_EXP_NEXT1:%.*]] = getelementptr inbounds i32, ptr [[ARRAY_EXP_NEXT]], i64 1
519   // CHECK-NEXT: store ptr [[CALL_PTR]], ptr %arr8, align 8
520   // CHECK-NEXT: ret void
521   void foo25() {
522     int* arr8 = new int[](1, 2);
523   }
524 
525   // CHECK: define {{.*}} void @{{.*foo26.*}} {
526   // CHECK-NEXT: entry
527   // CHECK-NEXT: [[ARR_10:%.*arr9.*]] = alloca ptr, align 8
528   // CHECK-NEXT: [[CALL_PTR]] = call noalias noundef nonnull ptr @_Znam(i64 noundef 16)
529   // CHECK-NEXT: store i32 1, ptr [[CALL]], align 4
530   // CHECK-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds i32, ptr [[CALL]], i64 1
531   // CHECK-NEXT: store i32 2, ptr [[ARRAYINIT_ELEMENT]], align 4
532   // CHECK-NEXT: [[ARRAY_EXP_NEXT:%.*]] = getelementptr inbounds [2 x i32], ptr %call, i64 1
533   // CHECK-NEXT: store i32 3, ptr [[ARRAY_EXP_NEXT]], align 4
534   // CHECK-NEXT: [[ARRAYINIT_ELEMENT2:%.*]] = getelementptr inbounds i32, ptr [[ARRAY_EXP_NEXT]], i64 1
535   // CHECK-NEXT: store i32 4, ptr [[ARRAYINIT_ELEMENT2]], align 4
536   // CHECK-NEXT: [[ARRAY_EXP_NEXT3:%.*]] = getelementptr inbounds [2 x i32], ptr [[ARRAY_EXP_NEXT]], i64 1
537   // CHECK-NEXT: store ptr [[CALL_PTR]], ptr [[ARR_10]], align 8
538   // CHECK-NEXT: ret void
539   void foo26() {
540     void* arr9 = new int[][2]({1, 2}, {3, 4});
541   }
542 
543   // CHECK: define {{.*}} void @{{.*foo27.*}} {
544   // CHECK-NEXT: entry
545   // CHECK-NEXT: [[ARR_10:%.*arr10.*]] = alloca ptr, align 8
546   // CHECK-NEXT: [[CALL_PTR]] = call noalias noundef nonnull ptr @_Znam(i64 noundef 32)
547   // CHECK-NEXT: store i32 5, ptr [[CALL]], align 4
548   // CHECK-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds i32, ptr [[CALL]], i64 1
549   // CHECK-NEXT: store i32 6, ptr [[ARRAYINIT_ELEMENT]], align 4
550   // CHECK-NEXT: [[ARRAY_EXP_NEXT:%.*]] = getelementptr inbounds [2 x i32], ptr %call, i64 1
551   // CHECK-NEXT: store i32 7, ptr [[ARRAY_EXP_NEXT]], align 4
552   // CHECK-NEXT: [[ARRAYINIT_ELEMENT2:%.*]] = getelementptr inbounds i32, ptr [[ARRAY_EXP_NEXT]], i64 1
553   // CHECK-NEXT: store i32 8, ptr [[ARRAYINIT_ELEMENT2]], align 4
554   // CHECK-NEXT: [[ARRAY_EXP_NEXT3:%.*]] = getelementptr inbounds [2 x i32], ptr [[ARRAY_EXP_NEXT]], i64 1
555   // CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 4 [[ARRAY_EXP_NEXT3]], i8 0, i64 16, i1 false)
556   // CHECK-NEXT: store ptr [[CALL_PTR]], ptr [[ARR_10]], align 8
557   // CHECK-NEXT: ret void
558   void foo27() {
559     void* arr10 = new int[4][2]({5, 6}, {7, 8});
560   }
561 }
562