Skip to content

Commit ef64f86

Browse files
authored
[CIR] Implement virtual destructor call (#1856)
Implements #1812
1 parent 4f08056 commit ef64f86

File tree

2 files changed

+60
-1
lines changed

2 files changed

+60
-1
lines changed

clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,8 @@ RValue CIRGenFunction::emitCXXMemberOrOperatorMemberCallExpr(
302302
"Destructor shouldn't have explicit parameters");
303303
assert(ReturnValue.isNull() && "Destructor shouldn't have return value");
304304
if (useVirtualCall) {
305-
llvm_unreachable("NYI");
305+
CIRGenFunction* CGF = CGM.getCurrCIRGenFun();
306+
CGM.getCXXABI().emitVirtualDestructorCall(*CGF, dtor, Dtor_Complete,This.getAddress(), dyn_cast<CXXMemberCallExpr>(CE));
306307
} else {
307308
GlobalDecl globalDecl(dtor, Dtor_Complete);
308309
CIRGenCallee Callee;
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c++20 -fclangir -emit-cir %s -o %t.cir
2+
// RUN: FileCheck --check-prefix=CIR --input-file=%t.cir %s
3+
4+
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c++20 -fclangir -emit-llvm %s -o %t.cir
5+
// RUN: FileCheck --check-prefix=LLVM --input-file=%t.cir %s
6+
7+
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c++20 -emit-llvm %s -o %t.cir
8+
// RUN: FileCheck --check-prefix=OGCG --input-file=%t.cir %s
9+
10+
class A {
11+
virtual ~A();
12+
A B(A);
13+
};
14+
A A::B(A) {
15+
// CIR-LABEL: cir.func dso_local @_ZN1A1BES_(
16+
// CIR-SAME: %[[THIS_ARG:.*]]: !cir.ptr<!rec_A>
17+
// CIR-NEXT: %[[THIS_VAR:.*]] = cir.alloca !cir.ptr<!rec_A>, !cir.ptr<!cir.ptr<!rec_A>>
18+
// CIR: cir.store %[[THIS_ARG]], %[[THIS_VAR]] : !cir.ptr<!rec_A>, !cir.ptr<!cir.ptr<!rec_A>>
19+
// CIR: %[[THIS:.*]] = cir.load %[[THIS_VAR]] : !cir.ptr<!cir.ptr<!rec_A>>, !cir.ptr<!rec_A>
20+
// CIR-NEXT: %[[VPTR_PTR:.*]] = cir.vtable.get_vptr %[[THIS]] : !cir.ptr<!rec_A> -> !cir.ptr<!cir.vptr>
21+
// CIR-NEXT: %[[VPTR:.*]] = cir.load align(8) %[[VPTR_PTR]] : !cir.ptr<!cir.vptr>, !cir.vptr
22+
// CIR-NEXT: %[[DTOR_PTR:.*]] = cir.vtable.get_virtual_fn_addr %[[VPTR]][0] : !cir.vptr -> !cir.ptr<!cir.ptr<!cir.func<(!cir.ptr<!rec_A>)>>>
23+
// CIR-NEXT: %[[DTOR:.*]] = cir.load align(8) %[[DTOR_PTR]] : !cir.ptr<!cir.ptr<!cir.func<(!cir.ptr<!rec_A>)>>>, !cir.ptr<!cir.func<(!cir.ptr<!rec_A>)>>
24+
// CIR-NEXT: cir.call %[[DTOR]](%[[THIS]]) : (!cir.ptr<!cir.func<(!cir.ptr<!rec_A>)>>, !cir.ptr<!rec_A>) -> ()
25+
// CIR-NEXT: cir.trap
26+
// CIR-NEXT: }
27+
28+
29+
// LLVM-LABEL: define dso_local %class.A @_ZN1A1BES_(
30+
// LLVM-SAME: ptr %[[THIS_ARG:[0-9]+]],
31+
// LLVM-NEXT: %[[THIS_VAR:.*]] = alloca ptr, i64 1, align 8
32+
// LLVM: store ptr %[[THIS_ARG]], ptr %[[THIS_VAR]], align 8
33+
// LLVM: %[[THIS:.*]] = load ptr, ptr %[[THIS_VAR]], align 8
34+
// LLVM-NEXT: %[[VTABLE_PTR:.*]] = load ptr, ptr %[[THIS]], align 8
35+
// LLVM-NEXT: %[[VIRT_DTOR_ADDR:.*]] = getelementptr inbounds ptr, ptr %[[VTABLE_PTR]], i32 0
36+
// LLVM-NEXT: %[[DTOR:.*]] = load ptr, ptr %[[VIRT_DTOR_ADDR]], align 8
37+
// LLVM-NEXT: call void %[[DTOR]](ptr %[[THIS]])
38+
// LLVM-NEXT: call void @llvm.trap()
39+
// LLVM-NEXT: unreachable
40+
// LLVM-NEXT: }
41+
42+
43+
// OGCG-LABEL: define dso_local void @_ZN1A1BES_(
44+
// OGCG-SAME: ptr {{.*}}%[[THIS_ARG:.*]],
45+
// OGCG: %[[VAL_0:.*]] = alloca ptr, align 8
46+
// OGCG-NEXT: %[[THIS_VAR:.*]] = alloca ptr, align 8
47+
// OGCG: store ptr %[[THIS_ARG]], ptr %[[THIS_VAR]], align 8
48+
// OGCG: %[[THIS:.*]] = load ptr, ptr %[[THIS_VAR]], align 8
49+
// OGCG-NEXT: %[[VTABLE:.*]] = load ptr, ptr %[[THIS]], align 8
50+
// OGCG-NEXT: %[[VIRT_DTOR_ADDR:.*]] = getelementptr inbounds ptr, ptr %[[VTABLE]], i64 0
51+
// OGCG-NEXT: %[[DTOR:.*]] = load ptr, ptr %[[VIRT_DTOR_ADDR]], align 8
52+
// OGCG-NEXT: call void %[[DTOR]](ptr noundef nonnull align 8 dereferenceable(8) %[[THIS]]) #2
53+
// OGCG-NEXT: call void @llvm.trap()
54+
// OGCG-NEXT: unreachable
55+
// OGCG-NEXT: }
56+
57+
this->~A();
58+
}

0 commit comments

Comments
 (0)