pure virtual function called 2


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
posted @ 2021-06-23 19:35  fndefbwefsowpvqfx  阅读(68)  评论(0编辑  收藏  举报