1 // RUN: %clang_cc1 -fsyntax-only -triple %itanium_abi_triple -verify -std=c++98 %s 2 // RUN: %clang_cc1 -fsyntax-only -triple %ms_abi_triple -DMSABI -verify -std=c++98 %s 3 // RUN: %clang_cc1 -fsyntax-only -triple %itanium_abi_triple -verify -std=c++11 %s 4 // RUN: %clang_cc1 -fsyntax-only -triple %ms_abi_triple -DMSABI -verify -std=c++11 %s 5 6 typedef __typeof(sizeof(int)) size_t; 7 8 // PR7803 9 namespace test0 { 10 class A { 11 public: operator delete(void * p)12 static void operator delete(void *p) {}; 13 virtual ~A(); 14 }; 15 16 class B : protected A { 17 public: 18 ~B(); 19 }; 20 21 class C : protected B { 22 public: 23 using B::operator delete; 24 ~C(); 25 }; 26 27 // Shouldn't have an error. ~C()28 C::~C() {} 29 } 30 31 namespace test1 { 32 class A { 33 public: operator delete(void * p)34 static void operator delete(void *p) {}; 35 virtual ~A(); 36 }; 37 38 class B : protected A { 39 public: operator delete(void *,size_t)40 static void operator delete(void *, size_t) {}; 41 ~B(); 42 }; 43 44 class C : protected B { 45 public: 46 using A::operator delete; 47 using B::operator delete; 48 49 ~C(); 50 }; 51 52 // We assume that the intent is to treat C::operator delete(void*, size_t) as 53 // /not/ being a usual deallocation function, as it would be if it were 54 // declared with in C directly. ~C()55 C::~C() {} 56 57 struct D { 58 void operator delete(void*); // expected-note {{member 'operator delete' declared here}} 59 void operator delete(void*, ...); // expected-note {{member 'operator delete' declared here}} 60 virtual ~D(); 61 }; 62 // FIXME: The standard doesn't say this is ill-formed, but presumably either 63 // it should be or the variadic operator delete should not be a usual 64 // deallocation function. ~D()65 D::~D() {} // expected-error {{multiple suitable 'operator delete' functions in 'D'}} 66 } 67 68 // ...at the point of definition of a virtual destructor... 69 namespace test2 { 70 struct A { 71 virtual ~A(); 72 static void operator delete(void*, const int &); 73 }; 74 75 struct B { 76 virtual ~B(); 77 static void operator delete(void*, const int &); // expected-note {{declared here}} 78 }; ~B()79 B::~B() {} // expected-error {{no suitable member 'operator delete' in 'B'}} 80 81 #if __cplusplus < 201103L 82 struct CBase { virtual ~CBase(); }; 83 struct C : CBase { // expected-error {{no suitable member 'operator delete' in 'C'}} 84 static void operator delete(void*, const int &); // expected-note {{declared here}} 85 }; test()86 void test() { 87 C c; // expected-note {{first required here}} 88 } 89 #else 90 struct CBase { virtual ~CBase(); }; // expected-note {{overridden virtual function is here}} 91 struct C : CBase { // expected-error {{deleted function '~C' cannot override a non-deleted function}} expected-note 2{{requires an unambiguous, accessible 'operator delete'}} 92 static void operator delete(void*, const int &); 93 }; test()94 void test() { 95 C c; // expected-error {{attempt to use a deleted function}} 96 } 97 #endif 98 } 99 100 // PR7346 101 namespace test3 { 102 struct A { 103 #ifdef MSABI 104 // expected-error@+2 {{no suitable member 'operator delete' in 'A'}} 105 #endif 106 virtual ~A(); 107 #ifdef MSABI 108 // expected-note@+2 {{declared here}} 109 #endif 110 static void operator delete(void*, const int &); 111 }; 112 113 struct B : A { ~Btest3::B114 virtual ~B() {} 115 static void operator delete(void*); 116 }; 117 f()118 void f() { 119 #ifdef MSABI 120 // expected-note@+2 {{implicit default constructor for 'test3::B' first required here}} 121 #endif 122 B use_vtable; 123 } 124 } 125