1// RUN: %clang_cc1 %s -fno-rtti -triple=i386-pc-win32 -emit-llvm -o %t 2// RUN: FileCheck %s < %t 3// RUN: FileCheck --check-prefix=CHECK2 %s < %t 4 5// For now, just make sure x86_64 doesn't crash. 6// RUN: %clang_cc1 %s -fno-rtti -triple=x86_64-pc-win32 -emit-llvm -o %t 7 8struct VBase { 9 virtual ~VBase(); 10 virtual void foo(); 11 virtual void bar(); 12 int field; 13}; 14 15struct B : virtual VBase { 16 B(); 17 virtual ~B(); 18 virtual void foo(); 19 virtual void bar(); 20}; 21 22B::B() { 23 // CHECK-LABEL: define x86_thiscallcc %struct.B* @"\01??0B@@QAE@XZ" 24 // CHECK: %[[THIS:.*]] = load %struct.B** 25 // CHECK: br i1 %{{.*}}, label %[[INIT_VBASES:.*]], label %[[SKIP_VBASES:.*]] 26 27 // Don't check the INIT_VBASES case as it's covered by the ctor tests. 28 29 // CHECK: %[[SKIP_VBASES]] 30 // CHECK: %[[THIS_i8:.*]] = bitcast %struct.B* %[[THIS]] to i8* 31 // CHECK: %[[VBPTR:.*]] = getelementptr inbounds i8* %[[THIS_i8]], i32 0 32 // ... 33 // CHECK: %[[THIS_i8:.*]] = bitcast %struct.B* %[[THIS]] to i8* 34 // CHECK: %[[VFPTR_i8:.*]] = getelementptr inbounds i8* %[[THIS_i8]], i32 %{{.*}} 35 // CHECK: %[[VFPTR:.*]] = bitcast i8* %[[VFPTR_i8]] to [3 x i8*]** 36 // CHECK: store [3 x i8*]* @"\01??_7B@@6B@", [3 x i8*]** %[[VFPTR]] 37 38 // Initialize vtorDisp: 39 // CHECK: %[[THIS_i8:.*]] = bitcast %struct.B* %[[THIS]] to i8* 40 // CHECK: %[[VBPTR:.*]] = getelementptr inbounds i8* %[[THIS_i8]], i32 0 41 // ... 42 // CHECK: %[[VBASE_OFFSET:.*]] = add nsw i32 0, %{{.*}} 43 // CHECK: %[[VTORDISP_VAL:.*]] = sub i32 %[[VBASE_OFFSET]], 8 44 // CHECK: %[[THIS_i8:.*]] = bitcast %struct.B* %[[THIS]] to i8* 45 // CHECK: %[[VBASE_i8:.*]] = getelementptr inbounds i8* %[[THIS_i8]], i32 %[[VBASE_OFFSET]] 46 // CHECK: %[[VTORDISP_i8:.*]] = getelementptr i8* %[[VBASE_i8]], i32 -4 47 // CHECK: %[[VTORDISP_PTR:.*]] = bitcast i8* %[[VTORDISP_i8]] to i32* 48 // CHECK: store i32 %[[VTORDISP_VAL]], i32* %[[VTORDISP_PTR]] 49 50 // CHECK: ret 51} 52 53B::~B() { 54 // CHECK-LABEL: define x86_thiscallcc void @"\01??1B@@UAE@XZ" 55 // Adjust the this parameter: 56 // CHECK: %[[THIS_PARAM_i8:.*]] = bitcast %struct.B* {{.*}} to i8* 57 // CHECK: %[[THIS_i8:.*]] = getelementptr inbounds i8* %[[THIS_PARAM_i8]], i32 -8 58 // CHECK: %[[THIS:.*]] = bitcast i8* %[[THIS_i8]] to %struct.B* 59 // CHECK: store %struct.B* %[[THIS]], %struct.B** %[[THIS_ADDR:.*]], align 4 60 // CHECK: %[[THIS:.*]] = load %struct.B** %[[THIS_ADDR]] 61 62 // Restore the vfptr that could have been changed by a subclass. 63 // CHECK: %[[THIS_i8:.*]] = bitcast %struct.B* %[[THIS]] to i8* 64 // CHECK: %[[VBPTR:.*]] = getelementptr inbounds i8* %[[THIS_i8]], i32 0 65 // ... 66 // CHECK: %[[THIS_i8:.*]] = bitcast %struct.B* %[[THIS]] to i8* 67 // CHECK: %[[VFPTR_i8:.*]] = getelementptr inbounds i8* %[[THIS_i8]], i32 %{{.*}} 68 // CHECK: %[[VFPTR:.*]] = bitcast i8* %[[VFPTR_i8]] to [3 x i8*]** 69 // CHECK: store [3 x i8*]* @"\01??_7B@@6B@", [3 x i8*]** %[[VFPTR]] 70 71 // Initialize vtorDisp: 72 // CHECK: %[[THIS_i8:.*]] = bitcast %struct.B* %[[THIS]] to i8* 73 // CHECK: %[[VBPTR:.*]] = getelementptr inbounds i8* %[[THIS_i8]], i32 0 74 // ... 75 // CHECK: %[[VBASE_OFFSET:.*]] = add nsw i32 0, %{{.*}} 76 // CHECK: %[[VTORDISP_VAL:.*]] = sub i32 %[[VBASE_OFFSET]], 8 77 // CHECK: %[[THIS_i8:.*]] = bitcast %struct.B* %[[THIS]] to i8* 78 // CHECK: %[[VBASE_i8:.*]] = getelementptr inbounds i8* %[[THIS_i8]], i32 %[[VBASE_OFFSET]] 79 // CHECK: %[[VTORDISP_i8:.*]] = getelementptr i8* %[[VBASE_i8]], i32 -4 80 // CHECK: %[[VTORDISP_PTR:.*]] = bitcast i8* %[[VTORDISP_i8]] to i32* 81 // CHECK: store i32 %[[VTORDISP_VAL]], i32* %[[VTORDISP_PTR]] 82 83 foo(); // Avoid the "trivial destructor" optimization. 84 85 // CHECK: ret 86 87 // CHECK2-LABEL: define linkonce_odr x86_thiscallcc void @"\01??_DB@@UAE@XZ"(%struct.B* 88 // CHECK2: %[[THIS:.*]] = load %struct.B** {{.*}} 89 // CHECK2: %[[THIS_i8:.*]] = bitcast %struct.B* %[[THIS]] to i8* 90 // CHECK2: %[[B_i8:.*]] = getelementptr i8* %[[THIS_i8]], i32 8 91 // CHECK2: %[[B:.*]] = bitcast i8* %[[B_i8]] to %struct.B* 92 // CHECK2: call x86_thiscallcc void @"\01??1B@@UAE@XZ"(%struct.B* %[[B]]) 93 // CHECK2: %[[THIS_i8:.*]] = bitcast %struct.B* %[[THIS]] to i8* 94 // CHECK2: %[[VBASE_i8:.*]] = getelementptr inbounds i8* %[[THIS_i8]], i64 8 95 // CHECK2: %[[VBASE:.*]] = bitcast i8* %[[VBASE_i8]] to %struct.VBase* 96 // CHECK2: call x86_thiscallcc void @"\01??1VBase@@UAE@XZ"(%struct.VBase* %[[VBASE]]) 97 // CHECK2: ret 98 99 // CHECK2-LABEL: define linkonce_odr x86_thiscallcc void @"\01??_GB@@UAEPAXI@Z" 100 // CHECK2: %[[THIS_PARAM_i8:.*]] = bitcast %struct.B* {{.*}} to i8* 101 // CHECK2: %[[THIS_i8:.*]] = getelementptr inbounds i8* %[[THIS_PARAM_i8:.*]], i32 -8 102 // CHECK2: %[[THIS:.*]] = bitcast i8* %[[THIS_i8]] to %struct.B* 103 // CHECK2: store %struct.B* %[[THIS]], %struct.B** %[[THIS_ADDR:.*]], align 4 104 // CHECK2: %[[THIS:.*]] = load %struct.B** %[[THIS_ADDR]] 105 // CHECK2: call x86_thiscallcc void @"\01??_DB@@UAE@XZ"(%struct.B* %[[THIS]]) 106 // ... 107 // CHECK2: ret 108} 109 110void B::foo() { 111// CHECK-LABEL: define x86_thiscallcc void @"\01?foo@B@@UAEXXZ"(i8* 112// 113// B::foo gets 'this' cast to VBase* in ECX (i.e. this+8) so we 114// need to adjust 'this' before use. 115// 116// CHECK: %[[THIS_ADDR:.*]] = alloca %struct.B*, align 4 117// CHECK: %[[THIS_i8:.*]] = getelementptr inbounds i8* %[[ECX:.*]], i32 -8 118// CHECK: %[[THIS:.*]] = bitcast i8* %[[THIS_i8]] to %struct.B* 119// CHECK: store %struct.B* %[[THIS]], %struct.B** %[[THIS_ADDR]], align 4 120 121 field = 42; 122// CHECK: %[[THIS:.*]] = load %struct.B** %[[THIS_ADDR]] 123// CHECK: %[[THIS8:.*]] = bitcast %struct.B* %[[THIS]] to i8* 124// CHECK: %[[VBPTR:.*]] = getelementptr inbounds i8* %[[THIS8]], i32 0 125// CHECK: %[[VBPTR8:.*]] = bitcast i8* %[[VBPTR]] to i8** 126// CHECK: %[[VBTABLE:.*]] = load i8** %[[VBPTR8]] 127// CHECK: %[[VBENTRY8:.*]] = getelementptr inbounds i8* %[[VBTABLE]], i32 4 128// CHECK: %[[VBENTRY:.*]] = bitcast i8* %[[VBENTRY8]] to i32* 129// CHECK: %[[VBOFFSET32:.*]] = load i32* %[[VBENTRY]] 130// CHECK: %[[VBOFFSET:.*]] = add nsw i32 0, %[[VBOFFSET32]] 131// CHECK: %[[THIS8:.*]] = bitcast %struct.B* %[[THIS]] to i8* 132// CHECK: %[[VBASE_i8:.*]] = getelementptr inbounds i8* %[[THIS8]], i32 %[[VBOFFSET]] 133// CHECK: %[[VBASE:.*]] = bitcast i8* %[[VBASE_i8]] to %struct.VBase* 134// CHECK: %[[FIELD:.*]] = getelementptr inbounds %struct.VBase* %[[VBASE]], i32 0, i32 1 135// CHECK: store i32 42, i32* %[[FIELD]], align 4 136// 137// CHECK: ret void 138} 139 140void call_vbase_bar(B *obj) { 141// CHECK-LABEL: define void @"\01?call_vbase_bar@@YAXPAUB@@@Z"(%struct.B* %obj) 142// CHECK: %[[OBJ:.*]] = load %struct.B 143 144 obj->bar(); 145// When calling a vbase's virtual method, one needs to adjust 'this' 146// at the caller site. 147// 148// CHECK: %[[OBJ_i8:.*]] = bitcast %struct.B* %[[OBJ]] to i8* 149// CHECK: %[[VBPTR:.*]] = getelementptr inbounds i8* %[[OBJ_i8]], i32 0 150// CHECK: %[[VBPTR8:.*]] = bitcast i8* %[[VBPTR]] to i8** 151// CHECK: %[[VBTABLE:.*]] = load i8** %[[VBPTR8]] 152// CHECK: %[[VBENTRY8:.*]] = getelementptr inbounds i8* %[[VBTABLE]], i32 4 153// CHECK: %[[VBENTRY:.*]] = bitcast i8* %[[VBENTRY8]] to i32* 154// CHECK: %[[VBOFFSET32:.*]] = load i32* %[[VBENTRY]] 155// CHECK: %[[VBOFFSET:.*]] = add nsw i32 0, %[[VBOFFSET32]] 156// CHECK: %[[VBASE_i8:.*]] = getelementptr inbounds i8* %[[OBJ_i8]], i32 %[[VBOFFSET]] 157// CHECK: %[[VFPTR:.*]] = bitcast i8* %[[VBASE_i8]] to void (i8*)*** 158// CHECK: %[[VFTABLE:.*]] = load void (i8*)*** %[[VFPTR]] 159// CHECK: %[[VFUN:.*]] = getelementptr inbounds void (i8*)** %[[VFTABLE]], i64 2 160// CHECK: %[[VFUN_VALUE:.*]] = load void (i8*)** %[[VFUN]] 161// 162// CHECK: %[[OBJ_i8:.*]] = bitcast %struct.B* %[[OBJ]] to i8* 163// CHECK: %[[VBPTR:.*]] = getelementptr inbounds i8* %[[OBJ_i8]], i32 0 164// CHECK: %[[VBPTR8:.*]] = bitcast i8* %[[VBPTR]] to i8** 165// CHECK: %[[VBTABLE:.*]] = load i8** %[[VBPTR8]] 166// CHECK: %[[VBENTRY8:.*]] = getelementptr inbounds i8* %[[VBTABLE]], i32 4 167// CHECK: %[[VBENTRY:.*]] = bitcast i8* %[[VBENTRY8]] to i32* 168// CHECK: %[[VBOFFSET32:.*]] = load i32* %[[VBENTRY]] 169// CHECK: %[[VBOFFSET:.*]] = add nsw i32 0, %[[VBOFFSET32]] 170// CHECK: %[[VBASE:.*]] = getelementptr inbounds i8* %[[OBJ_i8]], i32 %[[VBOFFSET]] 171// 172// CHECK: call x86_thiscallcc void %[[VFUN_VALUE]](i8* %[[VBASE]]) 173// 174// CHECK: ret void 175} 176 177void delete_B(B *obj) { 178// CHECK-LABEL: define void @"\01?delete_B@@YAXPAUB@@@Z"(%struct.B* %obj) 179// CHECK: %[[OBJ:.*]] = load %struct.B 180 181 delete obj; 182// CHECK: %[[OBJ_i8:.*]] = bitcast %struct.B* %[[OBJ]] to i8* 183// CHECK: %[[VBPTR:.*]] = getelementptr inbounds i8* %[[OBJ_i8]], i32 0 184// CHECK: %[[VBPTR8:.*]] = bitcast i8* %[[VBPTR]] to i8** 185// CHECK: %[[VBTABLE:.*]] = load i8** %[[VBPTR8]] 186// CHECK: %[[VBENTRY8:.*]] = getelementptr inbounds i8* %[[VBTABLE]], i32 4 187// CHECK: %[[VBENTRY:.*]] = bitcast i8* %[[VBENTRY8]] to i32* 188// CHECK: %[[VBOFFSET32:.*]] = load i32* %[[VBENTRY]] 189// CHECK: %[[VBOFFSET:.*]] = add nsw i32 0, %[[VBOFFSET32]] 190// CHECK: %[[VBASE_i8:.*]] = getelementptr inbounds i8* %[[OBJ_i8]], i32 %[[VBOFFSET]] 191// CHECK: %[[VFPTR:.*]] = bitcast i8* %[[VBASE_i8]] to void (%struct.B*, i32)*** 192// CHECK: %[[VFTABLE:.*]] = load void (%struct.B*, i32)*** %[[VFPTR]] 193// CHECK: %[[VFUN:.*]] = getelementptr inbounds void (%struct.B*, i32)** %[[VFTABLE]], i64 0 194// CHECK: %[[VFUN_VALUE:.*]] = load void (%struct.B*, i32)** %[[VFUN]] 195// 196// CHECK: %[[OBJ_i8:.*]] = bitcast %struct.B* %[[OBJ]] to i8* 197// CHECK: %[[VBPTR:.*]] = getelementptr inbounds i8* %[[OBJ_i8]], i32 0 198// CHECK: %[[VBPTR8:.*]] = bitcast i8* %[[VBPTR]] to i8** 199// CHECK: %[[VBTABLE:.*]] = load i8** %[[VBPTR8]] 200// CHECK: %[[VBENTRY8:.*]] = getelementptr inbounds i8* %[[VBTABLE]], i32 4 201// CHECK: %[[VBENTRY:.*]] = bitcast i8* %[[VBENTRY8]] to i32* 202// CHECK: %[[VBOFFSET32:.*]] = load i32* %[[VBENTRY]] 203// CHECK: %[[VBOFFSET:.*]] = add nsw i32 0, %[[VBOFFSET32]] 204// CHECK: %[[VBASE_i8:.*]] = getelementptr inbounds i8* %[[OBJ_i8]], i32 %[[VBOFFSET]] 205// CHECK: %[[VBASE:.*]] = bitcast i8* %[[VBASE_i8]] to %struct.B* 206// 207// CHECK: call x86_thiscallcc void %[[VFUN_VALUE]](%struct.B* %[[VBASE]], i32 1) 208// CHECK: ret void 209} 210 211void call_complete_dtor() { 212 // CHECK-LABEL: define void @"\01?call_complete_dtor@@YAXXZ" 213 B b; 214 // CHECK: call x86_thiscallcc %struct.B* @"\01??0B@@QAE@XZ"(%struct.B* %[[B:.*]], i32 1) 215 // CHECK-NOT: getelementptr 216 // CHECK: call x86_thiscallcc void @"\01??_DB@@UAE@XZ"(%struct.B* %[[B]]) 217 // CHECK: ret 218} 219 220struct C : B { 221 C(); 222 // has an implicit vdtor. 223}; 224 225// Used to crash on an assertion. 226C::C() { 227// CHECK-LABEL: define x86_thiscallcc %struct.C* @"\01??0C@@QAE@XZ" 228} 229 230namespace multiple_vbases { 231struct A { 232 virtual void a(); 233}; 234 235struct B { 236 virtual void b(); 237}; 238 239struct C { 240 virtual void c(); 241}; 242 243struct D : virtual A, virtual B, virtual C { 244 virtual void a(); 245 virtual void b(); 246 virtual void c(); 247 D(); 248}; 249 250D::D() { 251 // CHECK-LABEL: define x86_thiscallcc %"struct.multiple_vbases::D"* @"\01??0D@multiple_vbases@@QAE@XZ" 252 // Just make sure we emit 3 vtordisps after initializing vfptrs. 253 // CHECK: store [1 x i8*]* @"\01??_7D@multiple_vbases@@6BA@1@@", [1 x i8*]** %{{.*}} 254 // CHECK: store [1 x i8*]* @"\01??_7D@multiple_vbases@@6BB@1@@", [1 x i8*]** %{{.*}} 255 // CHECK: store [1 x i8*]* @"\01??_7D@multiple_vbases@@6BC@1@@", [1 x i8*]** %{{.*}} 256 // ... 257 // CHECK: store i32 %{{.*}}, i32* %{{.*}} 258 // CHECK: store i32 %{{.*}}, i32* %{{.*}} 259 // CHECK: store i32 %{{.*}}, i32* %{{.*}} 260 // CHECK: ret 261} 262} 263 264namespace diamond { 265struct A { 266 A(); 267 virtual ~A(); 268}; 269 270struct B : virtual A { 271 B(); 272 ~B(); 273}; 274 275struct C : virtual A { 276 C(); 277 ~C(); 278 int c1, c2, c3; 279}; 280 281struct Z { 282 int z; 283}; 284 285struct D : virtual Z, B, C { 286 D(); 287 ~D(); 288} d; 289 290D::~D() { 291 // CHECK-LABEL: define x86_thiscallcc void @"\01??1D@diamond@@UAE@XZ"(%"struct.diamond::D"*) 292 // CHECK: %[[ARG_i8:.*]] = bitcast %"struct.diamond::D"* %{{.*}} to i8* 293 // CHECK: %[[THIS_i8:.*]] = getelementptr inbounds i8* %[[ARG_i8]], i32 -24 294 // CHECK: %[[THIS:.*]] = bitcast i8* %[[THIS_i8]] to %"struct.diamond::D"* 295 // CHECK: store %"struct.diamond::D"* %[[THIS]], %"struct.diamond::D"** %[[THIS_VAL:.*]], align 4 296 // CHECK: %[[THIS:.*]] = load %"struct.diamond::D"** %[[THIS_VAL]] 297 // CHECK: %[[D_i8:.*]] = bitcast %"struct.diamond::D"* %[[THIS]] to i8* 298 // CHECK: %[[C_i8:.*]] = getelementptr inbounds i8* %[[D_i8]], i64 4 299 // CHECK: %[[C:.*]] = bitcast i8* %[[C_i8]] to %"struct.diamond::C"* 300 // CHECK: %[[C_i8:.*]] = bitcast %"struct.diamond::C"* %[[C]] to i8* 301 // CHECK: %[[ARG_i8:.*]] = getelementptr i8* %{{.*}}, i32 16 302 // FIXME: We might consider changing the dtor this parameter type to i8*. 303 // CHECK: %[[ARG:.*]] = bitcast i8* %[[ARG_i8]] to %"struct.diamond::C"* 304 // CHECK: call x86_thiscallcc void @"\01??1C@diamond@@UAE@XZ"(%"struct.diamond::C"* %[[ARG]]) 305 306 // CHECK: %[[B:.*]] = bitcast %"struct.diamond::D"* %[[THIS]] to %"struct.diamond::B"* 307 // CHECK: %[[B_i8:.*]] = bitcast %"struct.diamond::B"* %[[B]] to i8* 308 // CHECK: %[[ARG_i8:.*]] = getelementptr i8* %[[B_i8]], i32 4 309 // CHECK: %[[ARG:.*]] = bitcast i8* %[[ARG_i8]] to %"struct.diamond::B"* 310 // CHECK: call x86_thiscallcc void @"\01??1B@diamond@@UAE@XZ"(%"struct.diamond::B"* %[[ARG]]) 311 // CHECK: ret void 312} 313 314} 315 316namespace test2 { 317struct A { A(); }; 318struct B : virtual A { B() {} }; 319struct C : B, A { C() {} }; 320 321// PR18435: Order mattered here. We were generating code for the delegating 322// call to B() from C(). 323void callC() { C x; } 324 325// CHECK-LABEL: define linkonce_odr x86_thiscallcc %"struct.test2::C"* @"\01??0C@test2@@QAE@XZ" 326// CHECK: (%"struct.test2::C"* returned %this, i32 %is_most_derived) 327// CHECK: br i1 328// Virtual bases 329// CHECK: call x86_thiscallcc %"struct.test2::A"* @"\01??0A@test2@@QAE@XZ"(%"struct.test2::A"* %{{.*}}) 330// CHECK: br label 331// Non-virtual bases 332// CHECK: call x86_thiscallcc %"struct.test2::B"* @"\01??0B@test2@@QAE@XZ"(%"struct.test2::B"* %{{.*}}, i32 0) 333// CHECK: call x86_thiscallcc %"struct.test2::A"* @"\01??0A@test2@@QAE@XZ"(%"struct.test2::A"* %{{.*}}) 334// CHECK: ret 335 336// CHECK2-LABEL: define linkonce_odr x86_thiscallcc %"struct.test2::B"* @"\01??0B@test2@@QAE@XZ" 337// CHECK2: (%"struct.test2::B"* returned %this, i32 %is_most_derived) 338// CHECK2: call x86_thiscallcc %"struct.test2::A"* @"\01??0A@test2@@QAE@XZ"(%"struct.test2::A"* %{{.*}}) 339// CHECK2: ret 340 341} 342 343namespace test3 { 344// PR19104: A non-virtual call of a virtual method doesn't use vftable thunks, 345// so requires only static adjustment which is different to the one used 346// for virtual calls. 347struct A { 348 virtual void foo(); 349}; 350 351struct B : virtual A { 352 virtual void bar(); 353}; 354 355struct C : virtual A { 356 virtual void foo(); 357}; 358 359struct D : B, C { 360 virtual void bar(); 361 int field; // Laid out between C and A subobjects in D. 362}; 363 364void D::bar() { 365 // CHECK-LABEL: define x86_thiscallcc void @"\01?bar@D@test3@@UAEXXZ"(%"struct.test3::D"* %this) 366 367 C::foo(); 368 // Shouldn't need any vbtable lookups. All we have to do is adjust to C*, 369 // then compensate for the adjustment performed in the C::foo() prologue. 370 // CHECK-NOT: load i8** 371 // CHECK: %[[OBJ_i8:.*]] = bitcast %"struct.test3::D"* %{{.*}} to i8* 372 // CHECK: %[[C_i8:.*]] = getelementptr inbounds i8* %[[OBJ_i8]], i32 8 373 // CHECK: %[[C:.*]] = bitcast i8* %[[C_i8]] to %"struct.test3::C"* 374 // CHECK: %[[C_i8:.*]] = bitcast %"struct.test3::C"* %[[C]] to i8* 375 // CHECK: %[[ARG:.*]] = getelementptr i8* %[[C_i8]], i32 4 376 // CHECK: call x86_thiscallcc void @"\01?foo@C@test3@@UAEXXZ"(i8* %[[ARG]]) 377 // CHECK: ret 378} 379} 380 381namespace test4{ 382// PR19172: We used to merge method vftable locations wrong. 383 384struct A { 385 virtual ~A() {} 386}; 387 388struct B { 389 virtual ~B() {} 390}; 391 392struct C : virtual A, B { 393 virtual ~C(); 394}; 395 396void foo(void*); 397 398C::~C() { 399 // CHECK-LABEL: define x86_thiscallcc void @"\01??1C@test4@@UAE@XZ"(%"struct.test4::C"* %this) 400 401 // In this case "this" points to the most derived class, so no GEPs needed. 402 // CHECK-NOT: getelementptr 403 // CHECK-NOT: bitcast 404 // CHECK: %[[VFPTR_i8:.*]] = bitcast %"struct.test4::C"* %{{.*}} to [1 x i8*]** 405 // CHECK: store [1 x i8*]* @"\01??_7C@test4@@6BB@1@@", [1 x i8*]** %[[VFPTR_i8]] 406 407 foo(this); 408 // CHECK: ret 409} 410 411void destroy(C *obj) { 412 // CHECK-LABEL: define void @"\01?destroy@test4@@YAXPAUC@1@@Z"(%"struct.test4::C"* %obj) 413 414 delete obj; 415 // CHECK: %[[VPTR:.*]] = bitcast %"struct.test4::C"* %[[OBJ:.*]] to void (%"struct.test4::C"*, i32)*** 416 // CHECK: %[[VFTABLE:.*]] = load void (%"struct.test4::C"*, i32)*** %[[VPTR]] 417 // CHECK: %[[VFTENTRY:.*]] = getelementptr inbounds void (%"struct.test4::C"*, i32)** %[[VFTABLE]], i64 0 418 // CHECK: %[[VFUN:.*]] = load void (%"struct.test4::C"*, i32)** %[[VFTENTRY]] 419 // CHECK: call x86_thiscallcc void %[[VFUN]](%"struct.test4::C"* %[[OBJ]], i32 1) 420 // CHECK: ret 421} 422 423struct D { 424 virtual void d(); 425}; 426 427// The first non-virtual base doesn't have a vdtor, 428// but "this adjustment" is not needed. 429struct E : D, B, virtual A { 430 virtual ~E(); 431}; 432 433E::~E() { 434 // CHECK-LABEL: define x86_thiscallcc void @"\01??1E@test4@@UAE@XZ"(%"struct.test4::E"* %this) 435 436 // In this case "this" points to the most derived class, so no GEPs needed. 437 // CHECK-NOT: getelementptr 438 // CHECK-NOT: bitcast 439 // CHECK: %[[VFPTR_i8:.*]] = bitcast %"struct.test4::E"* %{{.*}} to [1 x i8*]** 440 // CHECK: store [1 x i8*]* @"\01??_7E@test4@@6BD@1@@", [1 x i8*]** %[[VFPTR_i8]] 441 foo(this); 442} 443 444void destroy(E *obj) { 445 // CHECK-LABEL: define void @"\01?destroy@test4@@YAXPAUE@1@@Z"(%"struct.test4::E"* %obj) 446 447 // CHECK-NOT: getelementptr 448 // CHECK: %[[OBJ_i8:.*]] = bitcast %"struct.test4::E"* %[[OBJ:.*]] to i8* 449 // CHECK: %[[B_i8:.*]] = getelementptr inbounds i8* %[[OBJ_i8]], i32 4 450 // CHECK: %[[VPTR:.*]] = bitcast i8* %[[B_i8]] to void (%"struct.test4::E"*, i32)*** 451 // CHECK: %[[VFTABLE:.*]] = load void (%"struct.test4::E"*, i32)*** %[[VPTR]] 452 // CHECK: %[[VFTENTRY:.*]] = getelementptr inbounds void (%"struct.test4::E"*, i32)** %[[VFTABLE]], i64 0 453 // CHECK: %[[VFUN:.*]] = load void (%"struct.test4::E"*, i32)** %[[VFTENTRY]] 454 // CHECK: %[[OBJ_i8:.*]] = bitcast %"struct.test4::E"* %[[OBJ]] to i8* 455 // CHECK: %[[B_i8:.*]] = getelementptr inbounds i8* %[[OBJ_i8]], i32 4 456 // FIXME: in fact, the call should take i8* and the bitcast is redundant. 457 // CHECK: %[[B_as_E:.*]] = bitcast i8* %[[B_i8]] to %"struct.test4::E"* 458 // CHECK: call x86_thiscallcc void %[[VFUN]](%"struct.test4::E"* %[[B_as_E]], i32 1) 459 delete obj; 460} 461 462} 463