value-init.cpp revision 2ed7cb649aa709b875c519f4a980a1e2b5712370
1// RUN: %clang_cc1 %s -triple x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s 2 3struct A { 4 virtual ~A(); 5}; 6 7struct B : A { }; 8 9struct C { 10 int i; 11 B b; 12}; 13 14// CHECK: _Z15test_value_initv 15void test_value_init() { 16 // This value initialization requires zero initialization of the 'B' 17 // subobject followed by a call to its constructor. 18 // PR5800 19 20 // CHECK: store i32 17 21 // CHECK: call void @llvm.memset.p0i8.i64 22 // CHECK: call void @_ZN1BC1Ev 23 C c = { 17 } ; 24 // CHECK: call void @_ZN1CD1Ev 25} 26 27enum enum_type { negative_number = -1, magic_number = 42 }; 28 29class enum_holder 30{ 31 enum_type m_enum; 32 33public: 34 enum_holder() : m_enum(magic_number) { } 35}; 36 37struct enum_holder_and_int 38{ 39 enum_holder e; 40 int i; 41}; 42 43// CHECK: _Z24test_enum_holder_and_intv() 44void test_enum_holder_and_int() { 45 // CHECK: alloca 46 // CHECK-NEXT: bitcast 47 // CHECK-NEXT: call void @llvm.memset 48 // CHECK-NEXT: call void @_ZN19enum_holder_and_intC1Ev 49 enum_holder_and_int(); 50 // CHECK-NEXT: ret void 51} 52 53// PR7834: don't crash. 54namespace test1 { 55 struct A { 56 int A::*f; 57 A(); 58 A(const A&); 59 A &operator=(const A &); 60 }; 61 62 struct B { 63 A base; 64 }; 65 66 void foo() { 67 B(); 68 } 69} 70 71namespace ptrmem { 72 struct S { 73 int mem1; 74 int S::*mem2; 75 }; 76 77 // CHECK: define i32 @_ZN6ptrmem4testEPNS_1SE 78 int test(S *s) { 79 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64 80 // CHECK: getelementptr 81 // CHECK: ret 82 return s->*S().mem2; 83 } 84} 85 86namespace PR9801 { 87 88struct Test { 89 Test() : i(10) {} 90 Test(int i) : i(i) {} 91 int i; 92private: 93 int j; 94}; 95 96struct Test2 { 97 Test t; 98}; 99 100struct Test3 : public Test { }; 101 102// CHECK: define void @_ZN6PR98011fEv 103void f() { 104 // CHECK-NOT: call void @llvm.memset.p0i8.i64 105 // CHECK: call void @_ZN6PR98014TestC1Ei 106 // CHECK-NOT: call void @llvm.memset.p0i8.i64 107 // CHECK: call void @_ZN6PR98014TestC1Ev 108 Test partial[3] = { 1 }; 109 110 // CHECK-NOT: call void @llvm.memset.p0i8.i64 111 // CHECK: call void @_ZN6PR98014TestC1Ev 112 // CHECK-NOT: call void @_ZN6PR98014TestC1Ev 113 Test empty[3] = {}; 114 115 // CHECK: call void @llvm.memset.p0i8.i64 116 // CHECK-NOT: call void @llvm.memset.p0i8.i64 117 // CHECK: call void @_ZN6PR98015Test2C1Ev 118 // CHECK-NOT: call void @_ZN6PR98015Test2C1Ev 119 Test2 empty2[3] = {}; 120 121 // CHECK: call void @llvm.memset.p0i8.i64 122 // CHECK-NOT: call void @llvm.memset.p0i8.i64 123 // CHECK: call void @_ZN6PR98015Test3C1Ev 124 // CHECK-NOT: call void @llvm.memset.p0i8.i64 125 // CHECK-NOT: call void @_ZN6PR98015Test3C1Ev 126 Test3 empty3[3] = {}; 127} 128 129} 130 131namespace zeroinit { 132 struct S { int i; }; 133 134 // CHECK: define i32 @_ZN8zeroinit4testEv() 135 int test() { 136 // CHECK: call void @llvm.memset.p0i8.i64 137 // CHECK: getelementptr 138 // CHECK: ret i32 139 return S().i; 140 } 141 142 struct X0 { 143 X0() { } 144 int x; 145 }; 146 147 struct X1 : X0 { 148 int x1; 149 void f(); 150 }; 151 152 // CHECK: define void @_ZN8zeroinit9testX0_X1Ev 153 void testX0_X1() { 154 // CHECK: call void @llvm.memset.p0i8.i64 155 // CHECK-NEXT: call void @_ZN8zeroinit2X1C1Ev 156 // CHECK-NEXT: call void @_ZN8zeroinit2X11fEv 157 X1().f(); 158 } 159 160 template<typename> 161 struct X2 : X0 { 162 int x2; 163 void f(); 164 }; 165 166 template<typename> 167 struct X3 : X2<int> { 168 X3() : X2<int>() { } 169 int i; 170 }; 171 172 173 // CHECK: define void @_ZN8zeroinit9testX0_X3Ev 174 void testX0_X3() { 175 // CHECK-NOT: call void @llvm.memset 176 // CHECK: call void @_ZN8zeroinit2X3IiEC1Ev 177 // CHECK: call void @_ZN8zeroinit2X2IiE1fEv 178 // CHECK-NEXT: ret void 179 X3<int>().f(); 180 } 181 182 // More checks at EOF 183} 184 185namespace PR8726 { 186class C; 187struct S { 188 const C &c1; 189 int i; 190 const C &c2; 191}; 192void f(const C& c) { 193 S s = {c, 42, c}; 194} 195 196} 197 198// rdar://problem/9355931 199namespace test6 { 200 struct A { A(); A(int); }; 201 202 void test() { 203 A arr[10][20] = { 5 }; 204 }; 205 // CHECK: define void @_ZN5test64testEv() 206 // CHECK: [[ARR:%.*]] = alloca [10 x [20 x [[A:%.*]]]], 207 208 // CHECK-NEXT: [[INNER:%.*]] = getelementptr inbounds [10 x [20 x [[A]]]]* [[ARR]], i64 0, i64 0 209 // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [20 x [[A]]]* [[INNER]], i64 0, i64 0 210 // CHECK-NEXT: call void @_ZN5test61AC1Ei([[A]]* [[T0]], i32 5) 211 // CHECK-NEXT: [[BEGIN:%.*]] = getelementptr inbounds [[A]]* [[T0]], i64 1 212 // CHECK-NEXT: [[END:%.*]] = getelementptr inbounds [[A]]* [[T0]], i64 20 213 // CHECK-NEXT: br label 214 // CHECK: [[CUR:%.*]] = phi [[A]]* [ [[BEGIN]], {{%.*}} ], [ [[NEXT:%.*]], {{%.*}} ] 215 // CHECK-NEXT: call void @_ZN5test61AC1Ev([[A]]* [[CUR]]) 216 // CHECK-NEXT: [[NEXT]] = getelementptr inbounds [[A]]* [[CUR]], i64 1 217 // CHECK-NEXT: [[T0:%.*]] = icmp eq [[A]]* [[NEXT]], [[END]] 218 // CHECK-NEXT: br i1 219 220 // CHECK: [[BEGIN:%.*]] = getelementptr inbounds [20 x [[A]]]* [[INNER]], i64 1 221 // CHECK-NEXT: [[END:%.*]] = getelementptr inbounds [20 x [[A]]]* [[INNER]], i64 10 222 // CHECK-NEXT: br label 223 // CHECK: [[CUR:%.*]] = phi [20 x [[A]]]* [ [[BEGIN]], {{%.*}} ], [ [[NEXT:%.*]], {{%.*}} ] 224 225 // Inner loop. 226 // CHECK-NEXT: [[IBEGIN:%.*]] = getelementptr inbounds [20 x [[A]]]* [[CUR]], i32 0, i32 0 227 // CHECK-NEXT: [[IEND:%.*]] = getelementptr inbounds [[A]]* [[IBEGIN]], i64 20 228 // CHECK-NEXT: br label 229 // CHECK: [[ICUR:%.*]] = phi [[A]]* [ [[IBEGIN]], {{%.*}} ], [ [[INEXT:%.*]], {{%.*}} ] 230 // CHECK-NEXT: call void @_ZN5test61AC1Ev([[A]]* [[ICUR]]) 231 // CHECK-NEXT: [[INEXT:%.*]] = getelementptr inbounds [[A]]* [[ICUR]], i64 1 232 // CHECK-NEXT: [[T0:%.*]] = icmp eq [[A]]* [[INEXT]], [[IEND]] 233 // CHECK-NEXT: br i1 [[T0]], 234 235 // CHECK: [[NEXT]] = getelementptr inbounds [20 x [[A]]]* [[CUR]], i64 1 236 // CHECK-NEXT: [[T0:%.*]] = icmp eq [20 x [[A]]]* [[NEXT]], [[END]] 237 // CHECK-NEXT: br i1 [[T0]] 238 // CHECK: ret void 239} 240 241namespace PR11124 { 242 // Make sure C::C doesn't overwrite parts of A while it is zero-initializing B 243 struct A { int a; A(); A(int); }; 244 struct B : virtual A { int b; }; 245 struct C : B { C(); }; 246 C::C() : A(3), B() {} 247 // CHECK: define void @_ZN7PR111241CC1Ev 248 // CHECK: call void @llvm.memset.p0i8.i64(i8* {{.*}}, i8 0, i64 12, i32 8, i1 false) 249 // CHECK-NEXT: call void @_ZN7PR111241BC2Ev 250 // Make sure C::C doesn't overwrite parts of A while it is zero-initializing B 251 252 struct B2 : virtual A { int B::*b; }; 253 struct C2 : B2 { C2(); }; 254 C2::C2() : A(3), B2() {} 255 // CHECK: define void @_ZN7PR111242C2C1Ev 256 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %{{.*}}, i8* {{.*}}, i64 16, i32 8, i1 false) 257 // CHECK-NEXT: call void @_ZN7PR111242B2C2Ev 258} 259 260// CHECK: define linkonce_odr void @_ZN8zeroinit2X3IiEC2Ev(%"struct.zeroinit::X3"* %this) unnamed_addr 261// CHECK: call void @llvm.memset.p0i8.i64 262// CHECK-NEXT: call void @_ZN8zeroinit2X2IiEC2Ev 263// CHECK-NEXT: ret void 264