1 // RUN: %clang_cc1 -std=c++17 -verify -Wno-defaulted-function-deleted %s -triple x86_64-windows-msvc 2 3 // MSVC emits the complete destructor as if it were its own special member. 4 // Clang attempts to do the same. This affects the diagnostics clang emits, 5 // because deleting a type with a user declared constructor implicitly 6 // references the destructors of virtual bases, which might be deleted or access 7 // controlled. 8 9 namespace t1 { 10 struct A { 11 ~A() = delete; // expected-note {{deleted here}} 12 }; 13 struct B { 14 B() = default; 15 A o; // expected-note {{destructor of 'B' is implicitly deleted because field 'o' has a deleted destructor}} 16 }; 17 struct C : virtual B { 18 ~C(); // expected-error {{attempt to use a deleted function}} 19 }; 20 void delete1(C *p) { delete p; } // expected-note {{in implicit destructor for 't1::C' first required here}} 21 void delete2(C *p) { delete p; } 22 } 23 24 namespace t2 { 25 struct A { 26 private: 27 ~A(); 28 }; 29 struct B { 30 B() = default; 31 A o; // expected-note {{destructor of 'B' is implicitly deleted because field 'o' has an inaccessible destructor}} 32 }; 33 struct C : virtual B { 34 ~C(); // expected-error {{attempt to use a deleted function}} 35 }; 36 void useCompleteDtor(C *p) { delete p; } // expected-note {{in implicit destructor for 't2::C' first required here}} 37 } 38 39 namespace t3 { 40 template <unsigned N> 41 class Base { ~Base(); }; // expected-note 1{{declared private here}} 42 // No diagnostic. 43 class Derived0 : virtual Base<0> { ~Derived0(); }; 44 class Derived1 : virtual Base<1> {}; 45 // Emitting complete dtor causes a diagnostic. 46 struct Derived2 : // expected-error {{inherited virtual base class 'Base<2>' has private destructor}} 47 virtual Base<2> { 48 ~Derived2(); 49 }; 50 void useCompleteDtor(Derived2 *p) { delete p; } // expected-note {{in implicit destructor for 't3::Derived2' first required here}} 51 } 52