164dbcca6SVitaly Buka // RUN: %clangxx_msan %s -O0 -fsanitize-memory-use-after-dtor -o %t && %run %t 264dbcca6SVitaly Buka // RUN: %clangxx_msan %s -O1 -fsanitize-memory-use-after-dtor -o %t && %run %t 364dbcca6SVitaly Buka // RUN: %clangxx_msan %s -O2 -fsanitize-memory-use-after-dtor -o %t && %run %t 464dbcca6SVitaly Buka // RUN: %clangxx_msan %s -DCVPTR=1 -O2 -fsanitize-memory-use-after-dtor -fsanitize-memory-track-origins -o %t && not %run %t 2>&1 | FileCheck %s --check-prefixes=CVPTR 564dbcca6SVitaly Buka // RUN: %clangxx_msan %s -DEAVPTR=1 -O2 -fsanitize-memory-use-after-dtor -fsanitize-memory-track-origins -o %t && not %run %t 2>&1 | FileCheck %s --check-prefixes=EAVPTR 664dbcca6SVitaly Buka // RUN: %clangxx_msan %s -DEDVPTR=1 -O2 -fsanitize-memory-use-after-dtor -fsanitize-memory-track-origins -o %t && not %run %t 2>&1 | FileCheck %s --check-prefixes=EDVPTR 7d21b3d34SFangrui Song 8d21b3d34SFangrui Song // Expected to quit due to invalid access when invoking 9d21b3d34SFangrui Song // function using vtable. 10d21b3d34SFangrui Song 11d21b3d34SFangrui Song class A { 12d21b3d34SFangrui Song public: 13d21b3d34SFangrui Song int x; ~A()14d21b3d34SFangrui Song virtual ~A() { 15d21b3d34SFangrui Song // Should succeed 16d21b3d34SFangrui Song this->A_Foo(); 17d21b3d34SFangrui Song } A_Foo()18d21b3d34SFangrui Song virtual void A_Foo() {} 19d21b3d34SFangrui Song }; 20d21b3d34SFangrui Song 21d21b3d34SFangrui Song class B : public virtual A { 22d21b3d34SFangrui Song public: 23d21b3d34SFangrui Song int y; ~B()24d21b3d34SFangrui Song virtual ~B() {} A_Foo()25d21b3d34SFangrui Song virtual void A_Foo() {} 26d21b3d34SFangrui Song }; 27d21b3d34SFangrui Song 28d21b3d34SFangrui Song class C : public B { 29d21b3d34SFangrui Song public: 30d21b3d34SFangrui Song int z; 31d21b3d34SFangrui Song }; 32d21b3d34SFangrui Song 33d21b3d34SFangrui Song class D { 34d21b3d34SFangrui Song public: 35d21b3d34SFangrui Song int w; ~D()36d21b3d34SFangrui Song ~D() {} D_Foo()37d21b3d34SFangrui Song virtual void D_Foo() {} 38d21b3d34SFangrui Song }; 39d21b3d34SFangrui Song 40d21b3d34SFangrui Song class E : public virtual A, public virtual D { 41d21b3d34SFangrui Song public: 42d21b3d34SFangrui Song int u; ~E()43d21b3d34SFangrui Song ~E() {} A_Foo()44d21b3d34SFangrui Song void A_Foo() {} 45d21b3d34SFangrui Song }; 46d21b3d34SFangrui Song main()47d21b3d34SFangrui Songint main() { 48d21b3d34SFangrui Song // Simple linear inheritance 49d21b3d34SFangrui Song C *c = new C(); 50d21b3d34SFangrui Song c->~C(); 51d21b3d34SFangrui Song // This fails 52d21b3d34SFangrui Song #ifdef CVPTR 53d21b3d34SFangrui Song c->A_Foo(); 54*c059ede2SVitaly Buka // CVPTR: Virtual table ptr was destroyed 55*c059ede2SVitaly Buka // CVPTR: {{#0 0x.* in __sanitizer_dtor_callback_vptr}} 5664dbcca6SVitaly Buka // CVPTR: {{#1 0x.* in ~C .*cpp:}}[[@LINE-28]]: 5764dbcca6SVitaly Buka // CVPTR: {{#2 0x.* in main .*cpp:}}[[@LINE-7]]: 58d21b3d34SFangrui Song #endif 59d21b3d34SFangrui Song 60d21b3d34SFangrui Song // Multiple inheritance, so has multiple vtables 61d21b3d34SFangrui Song E *e = new E(); 62d21b3d34SFangrui Song e->~E(); 63d21b3d34SFangrui Song // Both of these fail 64d21b3d34SFangrui Song #ifdef EAVPTR 65d21b3d34SFangrui Song e->A_Foo(); 66*c059ede2SVitaly Buka // EAVPTR: Virtual table ptr was destroyed 67*c059ede2SVitaly Buka // EAVPTR: {{#0 0x.* in __sanitizer_dtor_callback_vptr}} 6864dbcca6SVitaly Buka // EAVPTR: {{#1 0x.* in ~E .*cpp:}}[[@LINE-25]]: 6964dbcca6SVitaly Buka // EAVPTR: {{#2 0x.* in main .*cpp:}}[[@LINE-7]]: 70d21b3d34SFangrui Song #endif 7164dbcca6SVitaly Buka 72d21b3d34SFangrui Song #ifdef EDVPTR 73d21b3d34SFangrui Song e->D_Foo(); 74*c059ede2SVitaly Buka // EDVPTR: Virtual table ptr was destroyed 75*c059ede2SVitaly Buka // EDVPTR: {{#0 0x.* in __sanitizer_dtor_callback_vptr}} 7664dbcca6SVitaly Buka // EDVPTR: {{#1 0x.* in ~E .*cpp:}}[[@LINE-33]]: 7764dbcca6SVitaly Buka // EDVPTR: {{#2 0x.* in main .*cpp:}}[[@LINE-15]]: 78d21b3d34SFangrui Song #endif 79d21b3d34SFangrui Song } 80