pure virtual method called

#include <iostream>
class Base
{
public:
    Base() { foo(); }
    void foo() { wrong(); }
    virtual void wrong() = 0;
};

void Base::wrong()
{
    std::cout << "base impl wrong" << std::endl;
}

class Derived : public Base
{
    void wrong() {
        std::cout << "derived impl wrong" << std::endl;
    }
};

int main(void)
{
    {
        Derived d;  // "pure virtual method called"  "pure virtual function call"
    }
    int i = 1;
    std::cout << "hello" << std::endl;
    return 0;
}
/*{
	"owner": "_generated_diagnostic_collection_name_#5",
	"code": "clang-analyzer-cplusplus.PureVirtualCall",
	"severity": 4,
	"message": "Call to pure virtual method 'Base::wrong' during construction has undefined behavior",
	"source": "clang-tidy",
	"startLineNumber": 6,
	"startColumn": 5,
	"endLineNumber": 6,
	"endColumn": 1.7976931348623157e+308
}*/

When a virtual function is called
    directly or indirectly
    from
    a constructor or from a destructor,including during the construction or destruction of the class’s non-static data members,
and
the object to which the call applies is the object (call it x) under construction or destruction,

the function called is the final overrider in the constructor’s or destructor’s class and not one overriding it in a more-derived class.
-------------------------------------------------
If the virtual function call uses an explicit class member access (7.6.1.4)
and
the object expression refers to the complete object of x or one of that object’s base class subobjects but not x or one of its base class subobjects, 

the behavior is undefined.
#include<iostream>
using namespace std;
struct V {
    virtual void f(){cout<<"V f"<<endl;}
    virtual void g(){cout<<"V g"<<endl;}
};

struct A : virtual V {
    virtual void f(){cout<<"A f"<<endl;}
};

struct B : virtual V {
    virtual void g(){cout<<"B g"<<endl;}
    B(V*, A*);
};

struct D : A, B {
    virtual void f(){cout<<"D f"<<endl;}
    virtual void g(){cout<<"D g"<<endl;}
    D() : B((A*)this, this) { }
};

B::B(V* v, A* a) {
    f(); // calls V::f, not A::f
    g(); // calls B::g, not D::g
    v->g(); // v is base of B, the call is well-defined, calls B::g
    a->f(); // undefined behavior: a’s type not a base of B
}

int main(){
    {
        D d;
    }
    return 0;
}

/*
gcc 11.1 c++20
clang 5.0 c++17
msvc 19
*/
//输出结果均为:
/*
V f
B g
B g
V f
*/
#include <iostream>
using namespace std;

char pool[256];

struct Base
{
    virtual void foo() = 0;
    virtual ~Base(){};
};

struct Derived: public Base
{
    virtual void foo() override { cout <<"Derived::foo()" << endl;}
};

int main()
{
    auto* pd = new (pool) Derived();
    Base* pb = pd;
    pd->~Derived();
    pb->foo();
    return 0;
}

armv7-a clang 11.0.1

