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