1 | // RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm -o - %s | FileCheck %s |
2 | |
3 | extern "C" int printf(...); |
4 | |
5 | int init = 100; |
6 | |
7 | struct M { |
8 | int iM; |
9 | M() : iM(init++) {} |
10 | }; |
11 | |
12 | struct N { |
13 | int iN; |
14 | N() : iN(200) {} |
15 | N(N const & arg){this->iN = arg.iN; } |
16 | }; |
17 | |
18 | struct P { |
19 | int iP; |
20 | P() : iP(init++) {} |
21 | }; |
22 | |
23 | |
24 | // CHECK-LABEL: define linkonce_odr void @_ZN1XC1ERKS_(%struct.X* %this, %struct.X* dereferenceable({{[0-9]+}})) unnamed_addr |
25 | struct X : M, N, P { // ... |
26 | X() : f1(1.0), d1(2.0), i1(3), name("HELLO"), bf1(0xff), bf2(0xabcd), |
27 | au_i1(1234), au1_4("MASKED") {} |
28 | P p0; |
29 | void pr() { |
30 | printf("iM = %d iN = %d, m1.iM = %d\n", iM, iN, m1.iM); |
31 | printf("im = %d p0.iP = %d, p1.iP = %d\n", iP, p0.iP, p1.iP); |
32 | printf("f1 = %f d1 = %f i1 = %d name(%s) \n", f1, d1, i1, name); |
33 | printf("bf1 = %x bf2 = %x\n", bf1, bf2); |
34 | printf("au_i2 = %d\n", au_i2); |
35 | printf("au1_1 = %s\n", au1_1); |
36 | } |
37 | M m1; |
38 | P p1; |
39 | float f1; |
40 | double d1; |
41 | int i1; |
42 | const char *name; |
43 | unsigned bf1 : 8; |
44 | unsigned bf2 : 16; |
45 | int arr[2]; |
46 | _Complex float complex; |
47 | |
48 | union { |
49 | int au_i1; |
50 | int au_i2; |
51 | }; |
52 | union { |
53 | const char * au1_1; |
54 | float au1_2; |
55 | int au1_3; |
56 | const char * au1_4; |
57 | }; |
58 | }; |
59 | |
60 | static int ix = 1; |
61 | // class with user-defined copy constructor. |
62 | struct S { |
63 | S() : iS(ix++) { } |
64 | S(const S& arg) { *this = arg; } |
65 | int iS; |
66 | }; |
67 | |
68 | // class with trivial copy constructor. |
69 | struct I { |
70 | I() : iI(ix++) { } |
71 | int iI; |
72 | }; |
73 | |
74 | struct XM { |
75 | XM() { } |
76 | double dXM; |
77 | S ARR_S[3][4][2]; |
78 | void pr() { |
79 | for (unsigned i = 0; i < 3; i++) |
80 | for (unsigned j = 0; j < 4; j++) |
81 | for (unsigned k = 0; k < 2; k++) |
82 | printf("ARR_S[%d][%d][%d] = %d\n", i,j,k, ARR_S[i][j][k].iS); |
83 | for (unsigned i = 0; i < 3; i++) |
84 | for (unsigned k = 0; k < 2; k++) |
85 | printf("ARR_I[%d][%d] = %d\n", i,k, ARR_I[i][k].iI); |
86 | } |
87 | I ARR_I[3][2]; |
88 | }; |
89 | |
90 | int main() { |
91 | X a; |
92 | X b(a); |
93 | b.pr(); |
94 | X x; |
95 | X c(x); |
96 | c.pr(); |
97 | |
98 | XM m0; |
99 | XM m1 = m0; |
100 | m1.pr(); |
101 | } |
102 | |
103 | struct A { |
104 | }; |
105 | |
106 | struct B : A { |
107 | A &a; |
108 | }; |
109 | |
110 | void f(const B &b1) { |
111 | B b2(b1); |
112 | } |
113 | |
114 | // PR6628 |
115 | namespace PR6628 { |
116 | |
117 | struct T { |
118 | T(); |
119 | ~T(); |
120 | |
121 | double d; |
122 | }; |
123 | |
124 | struct A { |
125 | A(const A &other, const T &t = T(), const T& t2 = T()); |
126 | }; |
127 | |
128 | struct B : A { |
129 | A a1; |
130 | A a2; |
131 | A a[10]; |
132 | }; |
133 | |
134 | // Force the copy constructor to be synthesized. |
135 | void f(B b1) { |
136 | B b2 = b1; |
137 | } |
138 | |
139 | // CHECK: define linkonce_odr dereferenceable({{[0-9]+}}) [[A:%.*]]* @_ZN12rdar138169401AaSERKS0_( |
140 | // CHECK: [[THIS:%.*]] = load [[A]]*, [[A]]** |
141 | // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[A]], [[A]]* [[THIS]], i32 0, i32 1 |
142 | // CHECK-NEXT: [[OTHER:%.*]] = load [[A]]*, [[A]]** |
143 | // CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds [[A]], [[A]]* [[OTHER]], i32 0, i32 1 |
144 | // CHECK-NEXT: [[T4:%.*]] = bitcast i16* [[T0]] to i8* |
145 | // CHECK-NEXT: [[T5:%.*]] = bitcast i16* [[T2]] to i8* |
146 | // CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 [[T4]], i8* align 8 [[T5]], i64 8, i1 false) |
147 | // CHECK-NEXT: ret [[A]]* [[THIS]] |
148 | |
149 | // CHECK-LABEL: define linkonce_odr void @_ZN6PR66281BC2ERKS0_(%"struct.PR6628::B"* %this, %"struct.PR6628::B"* dereferenceable({{[0-9]+}})) unnamed_addr |
150 | // CHECK: call void @_ZN6PR66281TC1Ev |
151 | // CHECK: call void @_ZN6PR66281TC1Ev |
152 | // CHECK: call void @_ZN6PR66281AC2ERKS0_RKNS_1TES5_ |
153 | // CHECK: call void @_ZN6PR66281TD1Ev |
154 | // CHECK: call void @_ZN6PR66281TD1Ev |
155 | // CHECK: call void @_ZN6PR66281TC1Ev |
156 | // CHECK: call void @_ZN6PR66281TC1Ev |
157 | // CHECK: call void @_ZN6PR66281AC1ERKS0_RKNS_1TES5_ |
158 | // CHECK: call void @_ZN6PR66281TD1Ev |
159 | // CHECK: call void @_ZN6PR66281TD1Ev |
160 | // CHECK: call void @_ZN6PR66281TC1Ev |
161 | // CHECK: call void @_ZN6PR66281TC1Ev |
162 | // CHECK: call void @_ZN6PR66281AC1ERKS0_RKNS_1TES5_ |
163 | // CHECK: call void @_ZN6PR66281TD1Ev |
164 | // CHECK: call void @_ZN6PR66281TD1Ev |
165 | |
166 | // CHECK-LABEL: define linkonce_odr void @_ZN12rdar138169401AC2ERKS0_( |
167 | // CHECK: [[THIS:%.*]] = load [[A]]*, [[A]]** |
168 | // CHECK-NEXT: [[T0:%.*]] = bitcast [[A]]* [[THIS]] to i32 (...)*** |
169 | // CHECK-NEXT: store i32 (...)** bitcast (i8** getelementptr inbounds ({ [4 x i8*] }, { [4 x i8*] }* @_ZTVN12rdar138169401AE, i32 0, inrange i32 0, i32 2) to i32 (...)**), i32 (...)*** [[T0]] |
170 | // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[A]], [[A]]* [[THIS]], i32 0, i32 1 |
171 | // CHECK-NEXT: [[OTHER:%.*]] = load [[A]]*, [[A]]** |
172 | // CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds [[A]], [[A]]* [[OTHER]], i32 0, i32 1 |
173 | // CHECK-NEXT: [[T4:%.*]] = bitcast i16* [[T0]] to i8* |
174 | // CHECK-NEXT: [[T5:%.*]] = bitcast i16* [[T2]] to i8* |
175 | // CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 [[T4]], i8* align 8 [[T5]], i64 8, i1 false) |
176 | // CHECK-NEXT: ret void |
177 | } |
178 | |
179 | // rdar://13816940 |
180 | // Test above because things get weirdly re-ordered. |
181 | namespace rdar13816940 { |
182 | struct A { |
183 | virtual ~A(); |
184 | unsigned short a : 1; |
185 | unsigned short : 15; |
186 | unsigned other; |
187 | }; |
188 | |
189 | void test(A &a) { |
190 | A x = a; // force copy constructor into existence |
191 | x = a; // also force the copy assignment operator |
192 | } |
193 | } |
194 | |