1 // RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++11 %s -emit-llvm -o - | FileCheck %s
2 
3 // PR10878
4 
5 struct S { S(); S(int); ~S(); int n; };
6 
7 void *p = new S[2][3]{ { 1, 2, 3 }, { 4, 5, 6 } };
8 
9 // CHECK-LABEL: define
10 // CHECK: %[[ALLOC:.*]] = call noalias i8* @_Znam(i64 32)
11 // CHECK: %[[COOKIE:.*]] = bitcast i8* %[[ALLOC]] to i64*
12 // CHECK: store i64 6, i64* %[[COOKIE]]
13 // CHECK: %[[START_AS_i8:.*]] = getelementptr inbounds i8* %[[ALLOC]], i64 8
14 // CHECK: %[[START_AS_S:.*]] = bitcast i8* %[[START_AS_i8]] to %[[S:.*]]*
15 //
16 // Explicit initializers:
17 //
18 // { 1, 2, 3 }
19 //
20 // CHECK: %[[S_0:.*]] = bitcast %[[S]]* %[[START_AS_S]] to [3 x %[[S]]]*
21 //
22 // CHECK: %[[S_0_0:.*]] = getelementptr inbounds [3 x %[[S]]]* %[[S_0]], i64 0, i64 0
23 // CHECK: call void @_ZN1SC1Ei(%[[S]]* %[[S_0_0]], i32 1)
24 // CHECK: %[[S_0_1:.*]] = getelementptr inbounds %[[S]]* %[[S_0_0]], i64 1
25 // CHECK: call void @_ZN1SC1Ei(%[[S]]* %[[S_0_1]], i32 2)
26 // CHECK: %[[S_0_2:.*]] = getelementptr inbounds %[[S]]* %[[S_0_1]], i64 1
27 // CHECK: call void @_ZN1SC1Ei(%[[S]]* %[[S_0_2]], i32 3)
28 //
29 // { 4, 5, 6 }
30 //
31 // CHECK: %[[S_1:.*]] = getelementptr [3 x %[[S]]]* %[[S_0]], i32 1
32 //
33 // CHECK: %[[S_1_0:.*]] = getelementptr inbounds [3 x %[[S]]]* %[[S_1]], i64 0, i64 0
34 // CHECK: call void @_ZN1SC1Ei(%[[S]]* %[[S_1_0]], i32 4)
35 // CHECK: %[[S_1_1:.*]] = getelementptr inbounds %[[S]]* %[[S_1_0]], i64 1
36 // CHECK: call void @_ZN1SC1Ei(%[[S]]* %[[S_1_1]], i32 5)
37 // CHECK: %[[S_1_2:.*]] = getelementptr inbounds %[[S]]* %[[S_1_1]], i64 1
38 // CHECK: call void @_ZN1SC1Ei(%[[S]]* %[[S_1_2]], i32 6)
39 //
40 // CHECK-NOT: br i1
41 // CHECK-NOT: call
42 // CHECK: }
43 
44 int n;
45 void *q = new S[n][3]{ { 1, 2, 3 }, { 4, 5, 6 } };
46 
47 // CHECK-LABEL: define
48 //
49 // CHECK: load i32* @n
50 // CHECK: call {{.*}} @llvm.umul.with.overflow.i64(i64 %[[N:.*]], i64 12)
51 // CHECK: %[[ELTS:.*]] = mul i64 %[[N]], 3
52 // CHECK: call {{.*}} @llvm.uadd.with.overflow.i64(i64 %{{.*}}, i64 8)
53 // CHECK: %[[ALLOC:.*]] = call noalias i8* @_Znam(i64 %{{.*}})
54 //
55 // CHECK: %[[COOKIE:.*]] = bitcast i8* %[[ALLOC]] to i64*
56 // CHECK: store i64 %[[ELTS]], i64* %[[COOKIE]]
57 // CHECK: %[[START_AS_i8:.*]] = getelementptr inbounds i8* %[[ALLOC]], i64 8
58 // CHECK: %[[START_AS_S:.*]] = bitcast i8* %[[START_AS_i8]] to %[[S]]*
59 // CHECK: %[[END_AS_S:.*]] = getelementptr inbounds %[[S]]* %[[START_AS_S]], i64 %[[ELTS]]
60 //
61 // Explicit initializers:
62 //
63 // { 1, 2, 3 }
64 //
65 // CHECK: %[[S_0:.*]] = bitcast %[[S]]* %[[START_AS_S]] to [3 x %[[S]]]*
66 //
67 // CHECK: %[[S_0_0:.*]] = getelementptr inbounds [3 x %[[S]]]* %[[S_0]], i64 0, i64 0
68 // CHECK: call void @_ZN1SC1Ei(%[[S]]* %[[S_0_0]], i32 1)
69 // CHECK: %[[S_0_1:.*]] = getelementptr inbounds %[[S]]* %[[S_0_0]], i64 1
70 // CHECK: call void @_ZN1SC1Ei(%[[S]]* %[[S_0_1]], i32 2)
71 // CHECK: %[[S_0_2:.*]] = getelementptr inbounds %[[S]]* %[[S_0_1]], i64 1
72 // CHECK: call void @_ZN1SC1Ei(%[[S]]* %[[S_0_2]], i32 3)
73 //
74 // { 4, 5, 6 }
75 //
76 // CHECK: %[[S_1:.*]] = getelementptr [3 x %[[S]]]* %[[S_0]], i32 1
77 //
78 // CHECK: %[[S_1_0:.*]] = getelementptr inbounds [3 x %[[S]]]* %[[S_1]], i64 0, i64 0
79 // CHECK: call void @_ZN1SC1Ei(%[[S]]* %[[S_1_0]], i32 4)
80 // CHECK: %[[S_1_1:.*]] = getelementptr inbounds %[[S]]* %[[S_1_0]], i64 1
81 // CHECK: call void @_ZN1SC1Ei(%[[S]]* %[[S_1_1]], i32 5)
82 // CHECK: %[[S_1_2:.*]] = getelementptr inbounds %[[S]]* %[[S_1_1]], i64 1
83 // CHECK: call void @_ZN1SC1Ei(%[[S]]* %[[S_1_2]], i32 6)
84 //
85 // CHECK: %[[S_2:.*]] = getelementptr [3 x %[[S]]]* %[[S_1]], i32 1
86 // CHECK: %[[S_2_AS_S:.*]] = bitcast [3 x %[[S]]]* %[[S_2]] to %[[S]]*
87 // CHECK: icmp eq %[[S]]* %[[S_2_AS_S]], %[[END_AS_S]]
88 // CHECK: br i1
89 //
90 // S[n-2][3] initialization loop:
91 //
92 // CHECK: %[[END_INNER:.*]] = getelementptr inbounds %[[S]]* %{{.*}}, i64 3
93 // CHECK: br label
94 //
95 //   S[3] initialization loop:
96 //
97 //   CHECK: call void @_ZN1SC1Ev(%[[S]]*
98 //   CHECK: %[[NEXT_INNER:.*]] = getelementptr inbounds %[[S]]* %{{.*}}, i64 1
99 //   CHECK: icmp eq %[[S]]* %[[NEXT_INNER]], %[[END_INNER]]
100 //   CHECK: br i1
101 //
102 // CHECK: %[[NEXT_OUTER:.*]] = getelementptr [3 x %[[S]]]* %{{.*}}, i32 1
103 // CHECK: %[[NEXT_OUTER_AS_S:.*]] = bitcast [3 x %[[S]]]* %[[NEXT_OUTER]] to %[[S]]*
104 // CHECK: icmp eq %[[S]]* %[[NEXT_OUTER_AS_S]], %[[END_AS_S]]
105 // CHECK: br i1
106 //
107 // CHECK: }
108