main:
        push    {r11, lr}
        mov     r11, sp
        sub     sp, sp, #24
        mov     r0, #0
        str     r0, [r11, #-4]
        ldr     r1, .LCPI1_0
        strb    r0, [r1, #3]
        strb    r0, [r1, #2]
        strb    r0, [r1, #1]
        strb    r0, [r1]
        str     r0, [sp, #8]                    @ 4-byte Spill
        mov     r0, r1
        str     r1, [sp, #4]                    @ 4-byte Spill
        bl      Derived::Derived() [base object constructor]
        ldr     r0, [sp, #4]                    @ 4-byte Reload
        str     r0, [r11, #-8]
        ldr     r1, [r11, #-8]
        str     r1, [sp, #12]
        ldr     r1, [r11, #-8]
        ldr     r2, [r1]
        ldr     r2, [r2, #4]
        mov     r0, r1
        mov     lr, pc
        bx      r2
        ldr     r1, [sp, #12]
        ldr     r2, [r1]
        ldr     r2, [r2]
        str     r0, [sp]                        @ 4-byte Spill
        mov     r0, r1
        mov     lr, pc
        bx      r2
        ldr     r0, [sp, #8]                    @ 4-byte Reload
        mov     sp, r11
        pop     {r11, lr}
        bx      lr
.LCPI1_0:
        .long   pool
Derived::Derived() [base object constructor]:
        push    {r11, lr}
        mov     r11, sp
        sub     sp, sp, #8
        str     r0, [sp, #4]
        ldr     r0, [sp, #4]
        str     r0, [sp]                        @ 4-byte Spill
        bl      Base::Base() [base object constructor]
        ldr     r0, .LCPI2_0
        add     r0, r0, #8
        ldr     r1, [sp]                        @ 4-byte Reload
        str     r0, [r1]
        mov     r0, r1
        mov     sp, r11
        pop     {r11, lr}
        bx      lr
.LCPI2_0:
        .long   vtable for Derived
Base::Base() [base object constructor]:
        sub     sp, sp, #4
        str     r0, [sp]
        ldr     r0, [sp]
        ldr     r1, .LCPI3_0
        add     r1, r1, #8
        str     r1, [r0]
        add     sp, sp, #4
        bx      lr
.LCPI3_0:
        .long   vtable for Base
Derived::foo():
        push    {r11, lr}
        mov     r11, sp
        sub     sp, sp, #8
        str     r0, [sp, #4]
        ldr     r0, .LCPI4_0
        ldr     r1, .LCPI4_1
        bl      std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)
        ldr     r1, .LCPI4_2
        bl      std::basic_ostream<char, std::char_traits<char> >::operator<<(std::basic_ostream<char, std::char_traits<char> >& (*)(std::basic_ostream<char, std::char_traits<char> >&))
        mov     sp, r11
        pop     {r11, lr}
        bx      lr
.LCPI4_0:
        .long   _ZSt4cout
.LCPI4_1:
        .long   .L.str
.LCPI4_2:
        .long   _ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_
Derived::~Derived() [base object destructor]:
        push    {r11, lr}
        mov     r11, sp
        sub     sp, sp, #8
        str     r0, [sp, #4]
        ldr     r0, [sp, #4]
        str     r0, [sp]                        @ 4-byte Spill
        bl      Base::~Base() [base object destructor]
        ldr     r0, [sp]                        @ 4-byte Reload
        mov     sp, r11
        pop     {r11, lr}
        bx      lr
Derived::~Derived() [deleting destructor]:
        push    {r11, lr}
        mov     r11, sp
        sub     sp, sp, #8
        str     r0, [sp, #4]
        ldr     r0, [sp, #4]
        str     r0, [sp]                        @ 4-byte Spill
        bl      Derived::~Derived() [base object destructor]
        ldr     r0, [sp]                        @ 4-byte Reload
        bl      operator delete(void*)
        mov     sp, r11
        pop     {r11, lr}
        bx      lr
Base::~Base() [base object destructor]:
        sub     sp, sp, #4
        str     r0, [sp]
        ldr     r0, [sp]
        add     sp, sp, #4
        bx      lr
Base::~Base() [deleting destructor]:
        sub     sp, sp, #4
        str     r0, [sp]
        .inst   0xe7ffdefe
_GLOBAL__sub_I_example.cpp:
        push    {r11, lr}
        mov     r11, sp
        bl      __cxx_global_var_init
        pop     {r11, lr}
        bx      lr
pool:
        .zero   256

vtable for Derived:
        .long   0
        .long   typeinfo for Derived
        .long   Derived::foo()
        .long   Derived::~Derived() [base object destructor]
        .long   Derived::~Derived() [deleting destructor]

typeinfo name for Derived:
        .asciz  "7Derived"

typeinfo name for Base:
        .asciz  "4Base"

typeinfo for Base:
        .long   _ZTVN10__cxxabiv117__class_type_infoE+8
        .long   typeinfo name for Base

typeinfo for Derived:
        .long   _ZTVN10__cxxabiv120__si_class_type_infoE+8
        .long   typeinfo name for Derived
        .long   typeinfo for Base

vtable for Base:
        .long   0
        .long   typeinfo for Base
        .long   __cxa_pure_virtual
        .long   Base::~Base() [base object destructor]
        .long   Base::~Base() [deleting destructor]

.L.str:
        .asciz  "Derived::foo()"

armv8-a clang 11.0.1

main:                                   // @main
        sub     sp, sp, #64                     // =64
        stp     x29, x30, [sp, #48]             // 16-byte Folded Spill
        add     x29, sp, #48                    // =48
        mov     w8, wzr
        stur    wzr, [x29, #-4]
        adrp    x9, pool
        add     x9, x9, :lo12:pool
        str     xzr, [x9]
        mov     x0, x9
        str     w8, [sp, #20]                   // 4-byte Folded Spill
        str     x9, [sp, #8]                    // 8-byte Folded Spill
        bl      Derived::Derived() [base object constructor]
        ldr     x9, [sp, #8]                    // 8-byte Folded Reload
        stur    x9, [x29, #-16]
        ldur    x10, [x29, #-16]
        str     x10, [sp, #24]
        ldur    x10, [x29, #-16]
        ldr     x11, [x10]
        ldr     x11, [x11, #8]
        mov     x0, x10
        blr     x11
        ldr     x9, [sp, #24]
        ldr     x10, [x9]
        ldr     x10, [x10]
        mov     x0, x9
        blr     x10
        ldr     w0, [sp, #20]                   // 4-byte Folded Reload
        ldp     x29, x30, [sp, #48]             // 16-byte Folded Reload
        add     sp, sp, #64                     // =64
        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
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::foo():                      // @Derived::foo()
        sub     sp, sp, #32                     // =32
        stp     x29, x30, [sp, #16]             // 16-byte Folded Spill
        add     x29, sp, #16                    // =16
        str     x0, [sp, #8]
        adrp    x0, _ZSt4cout
        add     x0, x0, :lo12:_ZSt4cout
        adrp    x1, .L.str
        add     x1, x1, :lo12:.L.str
        bl      std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)
        adrp    x1, _ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_
        add     x1, x1, :lo12:_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_
        bl      std::basic_ostream<char, std::char_traits<char> >::operator<<(std::basic_ostream<char, std::char_traits<char> >& (*)(std::basic_ostream<char, std::char_traits<char> >&))
        ldp     x29, x30, [sp, #16]             // 16-byte Folded Reload
        add     sp, sp, #32                     // =32
        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
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
Base::~Base() [base object destructor]:                           // @Base::~Base() [base object destructor]
        sub     sp, sp, #16                     // =16
        str     x0, [sp, #8]
        add     sp, sp, #16                     // =16
        ret
Base::~Base() [deleting destructor]:                           // @Base::~Base() [deleting destructor]
        sub     sp, sp, #16                     // =16
        str     x0, [sp, #8]
        brk     #0x1
_GLOBAL__sub_I_example.cpp:             // @_GLOBAL__sub_I_example.cpp
        stp     x29, x30, [sp, #-16]!           // 16-byte Folded Spill
        mov     x29, sp
        bl      __cxx_global_var_init
        ldp     x29, x30, [sp], #16             // 16-byte Folded Reload
        ret
pool:
        .zero   256

vtable for Derived:
        .xword  0
        .xword  typeinfo for Derived
        .xword  Derived::foo()
        .xword  Derived::~Derived() [base object destructor]
        .xword  Derived::~Derived() [deleting destructor]

typeinfo name for Derived:
        .asciz  "7Derived"

typeinfo name for Base:
        .asciz  "4Base"

typeinfo for Base:
        .xword  _ZTVN10__cxxabiv117__class_type_infoE+16
        .xword  typeinfo name for Base

typeinfo for Derived:
        .xword  _ZTVN10__cxxabiv120__si_class_type_infoE+16
        .xword  typeinfo name for Derived
        .xword  typeinfo for Base

vtable for Base:
        .xword  0
        .xword  typeinfo for Base
        .xword  __cxa_pure_virtual
        .xword  Base::~Base() [base object destructor]
        .xword  Base::~Base() [deleting destructor]

.L.str:
        .asciz  "Derived::foo()"

ARM64 gcc 11.1

pool:
        .zero   256
Base::~Base() [base object destructor]:
        sub     sp, sp, #16
        str     x0, [sp, 8]
        adrp    x0, vtable for Base+16
        add     x1, x0, :lo12:vtable for Base+16
        ldr     x0, [sp, 8]
        str     x1, [x0]
        nop
        add     sp, sp, 16
        ret
Base::~Base() [deleting destructor]:
        stp     x29, x30, [sp, -32]!
        mov     x29, sp
        str     x0, [sp, 24]
        ldr     x0, [sp, 24]
        bl      Base::~Base() [complete object destructor]
        mov     x1, 8
        ldr     x0, [sp, 24]
        bl      operator delete(void*, unsigned long)
        ldp     x29, x30, [sp], 32
        ret
.LC0:
        .string "Derived::foo()"
Derived::foo():
        stp     x29, x30, [sp, -32]!
        mov     x29, sp
        str     x0, [sp, 24]
        adrp    x0, .LC0
        add     x1, x0, :lo12:.LC0
        adrp    x0, _ZSt4cout
        add     x0, x0, :lo12:_ZSt4cout
        bl      std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)
        mov     x2, x0
        adrp    x0, _ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_
        add     x1, x0, :lo12:_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_
        mov     x0, x2
        bl      std::basic_ostream<char, std::char_traits<char> >::operator<<(std::basic_ostream<char, std::char_traits<char> >& (*)(std::basic_ostream<char, std::char_traits<char> >&))
        nop
        ldp     x29, x30, [sp], 32
        ret
Base::Base() [base object constructor]:
        sub     sp, sp, #16
        str     x0, [sp, 8]
        adrp    x0, vtable for Base+16
        add     x1, x0, :lo12:vtable for Base+16
        ldr     x0, [sp, 8]
        str     x1, [x0]
        nop
        add     sp, sp, 16
        ret
Derived::Derived() [base object constructor]:
        stp     x29, x30, [sp, -32]!
        mov     x29, sp
        str     x0, [sp, 24]
        ldr     x0, [sp, 24]
        bl      Base::Base() [base object constructor]
        adrp    x0, vtable for Derived+16
        add     x1, x0, :lo12:vtable for Derived+16
        ldr     x0, [sp, 24]
        str     x1, [x0]
        nop
        ldp     x29, x30, [sp], 32
        ret
main:
        stp     x29, x30, [sp, -48]!
        mov     x29, sp
        str     x19, [sp, 16]
        adrp    x0, pool
        add     x1, x0, :lo12:pool
        mov     x0, 8
        bl      operator new(unsigned long, void*)
        mov     x19, x0
        str     xzr, [x19]
        mov     x0, x19
        bl      Derived::Derived() [complete object constructor]
        str     x19, [sp, 40]
        ldr     x0, [sp, 40]
        str     x0, [sp, 32]
        ldr     x0, [sp, 40]
        ldr     x0, [x0]
        add     x0, x0, 8
        ldr     x1, [x0]
        ldr     x0, [sp, 40]
        blr     x1
        ldr     x0, [sp, 32]
        ldr     x0, [x0]
        ldr     x1, [x0]
        ldr     x0, [sp, 32]
        blr     x1
        mov     w0, 0
        ldr     x19, [sp, 16]
        ldp     x29, x30, [sp], 48
        ret
vtable for Derived:
        .xword  0
        .xword  typeinfo for Derived
        .xword  Derived::foo()
        .xword  Derived::~Derived() [complete object destructor]
        .xword  Derived::~Derived() [deleting destructor]
Derived::~Derived() [base object destructor]:
        stp     x29, x30, [sp, -32]!
        mov     x29, sp
        str     x0, [sp, 24]
        adrp    x0, vtable for Derived+16
        add     x1, x0, :lo12:vtable for Derived+16
        ldr     x0, [sp, 24]
        str     x1, [x0]
        ldr     x0, [sp, 24]
        bl      Base::~Base() [base object destructor]
        nop
        ldp     x29, x30, [sp], 32
        ret
Derived::~Derived() [deleting destructor]:
        stp     x29, x30, [sp, -32]!
        mov     x29, sp
        str     x0, [sp, 24]
        ldr     x0, [sp, 24]
        bl      Derived::~Derived() [complete object destructor]
        mov     x1, 8
        ldr     x0, [sp, 24]
        bl      operator delete(void*, unsigned long)
        ldp     x29, x30, [sp], 32
        ret
vtable for Base:
        .xword  0
        .xword  typeinfo for Base
        .xword  __cxa_pure_virtual
        .xword  0
        .xword  0
typeinfo for Derived:
        .xword  _ZTVN10__cxxabiv120__si_class_type_infoE+16
        .xword  typeinfo name for Derived
        .xword  typeinfo for Base
typeinfo name for Derived:
        .string "7Derived"
typeinfo for Base:
        .xword  _ZTVN10__cxxabiv117__class_type_infoE+16
        .xword  typeinfo name for Base
typeinfo name for Base:
        .string "4Base"
__static_initialization_and_destruction_0(int, int):
        stp     x29, x30, [sp, -32]!
        mov     x29, sp
        str     w0, [sp, 28]
        str     w1, [sp, 24]
        ldr     w0, [sp, 28]
        cmp     w0, 1
        bne     .L14
        ldr     w1, [sp, 24]
        mov     w0, 65535
        cmp     w1, w0
        bne     .L14
        adrp    x0, _ZStL8__ioinit
        add     x0, x0, :lo12:_ZStL8__ioinit
        bl      std::ios_base::Init::Init() [complete object constructor]
        adrp    x0, __dso_handle
        add     x2, x0, :lo12:__dso_handle
        adrp    x0, _ZStL8__ioinit
        add     x1, x0, :lo12:_ZStL8__ioinit
        adrp    x0, _ZNSt8ios_base4InitD1Ev
        add     x0, x0, :lo12:_ZNSt8ios_base4InitD1Ev
        bl      __cxa_atexit
.L14:
        nop
        ldp     x29, x30, [sp], 32
        ret
_GLOBAL__sub_I_pool:
        stp     x29, x30, [sp, -16]!
        mov     x29, sp
        mov     w1, 65535
        mov     w0, 1
        bl      __static_initialization_and_destruction_0(int, int)
        ldp     x29, x30, [sp], 16
        ret

x86-64 gcc 11.1

Program returned: 139
pure virtual method called
terminate c
pool:
        .zero   256
Base::~Base() [base object destructor]:
        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::~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
.LC0:
        .string "Derived::foo()"
Derived::foo():
        push    rbp
        mov     rbp, rsp
        sub     rsp, 16
        mov     QWORD PTR [rbp-8], rdi
        mov     esi, OFFSET FLAT:.LC0
        mov     edi, OFFSET FLAT:_ZSt4cout
        call    std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)
        mov     esi, OFFSET FLAT:_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_
        mov     rdi, rax
        call    std::basic_ostream<char, std::char_traits<char> >::operator<<(std::basic_ostream<char, std::char_traits<char> >& (*)(std::basic_ostream<char, std::char_traits<char> >&))
        nop
        leave
        ret
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
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
        push    rbx
        sub     rsp, 24
        mov     esi, OFFSET FLAT:pool
        mov     edi, 8
        call    operator new(unsigned long, void*)
        mov     rbx, rax
        mov     QWORD PTR [rbx], 0
        mov     rdi, rbx
        call    Derived::Derived() [complete object constructor]
        mov     QWORD PTR [rbp-24], rbx
        mov     rax, QWORD PTR [rbp-24]
        mov     QWORD PTR [rbp-32], rax
        mov     rax, QWORD PTR [rbp-24]
        mov     rax, QWORD PTR [rax]
        add     rax, 8
        mov     rdx, QWORD PTR [rax]
        mov     rax, QWORD PTR [rbp-24]
        mov     rdi, rax
        call    rdx
        mov     rax, QWORD PTR [rbp-32]
        mov     rax, QWORD PTR [rax]
        mov     rdx, QWORD PTR [rax]
        mov     rax, QWORD PTR [rbp-32]
        mov     rdi, rax
        call    rdx
        mov     eax, 0
        mov     rbx, QWORD PTR [rbp-8]
        leave
        ret
vtable for Derived:
        .quad   0
        .quad   typeinfo for Derived
        .quad   Derived::foo()
        .quad   Derived::~Derived() [complete object destructor]
        .quad   Derived::~Derived() [deleting destructor]
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
vtable for Base:
        .quad   0
        .quad   typeinfo for Base
        .quad   __cxa_pure_virtual
        .quad   0
        .quad   0
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"
__static_initialization_and_destruction_0(int, int):
        push    rbp
        mov     rbp, rsp
        sub     rsp, 16
        mov     DWORD PTR [rbp-4], edi
        mov     DWORD PTR [rbp-8], esi
        cmp     DWORD PTR [rbp-4], 1
        jne     .L14
        cmp     DWORD PTR [rbp-8], 65535
        jne     .L14
        mov     edi, OFFSET FLAT:_ZStL8__ioinit
        call    std::ios_base::Init::Init() [complete object constructor]
        mov     edx, OFFSET FLAT:__dso_handle
        mov     esi, OFFSET FLAT:_ZStL8__ioinit
        mov     edi, OFFSET FLAT:_ZNSt8ios_base4InitD1Ev
        call    __cxa_atexit
.L14:
        nop
        leave
        ret
_GLOBAL__sub_I_pool:
        push    rbp
        mov     rbp, rsp
        mov     esi, 65535
        mov     edi, 1
        call    __static_initialization_and_destruction_0(int, int)
        pop     rbp
        ret
原文地址:https://www.cnblogs.com/Searchor/p/14921535.html