153851923SRichard Smith // RUN: %clang_cc1 -fsyntax-only -triple %itanium_abi_triple -verify -std=c++98 %s 253851923SRichard Smith // RUN: %clang_cc1 -fsyntax-only -triple %ms_abi_triple -DMSABI -verify -std=c++98 %s 353851923SRichard Smith // RUN: %clang_cc1 -fsyntax-only -triple %itanium_abi_triple -verify -std=c++11 %s 453851923SRichard Smith // RUN: %clang_cc1 -fsyntax-only -triple %ms_abi_triple -DMSABI -verify -std=c++11 %s 566a87594SJohn McCall 653851923SRichard Smith typedef __typeof(sizeof(int)) size_t; 766a87594SJohn McCall 866a87594SJohn McCall // PR7803 966a87594SJohn McCall namespace test0 { 1066a87594SJohn McCall class A { 1166a87594SJohn McCall public: operator delete(void * p)1266a87594SJohn McCall static void operator delete(void *p) {}; 1366a87594SJohn McCall virtual ~A(); 1466a87594SJohn McCall }; 1566a87594SJohn McCall 1666a87594SJohn McCall class B : protected A { 1766a87594SJohn McCall public: 1866a87594SJohn McCall ~B(); 1966a87594SJohn McCall }; 2066a87594SJohn McCall 2166a87594SJohn McCall class C : protected B { 2266a87594SJohn McCall public: 2366a87594SJohn McCall using B::operator delete; 2466a87594SJohn McCall ~C(); 2566a87594SJohn McCall }; 2666a87594SJohn McCall 2766a87594SJohn McCall // Shouldn't have an error. ~C()2866a87594SJohn McCall C::~C() {} 2966a87594SJohn McCall } 3066a87594SJohn McCall 3166a87594SJohn McCall namespace test1 { 3266a87594SJohn McCall class A { 3366a87594SJohn McCall public: operator delete(void * p)34b2f0f057SRichard Smith static void operator delete(void *p) {}; 3566a87594SJohn McCall virtual ~A(); 3666a87594SJohn McCall }; 3766a87594SJohn McCall 3866a87594SJohn McCall class B : protected A { 3966a87594SJohn McCall public: operator delete(void *,size_t)40b2f0f057SRichard Smith static void operator delete(void *, size_t) {}; 4166a87594SJohn McCall ~B(); 4266a87594SJohn McCall }; 4366a87594SJohn McCall 4466a87594SJohn McCall class C : protected B { 4566a87594SJohn McCall public: 4666a87594SJohn McCall using A::operator delete; 4766a87594SJohn McCall using B::operator delete; 4866a87594SJohn McCall 49deb646ebSJohn McCall ~C(); 5066a87594SJohn McCall }; 51deb646ebSJohn McCall 52b2f0f057SRichard Smith // We assume that the intent is to treat C::operator delete(void*, size_t) as 53b2f0f057SRichard Smith // /not/ being a usual deallocation function, as it would be if it were 54b2f0f057SRichard Smith // declared with in C directly. ~C()55b2f0f057SRichard Smith C::~C() {} 56b2f0f057SRichard Smith 57b2f0f057SRichard Smith struct D { 58b2f0f057SRichard Smith void operator delete(void*); // expected-note {{member 'operator delete' declared here}} 59b2f0f057SRichard Smith void operator delete(void*, ...); // expected-note {{member 'operator delete' declared here}} 60b2f0f057SRichard Smith virtual ~D(); 61b2f0f057SRichard Smith }; 62b2f0f057SRichard Smith // FIXME: The standard doesn't say this is ill-formed, but presumably either 63b2f0f057SRichard Smith // it should be or the variadic operator delete should not be a usual 64b2f0f057SRichard Smith // deallocation function. ~D()65b2f0f057SRichard Smith D::~D() {} // expected-error {{multiple suitable 'operator delete' functions in 'D'}} 66deb646ebSJohn McCall } 67deb646ebSJohn McCall 68deb646ebSJohn McCall // ...at the point of definition of a virtual destructor... 69deb646ebSJohn McCall namespace test2 { 70deb646ebSJohn McCall struct A { 71deb646ebSJohn McCall virtual ~A(); 72deb646ebSJohn McCall static void operator delete(void*, const int &); 73deb646ebSJohn McCall }; 74deb646ebSJohn McCall 75deb646ebSJohn McCall struct B { 76deb646ebSJohn McCall virtual ~B(); 77deb646ebSJohn McCall static void operator delete(void*, const int &); // expected-note {{declared here}} 78deb646ebSJohn McCall }; ~B()79deb646ebSJohn McCall B::~B() {} // expected-error {{no suitable member 'operator delete' in 'B'}} 80deb646ebSJohn McCall 8153851923SRichard Smith #if __cplusplus < 201103L 82deb646ebSJohn McCall struct CBase { virtual ~CBase(); }; 83deb646ebSJohn McCall struct C : CBase { // expected-error {{no suitable member 'operator delete' in 'C'}} 84deb646ebSJohn McCall static void operator delete(void*, const int &); // expected-note {{declared here}} 85deb646ebSJohn McCall }; test()86deb646ebSJohn McCall void test() { 87deb646ebSJohn McCall C c; // expected-note {{first required here}} 88deb646ebSJohn McCall } 8953851923SRichard Smith #else 9053851923SRichard Smith struct CBase { virtual ~CBase(); }; // expected-note {{overridden virtual function is here}} 91*f3cec65dSRichard Smith struct C : CBase { // expected-error {{deleted function '~C' cannot override a non-deleted function}} expected-note 2{{requires an unambiguous, accessible 'operator delete'}} 9253851923SRichard Smith static void operator delete(void*, const int &); 9353851923SRichard Smith }; test()9453851923SRichard Smith void test() { 9553851923SRichard Smith C c; // expected-error {{attempt to use a deleted function}} 9653851923SRichard Smith } 9753851923SRichard Smith #endif 9866a87594SJohn McCall } 993faf1cf3SJohn McCall 1003faf1cf3SJohn McCall // PR7346 1013faf1cf3SJohn McCall namespace test3 { 1023faf1cf3SJohn McCall struct A { 1039125b08bSHans Wennborg #ifdef MSABI 1049125b08bSHans Wennborg // expected-error@+2 {{no suitable member 'operator delete' in 'A'}} 1059125b08bSHans Wennborg #endif 1063faf1cf3SJohn McCall virtual ~A(); 1079125b08bSHans Wennborg #ifdef MSABI 1089125b08bSHans Wennborg // expected-note@+2 {{declared here}} 1099125b08bSHans Wennborg #endif 1103faf1cf3SJohn McCall static void operator delete(void*, const int &); 1113faf1cf3SJohn McCall }; 1123faf1cf3SJohn McCall 1133faf1cf3SJohn McCall struct B : A { ~Btest3::B1143faf1cf3SJohn McCall virtual ~B() {} 1153faf1cf3SJohn McCall static void operator delete(void*); 1163faf1cf3SJohn McCall }; 117b3a9978dSNico Weber f()118b3a9978dSNico Weber void f() { 119b3a9978dSNico Weber #ifdef MSABI 120b3a9978dSNico Weber // expected-note@+2 {{implicit default constructor for 'test3::B' first required here}} 121b3a9978dSNico Weber #endif 122b3a9978dSNico Weber B use_vtable; 123b3a9978dSNico Weber } 1243faf1cf3SJohn McCall } 125