aboutsummaryrefslogtreecommitdiff
path: root/test/CodeGenCXX/delete.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'test/CodeGenCXX/delete.cpp')
-rw-r--r--test/CodeGenCXX/delete.cpp23
1 files changed, 17 insertions, 6 deletions
diff --git a/test/CodeGenCXX/delete.cpp b/test/CodeGenCXX/delete.cpp
index 5a88f9f92437..7a91ca814637 100644
--- a/test/CodeGenCXX/delete.cpp
+++ b/test/CodeGenCXX/delete.cpp
@@ -113,12 +113,23 @@ namespace test4 {
// CHECK: define void @_ZN5test421global_delete_virtualEPNS_1XE
void global_delete_virtual(X *xp) {
- // CHECK: [[VTABLE:%.*]] = load void ([[X:%.*]])***
- // CHECK-NEXT: [[VFN:%.*]] = getelementptr inbounds void ([[X]])** [[VTABLE]], i64 0
- // CHECK-NEXT: [[VFNPTR:%.*]] = load void ([[X]])** [[VFN]]
- // CHECK-NEXT: call void [[VFNPTR]]([[X]] [[OBJ:%.*]])
- // CHECK-NEXT: [[OBJVOID:%.*]] = bitcast [[X]] [[OBJ]] to i8*
- // CHECK-NEXT: call void @_ZdlPv(i8* [[OBJVOID]]) nounwind
+ // Load the offset-to-top from the vtable and apply it.
+ // This has to be done first because the dtor can mess it up.
+ // CHECK: [[T0:%.*]] = bitcast [[X:%.*]]* [[XP:%.*]] to i64**
+ // CHECK-NEXT: [[VTABLE:%.*]] = load i64** [[T0]]
+ // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds i64* [[VTABLE]], i64 -2
+ // CHECK-NEXT: [[OFFSET:%.*]] = load i64* [[T0]], align 8
+ // CHECK-NEXT: [[T0:%.*]] = bitcast [[X]]* [[XP]] to i8*
+ // CHECK-NEXT: [[ALLOCATED:%.*]] = getelementptr inbounds i8* [[T0]], i64 [[OFFSET]]
+ // Load the complete-object destructor (not the deleting destructor)
+ // and call it.
+ // CHECK-NEXT: [[T0:%.*]] = bitcast [[X:%.*]]* [[XP:%.*]] to void ([[X]]*)***
+ // CHECK-NEXT: [[VTABLE:%.*]] = load void ([[X]]*)*** [[T0]]
+ // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds void ([[X]]*)** [[VTABLE]], i64 0
+ // CHECK-NEXT: [[DTOR:%.*]] = load void ([[X]]*)** [[T0]]
+ // CHECK-NEXT: call void [[DTOR]]([[X]]* [[OBJ:%.*]])
+ // Call the global operator delete.
+ // CHECK-NEXT: call void @_ZdlPv(i8* [[ALLOCATED]]) nounwind
::delete xp;
}
}