diff options
Diffstat (limited to 'test/CodeGenCXX/delete.cpp')
-rw-r--r-- | test/CodeGenCXX/delete.cpp | 23 |
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; } } |