1 // RUN: %clang_cc1 -fsyntax-only -verify %s
2 
3 typedef typeof(sizeof(int)) size_t;
4 
5 // PR7803
6 namespace test0 {
7   class A {
8   public:
9     static void operator delete(void *p) {};
10     virtual ~A();
11   };
12 
13   class B : protected A {
14   public:
15     ~B();
16   };
17 
18   class C : protected B {
19   public:
20     using B::operator delete;
21     ~C();
22   };
23 
24   // Shouldn't have an error.
25   C::~C() {}
26 }
27 
28 namespace test1 {
29   class A {
30   public:
31     static void operator delete(void *p) {}; // expected-note {{member 'operator delete' declared here}}
32     virtual ~A();
33   };
34 
35   class B : protected A {
36   public:
37     static void operator delete(void *, size_t) {}; // expected-note {{member 'operator delete' declared here}}
38     ~B();
39   };
40 
41   class C : protected B {
42   public:
43     using A::operator delete;
44     using B::operator delete;
45 
46     ~C();
47   };
48 
49   C::~C() {} // expected-error {{multiple suitable 'operator delete' functions in 'C'}}
50 }
51 
52 // ...at the point of definition of a virtual destructor...
53 namespace test2 {
54   struct A {
55     virtual ~A();
56     static void operator delete(void*, const int &);
57   };
58 
59   struct B {
60     virtual ~B();
61     static void operator delete(void*, const int &); // expected-note {{declared here}}
62   };
63   B::~B() {} // expected-error {{no suitable member 'operator delete' in 'B'}}
64 
65   struct CBase { virtual ~CBase(); };
66   struct C : CBase { // expected-error {{no suitable member 'operator delete' in 'C'}}
67     static void operator delete(void*, const int &); // expected-note {{declared here}}
68   };
69   void test() {
70     C c; // expected-note {{first required here}}
71   }
72 }
73 
74 // PR7346
75 namespace test3 {
76   struct A {
77     virtual ~A();
78     static void operator delete(void*, const int &);
79   };
80 
81   struct B : A {
82     virtual ~B() {}
83     static void operator delete(void*);
84   };
85 }
86