diff options
Diffstat (limited to 'clang/test/CodeGenCXX/constructor-init.cpp')
-rw-r--r-- | clang/test/CodeGenCXX/constructor-init.cpp | 222 |
1 files changed, 222 insertions, 0 deletions
diff --git a/clang/test/CodeGenCXX/constructor-init.cpp b/clang/test/CodeGenCXX/constructor-init.cpp new file mode 100644 index 0000000..9f808f6 --- /dev/null +++ b/clang/test/CodeGenCXX/constructor-init.cpp @@ -0,0 +1,222 @@ +// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 %s -emit-llvm -o %t +// RUN: FileCheck %s < %t +// RUN: FileCheck -check-prefix=CHECK-PR10720 %s < %t + +extern "C" int printf(...); + +struct M { + M() { printf("M()\n"); } + M(int i) { iM = i; printf("M(%d)\n", i); } + int iM; + void MPR() {printf("iM = %d\n", iM); }; +}; + +struct P { + P() { printf("P()\n"); } + P(int i) { iP = i; printf("P(%d)\n", i); } + int iP; + void PPR() {printf("iP = %d\n", iP); }; +}; + +struct Q { + Q() { printf("Q()\n"); } + Q(int i) { iQ = i; printf("Q(%d)\n", i); } + int iQ; + void QPR() {printf("iQ = %d\n", iQ); }; +}; + +struct N : M , P, Q { + N() : f1(1.314), P(2000), ld(00.1234+f1), M(1000), Q(3000), + d1(3.4567), i1(1234), m1(100) { printf("N()\n"); } + M m1; + M m2; + float f1; + int i1; + float d1; + void PR() { + printf("f1 = %f d1 = %f i1 = %d ld = %f \n", f1,d1,i1, ld); + MPR(); + PPR(); + QPR(); + printf("iQ = %d\n", iQ); + printf("iP = %d\n", iP); + printf("iM = %d\n", iM); + // FIXME. We don't yet support this syntax. + // printf("iQ = %d\n", (*this).iQ); + printf("iQ = %d\n", this->iQ); + printf("iP = %d\n", this->iP); + printf("iM = %d\n", this->iM); + } + float ld; + float ff; + M arr_m[3]; + P arr_p[1][3]; + Q arr_q[2][3][4]; +}; + +int main() { + M m1; + + N n1; + n1.PR(); +} + +// PR5826 +template <class T> struct A { + A() {} + A(int) {} + A(const A&) {} + ~A() {} + operator int() {return 0;} +}; + +// CHECK: define void @_Z1fv() +void f() { + // CHECK: call void @_ZN1AIsEC1Ei + A<short> a4 = 97; + + // CHECK-NEXT: store i32 17 + int i = 17; + + // CHECK-NEXT: call void @_ZN1AIsED1Ev + // CHECK-NOT: call void @_ZN1AIsED1Ev + // CHECK: ret void +} + +// Make sure we initialize the vtable pointer if it's required by a +// base initializer. +namespace InitVTable { + struct A { A(int); }; + struct B : A { + virtual int foo(); + B(); + B(int); + }; + + // CHECK: define void @_ZN10InitVTable1BC2Ev(%"struct.InitVTable::B"* %this) unnamed_addr + // CHECK: [[T0:%.*]] = bitcast [[B:%.*]]* [[THIS:%.*]] to i8*** + // CHECK-NEXT: store i8** getelementptr inbounds ([3 x i8*]* @_ZTVN10InitVTable1BE, i64 0, i64 2), i8*** [[T0]] + // CHECK: [[VTBL:%.*]] = load i32 ([[B]]*)*** {{%.*}} + // CHECK-NEXT: [[FNP:%.*]] = getelementptr inbounds i32 ([[B]]*)** [[VTBL]], i64 0 + // CHECK-NEXT: [[FN:%.*]] = load i32 ([[B]]*)** [[FNP]] + // CHECK-NEXT: [[ARG:%.*]] = call i32 [[FN]]([[B]]* [[THIS]]) + // CHECK-NEXT: call void @_ZN10InitVTable1AC2Ei({{.*}}* {{%.*}}, i32 [[ARG]]) + // CHECK-NEXT: [[T0:%.*]] = bitcast [[B]]* [[THIS]] to i8*** + // CHECK-NEXT: store i8** getelementptr inbounds ([3 x i8*]* @_ZTVN10InitVTable1BE, i64 0, i64 2), i8*** [[T0]] + // CHECK-NEXT: ret void + B::B() : A(foo()) {} + + // CHECK: define void @_ZN10InitVTable1BC2Ei(%"struct.InitVTable::B"* %this, i32 %x) unnamed_addr + // CHECK: [[ARG:%.*]] = add nsw i32 {{%.*}}, 5 + // CHECK-NEXT: call void @_ZN10InitVTable1AC2Ei({{.*}}* {{%.*}}, i32 [[ARG]]) + // CHECK-NEXT: [[T0:%.*]] = bitcast [[B]]* {{%.*}} to i8*** + // CHECK-NEXT: store i8** getelementptr inbounds ([3 x i8*]* @_ZTVN10InitVTable1BE, i64 0, i64 2), i8*** [[T0]] + // CHECK-NEXT: ret void + B::B(int x) : A(x + 5) {} +} + +namespace rdar9694300 { + struct X { + int x; + }; + + // CHECK: define void @_ZN11rdar96943001fEv + void f() { + // CHECK: alloca + X x; + // CHECK-NEXT: [[I:%.*]] = alloca i32 + // CHECK-NEXT: store i32 17, i32* [[I]] + int i = 17; + // CHECK-NEXT: ret void + } +} + +template<typename T> +struct X { + X(const X &); + + T *start; + T *end; +}; + +template<typename T> struct X; + +// Make sure that the instantiated constructor initializes start and +// end properly. +// CHECK: define linkonce_odr void @_ZN1XIiEC2ERKS0_(%struct.X* %this, %struct.X* %other) unnamed_addr +// CHECK: {{store.*null}} +// CHECK: {{store.*null}} +// CHECK: ret +template<typename T> +X<T>::X(const X &other) : start(0), end(0) { } + +X<int> get_X(X<int> x) { return x; } + +namespace PR10720 { + struct X { + X(const X&); + X(X&&); + X& operator=(const X&); + X& operator=(X&&); + ~X(); + }; + + struct pair2 { + X second[4]; + + // CHECK-PR10720: define linkonce_odr {{.*}} @_ZN7PR107205pair2aSERKS0_ + // CHECK-PR10720: load + // CHECK-PR10720: icmp ne + // CHECK-PR10720-NEXT: br i1 + // CHECK-PR10720: call {{.*}} @_ZN7PR107201XaSERKS0_ + // CHECK-PR10720: ret + pair2 &operator=(const pair2&) = default; + + // CHECK-PR10720: define linkonce_odr {{.*}} @_ZN7PR107205pair2aSEOS0_ + // CHECK-PR10720: load + // CHECK-PR10720: icmp ne + // CHECK-PR10720-NEXT: br i1 + // CHECK-PR10720: call {{.*}} @_ZN7PR107201XaSEOS0_ + // CHECK-PR10720: ret + pair2 &operator=(pair2&&) = default; + + // CHECK-PR10720: define linkonce_odr void @_ZN7PR107205pair2C2EOS0_ + // CHECK-PR10720-NOT: ret + // CHECK-PR10720: load + // CHECK-PR10720: icmp ult + // CHECK-PR10720-NEXT: br i1 + // CHECK-PR10720: call void @_ZN7PR107201XC1EOS0_ + // CHECK-PR10720-NEXT: br label + // CHECK-PR10720: ret void + pair2(pair2&&) = default; + + // CHECK-PR10720: define linkonce_odr void @_ZN7PR107205pair2C2ERKS0_ + // CHECK-PR10720-NOT: ret + // CHECK-PR10720: load + // CHECK-PR10720: icmp ult + // CHECK-PR10720-NEXT: br i1 + // CHECK-PR10720: call void @_ZN7PR107201XC1ERKS0_ + // CHECK-PR10720-NEXT: br label + // CHECK-PR10720: ret void + pair2(const pair2&) = default; + }; + + struct pair : X { // Make the copy constructor non-trivial, so we actually generate it. + int second[4]; + // CHECK-PR10720: define linkonce_odr void @_ZN7PR107204pairC2ERKS0_ + // CHECK-PR10720-NOT: ret + // CHECK-PR10720: call void @llvm.memcpy + // CHECK-PR10720-NEXT: ret void + pair(const pair&) = default; + }; + + void foo(const pair &x, const pair2 &x2) { + pair y(x); + pair2 y2(x2); + pair2 y2m(static_cast<pair2&&>(y2)); + + y2 = x2; + y2m = static_cast<pair2&&>(y2); + } + +} |