1 | // RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 %s -emit-llvm -o %t |
2 | // RUN: FileCheck %s < %t |
3 | // RUN: FileCheck -check-prefix=CHECK-PR10720 %s < %t |
4 | |
5 | extern "C" int printf(...); |
6 | |
7 | struct M { |
8 | M() { printf("M()\n"); } |
9 | M(int i) { iM = i; printf("M(%d)\n", i); } |
10 | int iM; |
11 | void MPR() {printf("iM = %d\n", iM); }; |
12 | }; |
13 | |
14 | struct P { |
15 | P() { printf("P()\n"); } |
16 | P(int i) { iP = i; printf("P(%d)\n", i); } |
17 | int iP; |
18 | void PPR() {printf("iP = %d\n", iP); }; |
19 | }; |
20 | |
21 | struct Q { |
22 | Q() { printf("Q()\n"); } |
23 | Q(int i) { iQ = i; printf("Q(%d)\n", i); } |
24 | int iQ; |
25 | void QPR() {printf("iQ = %d\n", iQ); }; |
26 | }; |
27 | |
28 | struct N : M , P, Q { |
29 | N() : f1(1.314), P(2000), ld(00.1234+f1), M(1000), Q(3000), |
30 | d1(3.4567), i1(1234), m1(100) { printf("N()\n"); } |
31 | M m1; |
32 | M m2; |
33 | float f1; |
34 | int i1; |
35 | float d1; |
36 | void PR() { |
37 | printf("f1 = %f d1 = %f i1 = %d ld = %f \n", f1,d1,i1, ld); |
38 | MPR(); |
39 | PPR(); |
40 | QPR(); |
41 | printf("iQ = %d\n", iQ); |
42 | printf("iP = %d\n", iP); |
43 | printf("iM = %d\n", iM); |
44 | // FIXME. We don't yet support this syntax. |
45 | // printf("iQ = %d\n", (*this).iQ); |
46 | printf("iQ = %d\n", this->iQ); |
47 | printf("iP = %d\n", this->iP); |
48 | printf("iM = %d\n", this->iM); |
49 | } |
50 | float ld; |
51 | float ff; |
52 | M arr_m[3]; |
53 | P arr_p[1][3]; |
54 | Q arr_q[2][3][4]; |
55 | }; |
56 | |
57 | int main() { |
58 | M m1; |
59 | |
60 | N n1; |
61 | n1.PR(); |
62 | } |
63 | |
64 | // PR5826 |
65 | template <class T> struct A { |
66 | A() {} |
67 | A(int) {} |
68 | A(const A&) {} |
69 | ~A() {} |
70 | operator int() {return 0;} |
71 | }; |
72 | |
73 | // CHECK-LABEL: define void @_Z1fv() |
74 | void f() { |
75 | // CHECK: call void @_ZN1AIsEC1Ei |
76 | A<short> a4 = 97; |
77 | |
78 | // CHECK-NEXT: store i32 17 |
79 | int i = 17; |
80 | |
81 | // CHECK-NEXT: call void @_ZN1AIsED1Ev |
82 | // CHECK-NOT: call void @_ZN1AIsED1Ev |
83 | // CHECK: ret void |
84 | } |
85 | |
86 | // Make sure we initialize the vtable pointer if it's required by a |
87 | // base initializer. |
88 | namespace InitVTable { |
89 | struct A { A(int); }; |
90 | struct B : A { |
91 | virtual int foo(); |
92 | B(); |
93 | B(int); |
94 | }; |
95 | |
96 | // CHECK-LABEL: define void @_ZN10InitVTable1BC2Ev(%"struct.InitVTable::B"* %this) unnamed_addr |
97 | // CHECK: [[T0:%.*]] = bitcast [[B:%.*]]* [[THIS:%.*]] to i32 (...)*** |
98 | // CHECK-NEXT: store i32 (...)** bitcast (i8** getelementptr inbounds ({ [3 x i8*] }, { [3 x i8*] }* @_ZTVN10InitVTable1BE, i32 0, inrange i32 0, i32 2) to i32 (...)**), i32 (...)*** [[T0]] |
99 | // CHECK: [[VTBL:%.*]] = load i32 ([[B]]*)**, i32 ([[B]]*)*** {{%.*}} |
100 | // CHECK-NEXT: [[FNP:%.*]] = getelementptr inbounds i32 ([[B]]*)*, i32 ([[B]]*)** [[VTBL]], i64 0 |
101 | // CHECK-NEXT: [[FN:%.*]] = load i32 ([[B]]*)*, i32 ([[B]]*)** [[FNP]] |
102 | // CHECK-NEXT: [[ARG:%.*]] = call i32 [[FN]]([[B]]* [[THIS]]) |
103 | // CHECK-NEXT: call void @_ZN10InitVTable1AC2Ei({{.*}}* {{%.*}}, i32 [[ARG]]) |
104 | // CHECK-NEXT: [[T0:%.*]] = bitcast [[B]]* [[THIS]] to i32 (...)*** |
105 | // CHECK-NEXT: store i32 (...)** bitcast (i8** getelementptr inbounds ({ [3 x i8*] }, { [3 x i8*] }* @_ZTVN10InitVTable1BE, i32 0, inrange i32 0, i32 2) to i32 (...)**), i32 (...)*** [[T0]] |
106 | // CHECK-NEXT: ret void |
107 | B::B() : A(foo()) {} |
108 | |
109 | // CHECK-LABEL: define void @_ZN10InitVTable1BC2Ei(%"struct.InitVTable::B"* %this, i32 %x) unnamed_addr |
110 | // CHECK: [[ARG:%.*]] = add nsw i32 {{%.*}}, 5 |
111 | // CHECK-NEXT: call void @_ZN10InitVTable1AC2Ei({{.*}}* {{%.*}}, i32 [[ARG]]) |
112 | // CHECK-NEXT: [[T0:%.*]] = bitcast [[B]]* {{%.*}} to i32 (...)*** |
113 | // CHECK-NEXT: store i32 (...)** bitcast (i8** getelementptr inbounds ({ [3 x i8*] }, { [3 x i8*] }* @_ZTVN10InitVTable1BE, i32 0, inrange i32 0, i32 2) to i32 (...)**), i32 (...)*** [[T0]] |
114 | // CHECK-NEXT: ret void |
115 | B::B(int x) : A(x + 5) {} |
116 | } |
117 | |
118 | namespace rdar9694300 { |
119 | struct X { |
120 | int x; |
121 | }; |
122 | |
123 | // CHECK-LABEL: define void @_ZN11rdar96943001fEv |
124 | void f() { |
125 | // CHECK: alloca |
126 | X x; |
127 | // CHECK-NEXT: [[I:%.*]] = alloca i32 |
128 | // CHECK-NEXT: store i32 17, i32* [[I]] |
129 | int i = 17; |
130 | // CHECK-NEXT: ret void |
131 | } |
132 | } |
133 | |
134 | // Check that we emit a zero initialization step for list-value-initialization |
135 | // which calls a trivial default constructor. |
136 | namespace PR13273 { |
137 | struct U { |
138 | int t; |
139 | U() = default; |
140 | }; |
141 | |
142 | struct S : U { |
143 | S() = default; |
144 | }; |
145 | |
146 | // CHECK: define {{.*}}@_ZN7PR132731fEv( |
147 | int f() { |
148 | // CHECK-NOT: } |
149 | // CHECK: llvm.memset{{.*}}i8 0 |
150 | return (new S{})->t; |
151 | } |
152 | } |
153 | |
154 | template<typename T> |
155 | struct X { |
156 | X(const X &); |
157 | |
158 | T *start; |
159 | T *end; |
160 | }; |
161 | |
162 | template<typename T> struct X; |
163 | |
164 | // Make sure that the instantiated constructor initializes start and |
165 | // end properly. |
166 | // CHECK-LABEL: define linkonce_odr void @_ZN1XIiEC2ERKS0_(%struct.X* %this, %struct.X* dereferenceable({{[0-9]+}}) %other) unnamed_addr |
167 | // CHECK: {{store.*null}} |
168 | // CHECK: {{store.*null}} |
169 | // CHECK: ret |
170 | template<typename T> |
171 | X<T>::X(const X &other) : start(0), end(0) { } |
172 | |
173 | X<int> get_X(X<int> x) { return x; } |
174 | |
175 | namespace PR10720 { |
176 | struct X { |
177 | X(const X&); |
178 | X(X&&); |
179 | X& operator=(const X&); |
180 | X& operator=(X&&); |
181 | ~X(); |
182 | }; |
183 | |
184 | struct pair2 { |
185 | X second[4]; |
186 | |
187 | // CHECK-PR10720: define linkonce_odr {{.*}} @_ZN7PR107205pair2aSERKS0_ |
188 | // CHECK-PR10720: load |
189 | // CHECK-PR10720: icmp ne |
190 | // CHECK-PR10720-NEXT: br i1 |
191 | // CHECK-PR10720: call {{.*}} @_ZN7PR107201XaSERKS0_ |
192 | // CHECK-PR10720: ret |
193 | pair2 &operator=(const pair2&) = default; |
194 | |
195 | // CHECK-PR10720: define linkonce_odr {{.*}} @_ZN7PR107205pair2aSEOS0_ |
196 | // CHECK-PR10720: load |
197 | // CHECK-PR10720: icmp ne |
198 | // CHECK-PR10720-NEXT: br i1 |
199 | // CHECK-PR10720: call {{.*}} @_ZN7PR107201XaSEOS0_ |
200 | // CHECK-PR10720: ret |
201 | pair2 &operator=(pair2&&) = default; |
202 | |
203 | // CHECK-PR10720-LABEL: define linkonce_odr void @_ZN7PR107204pairC2ERKS0_ |
204 | // CHECK-PR10720-NOT: ret |
205 | // CHECK-PR10720: call void @llvm.memcpy |
206 | // CHECK-PR10720-NEXT: ret void |
207 | |
208 | // CHECK-PR10720-LABEL: define linkonce_odr void @_ZN7PR107205pair2C2ERKS0_ |
209 | // CHECK-PR10720-NOT: ret |
210 | // CHECK-PR10720: call void @_ZN7PR107201XC1ERKS0_ |
211 | // CHECK-PR10720: icmp eq |
212 | // CHECK-PR10720-NEXT: br i1 |
213 | // CHECK-PR10720: ret void |
214 | |
215 | // CHECK-PR10720-LABEL: define linkonce_odr void @_ZN7PR107205pair2C2EOS0_ |
216 | // CHECK-PR10720-NOT: ret |
217 | // CHECK-PR10720: load |
218 | // CHECK-PR10720: call void @_ZN7PR107201XC1EOS0_ |
219 | // CHECK-PR10720: icmp eq |
220 | // CHECK-PR10720-NEXT: br i1 |
221 | // CHECK-PR10720: ret void |
222 | pair2(pair2&&) = default; |
223 | |
224 | pair2(const pair2&) = default; |
225 | }; |
226 | |
227 | struct pair : X { // Make the copy constructor non-trivial, so we actually generate it. |
228 | int second[4]; |
229 | pair(const pair&) = default; |
230 | }; |
231 | |
232 | void foo(const pair &x, const pair2 &x2) { |
233 | pair y(x); |
234 | pair2 y2(x2); |
235 | pair2 y2m(static_cast<pair2&&>(y2)); |
236 | |
237 | y2 = x2; |
238 | y2m = static_cast<pair2&&>(y2); |
239 | } |
240 | |
241 | } |
242 | |