aboutsummaryrefslogtreecommitdiff
path: root/clang/test/CIR/CodeGen/dtors.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/test/CIR/CodeGen/dtors.cpp')
-rw-r--r--clang/test/CIR/CodeGen/dtors.cpp81
1 files changed, 81 insertions, 0 deletions
diff --git a/clang/test/CIR/CodeGen/dtors.cpp b/clang/test/CIR/CodeGen/dtors.cpp
index 49952a7..7fb0975 100644
--- a/clang/test/CIR/CodeGen/dtors.cpp
+++ b/clang/test/CIR/CodeGen/dtors.cpp
@@ -208,3 +208,84 @@ void test_nested_dtor() {
// OGCG: define {{.*}} void @_ZN1DD2Ev
// OGCG: %[[C:.*]] = getelementptr inbounds i8, ptr %{{.*}}, i64 4
// OGCG: call void @_ZN1CD1Ev(ptr {{.*}} %[[C]])
+
+struct E {
+ ~E();
+};
+
+struct F : public E {
+ int n;
+ ~F() {}
+};
+
+// CIR: cir.func {{.*}} @_ZN1FD2Ev
+// CIR: %[[BASE_E:.*]] = cir.base_class_addr %{{.*}} : !cir.ptr<!rec_F> nonnull [0] -> !cir.ptr<!rec_E>
+// CIR: cir.call @_ZN1ED2Ev(%[[BASE_E]]) nothrow : (!cir.ptr<!rec_E>) -> ()
+
+// Because E is at offset 0 in F, there is no getelementptr needed.
+
+// LLVM: define {{.*}} void @_ZN1FD2Ev
+// LLVM: call void @_ZN1ED2Ev(ptr %{{.*}})
+
+// This destructor is defined after the calling function in OGCG.
+
+void test_base_dtor_call() {
+ F f;
+}
+
+// CIR: cir.func {{.*}} @_Z19test_base_dtor_callv()
+// cir.call @_ZN1FD2Ev(%{{.*}}) nothrow : (!cir.ptr<!rec_F>) -> ()
+
+// LLVM: define {{.*}} void @_Z19test_base_dtor_callv()
+// LLVM: call void @_ZN1FD2Ev(ptr %{{.*}})
+
+// OGCG: define {{.*}} void @_Z19test_base_dtor_callv()
+// OGCG: call void @_ZN1FD2Ev(ptr {{.*}} %{{.*}})
+
+// OGCG: define {{.*}} void @_ZN1FD2Ev
+// OGCG: call void @_ZN1ED2Ev(ptr {{.*}} %{{.*}})
+
+struct VirtualBase {
+ ~VirtualBase();
+};
+
+struct Derived : virtual VirtualBase {
+ ~Derived() {}
+};
+
+void test_base_dtor_call_virtual_base() {
+ Derived d;
+}
+
+// Derived D2 (base) destructor -- does not call VirtualBase destructor
+
+// CIR: cir.func {{.*}} @_ZN7DerivedD2Ev
+// CIR-NOT: cir.call{{.*}} @_ZN11VirtualBaseD2Ev
+// CIR: cir.return
+
+// LLVM: define {{.*}} void @_ZN7DerivedD2Ev
+// LLVM-NOT: call{{.*}} @_ZN11VirtualBaseD2Ev
+// LLVM: ret
+
+// Derived D1 (complete) destructor -- does call VirtualBase destructor
+
+// CIR: cir.func {{.*}} @_ZN7DerivedD1Ev
+// CIR: %[[THIS:.*]] = cir.load %{{.*}}
+// CIR: %[[VTT:.*]] = cir.vtt.address_point @_ZTT7Derived, offset = 0 -> !cir.ptr<!cir.ptr<!void>>
+// CIR: cir.call @_ZN7DerivedD2Ev(%[[THIS]], %[[VTT]])
+// CIR: %[[VIRTUAL_BASE:.*]] = cir.base_class_addr %[[THIS]] : !cir.ptr<!rec_Derived> nonnull [0] -> !cir.ptr<!rec_VirtualBase>
+// CIR: cir.call @_ZN11VirtualBaseD2Ev(%[[VIRTUAL_BASE]])
+
+// LLVM: define {{.*}} void @_ZN7DerivedD1Ev
+// LLVM: call void @_ZN7DerivedD2Ev(ptr %{{.*}}, ptr @_ZTT7Derived)
+// LLVM: call void @_ZN11VirtualBaseD2Ev(ptr %{{.*}})
+
+// OGCG emits these destructors in reverse order
+
+// OGCG: define {{.*}} void @_ZN7DerivedD1Ev
+// OGCG: call void @_ZN7DerivedD2Ev(ptr {{.*}} %{{.*}}, ptr {{.*}} @_ZTT7Derived)
+// OGCG: call void @_ZN11VirtualBaseD2Ev(ptr {{.*}} %{{.*}})
+
+// OGCG: define {{.*}} void @_ZN7DerivedD2Ev
+// OGCG-NOT: call{{.*}} @_ZN11VirtualBaseD2Ev
+// OGCG: ret