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