class Base{
public:
Base() { }
virtual ~Base();
void foo() {
wrong();
}
virtual void wrong() = 0;
};
void Base::wrong(){}
Base::~Base(){
foo();
}
class Derived : public Base {
public:
~Derived(){}
void wrong() {}
};
int main(void)
{
{
Derived d;
}
int i = 1;
return 0;
}
x86-64 gcc 11.1
Base::Base() [base object constructor]:
push rbp
mov rbp, rsp
mov QWORD PTR [rbp-8], rdi
mov edx, OFFSET FLAT:vtable for Base+16
mov rax, QWORD PTR [rbp-8]
mov QWORD PTR [rax], rdx
nop
pop rbp
ret
Base::foo():
push rbp
mov rbp, rsp
sub rsp, 16
mov QWORD PTR [rbp-8], rdi
mov rax, QWORD PTR [rbp-8]
mov rax, QWORD PTR [rax]
add rax, 16
mov rdx, QWORD PTR [rax]
mov rax, QWORD PTR [rbp-8]
mov rdi, rax
call rdx
nop
leave
ret
Base::wrong():
push rbp
mov rbp, rsp
mov QWORD PTR [rbp-8], rdi
nop
pop rbp
ret
Base::~Base() [base object destructor]:
push rbp
mov rbp, rsp
sub rsp, 16
mov QWORD PTR [rbp-8], rdi
mov edx, OFFSET FLAT:vtable for Base+16
mov rax, QWORD PTR [rbp-8]
mov QWORD PTR [rax], rdx
mov rax, QWORD PTR [rbp-8]
mov rdi, rax
call Base::foo()
nop
leave
ret
Base::~Base() [deleting destructor]:
push rbp
mov rbp, rsp
sub rsp, 16
mov QWORD PTR [rbp-8], rdi
mov rax, QWORD PTR [rbp-8]
mov rdi, rax
call Base::~Base() [complete object destructor]
mov rax, QWORD PTR [rbp-8]
mov esi, 8
mov rdi, rax
call operator delete(void*, unsigned long)
leave
ret
Derived::~Derived() [base object destructor]:
push rbp
mov rbp, rsp
sub rsp, 16
mov QWORD PTR [rbp-8], rdi
mov edx, OFFSET FLAT:vtable for Derived+16
mov rax, QWORD PTR [rbp-8]
mov QWORD PTR [rax], rdx
mov rax, QWORD PTR [rbp-8]
mov rdi, rax
call Base::~Base() [base object destructor]
nop
leave
ret
Derived::~Derived() [deleting destructor]:
push rbp
mov rbp, rsp
sub rsp, 16
mov QWORD PTR [rbp-8], rdi
mov rax, QWORD PTR [rbp-8]
mov rdi, rax
call Derived::~Derived() [complete object destructor]
mov rax, QWORD PTR [rbp-8]
mov esi, 8
mov rdi, rax
call operator delete(void*, unsigned long)
leave
ret
Derived::wrong():
push rbp
mov rbp, rsp
mov QWORD PTR [rbp-8], rdi
nop
pop rbp
ret
Derived::Derived() [base object constructor]:
push rbp
mov rbp, rsp
sub rsp, 16
mov QWORD PTR [rbp-8], rdi
mov rax, QWORD PTR [rbp-8]
mov rdi, rax
call Base::Base() [base object constructor]
mov edx, OFFSET FLAT:vtable for Derived+16
mov rax, QWORD PTR [rbp-8]
mov QWORD PTR [rax], rdx
nop
leave
ret
main:
push rbp
mov rbp, rsp
sub rsp, 16
lea rax, [rbp-16]
mov rdi, rax
call Derived::Derived() [complete object constructor]
lea rax, [rbp-16]
mov rdi, rax
call Derived::~Derived() [complete object destructor]
mov DWORD PTR [rbp-4], 1
mov eax, 0
leave
ret
vtable for Derived:
.quad 0
.quad typeinfo for Derived
.quad Derived::~Derived() [complete object destructor]
.quad Derived::~Derived() [deleting destructor]
.quad Derived::wrong()
vtable for Base:
.quad 0
.quad typeinfo for Base
.quad 0
.quad 0
.quad __cxa_pure_virtual
typeinfo for Derived:
.quad vtable for __cxxabiv1::__si_class_type_info+16
.quad typeinfo name for Derived
.quad typeinfo for Base
typeinfo name for Derived:
.string "7Derived"
typeinfo for Base:
.quad vtable for __cxxabiv1::__class_type_info+16
.quad typeinfo name for Base
typeinfo name for Base:
.string "4Base"
armv8-a clang 11.0.1
Base::wrong(): // @Base::wrong()
sub sp, sp, #16 // =16
str x0, [sp, #8]
add sp, sp, #16 // =16
ret
Base::~Base() [base object destructor]: // @Base::~Base() [base object destructor]
sub sp, sp, #32 // =32
stp x29, x30, [sp, #16] // 16-byte Folded Spill
add x29, sp, #16 // =16
adrp x8, vtable for Base
add x8, x8, :lo12:vtable for Base
add x8, x8, #16 // =16
str x0, [sp, #8]
ldr x9, [sp, #8]
str x8, [x9]
mov x0, x9
bl Base::foo()
b .LBB1_1
.LBB1_1:
ldp x29, x30, [sp, #16] // 16-byte Folded Reload
add sp, sp, #32 // =32
ret
bl __clang_call_terminate
Base::foo(): // @Base::foo()
sub sp, sp, #32 // =32
stp x29, x30, [sp, #16] // 16-byte Folded Spill
add x29, sp, #16 // =16
str x0, [sp, #8]
ldr x8, [sp, #8]
ldr x9, [x8]
ldr x9, [x9, #16]
mov x0, x8
blr x9
ldp x29, x30, [sp, #16] // 16-byte Folded Reload
add sp, sp, #32 // =32
ret
__clang_call_terminate: // @__clang_call_terminate
str x30, [sp, #-16]! // 8-byte Folded Spill
bl __cxa_begin_catch
bl std::terminate()
Base::~Base() [deleting destructor]: // @Base::~Base() [deleting destructor]
sub sp, sp, #16 // =16
str x0, [sp, #8]
brk #0x1
main: // @main
sub sp, sp, #48 // =48
stp x29, x30, [sp, #32] // 16-byte Folded Spill
add x29, sp, #32 // =32
mov w8, wzr
stur wzr, [x29, #-4]
add x9, sp, #16 // =16
mov x0, x9
str w8, [sp, #8] // 4-byte Folded Spill
str x9, [sp] // 8-byte Folded Spill
bl Derived::Derived() [base object constructor]
ldr x0, [sp] // 8-byte Folded Reload
bl Derived::~Derived() [base object destructor]
mov w8, #1
str w8, [sp, #12]
ldr w0, [sp, #8] // 4-byte Folded Reload
ldp x29, x30, [sp, #32] // 16-byte Folded Reload
add sp, sp, #48 // =48
ret
Derived::Derived() [base object constructor]: // @Derived::Derived() [base object constructor]
sub sp, sp, #48 // =48
stp x29, x30, [sp, #32] // 16-byte Folded Spill
add x29, sp, #32 // =32
adrp x8, vtable for Derived
add x8, x8, :lo12:vtable for Derived
add x8, x8, #16 // =16
stur x0, [x29, #-8]
ldur x9, [x29, #-8]
mov x0, x9
str x8, [sp, #16] // 8-byte Folded Spill
str x9, [sp, #8] // 8-byte Folded Spill
bl Base::Base() [base object constructor]
ldr x8, [sp, #16] // 8-byte Folded Reload
ldr x9, [sp, #8] // 8-byte Folded Reload
str x8, [x9]
ldp x29, x30, [sp, #32] // 16-byte Folded Reload
add sp, sp, #48 // =48
ret
Derived::~Derived() [base object destructor]: // @Derived::~Derived() [base object destructor]
sub sp, sp, #32 // =32
stp x29, x30, [sp, #16] // 16-byte Folded Spill
add x29, sp, #16 // =16
str x0, [sp, #8]
ldr x0, [sp, #8]
bl Base::~Base() [base object destructor]
ldp x29, x30, [sp, #16] // 16-byte Folded Reload
add sp, sp, #32 // =32
ret
Base::Base() [base object constructor]: // @Base::Base() [base object constructor]
sub sp, sp, #16 // =16
adrp x8, vtable for Base
add x8, x8, :lo12:vtable for Base
add x8, x8, #16 // =16
str x0, [sp, #8]
ldr x9, [sp, #8]
str x8, [x9]
add sp, sp, #16 // =16
ret
Derived::~Derived() [deleting destructor]: // @Derived::~Derived() [deleting destructor]
sub sp, sp, #32 // =32
stp x29, x30, [sp, #16] // 16-byte Folded Spill
add x29, sp, #16 // =16
str x0, [sp, #8]
ldr x8, [sp, #8]
mov x0, x8
str x8, [sp] // 8-byte Folded Spill
bl Derived::~Derived() [base object destructor]
ldr x0, [sp] // 8-byte Folded Reload
bl operator delete(void*)
ldp x29, x30, [sp, #16] // 16-byte Folded Reload
add sp, sp, #32 // =32
ret
Derived::wrong(): // @Derived::wrong()
sub sp, sp, #16 // =16
str x0, [sp, #8]
add sp, sp, #16 // =16
ret
vtable for Base:
.xword 0
.xword typeinfo for Base
.xword _ZN4BaseD1Ev
.xword Base::~Base() [deleting destructor]
.xword __cxa_pure_virtual
typeinfo name for Base:
.asciz "4Base"
typeinfo for Base:
.xword _ZTVN10__cxxabiv117__class_type_infoE+16
.xword typeinfo name for Base
vtable for Derived:
.xword 0
.xword typeinfo for Derived
.xword Derived::~Derived() [base object destructor]
.xword Derived::~Derived() [deleting destructor]
.xword Derived::wrong()
typeinfo name for Derived:
.asciz "7Derived"
typeinfo for Derived:
.xword _ZTVN10__cxxabiv120__si_class_type_infoE+16
.xword typeinfo name for Derived
.xword typeinfo for Base
pure virtual function called 2