1// RUN: %clang_cc1 -fexceptions -fcxx-exceptions -std=c++11 -triple %itanium_abi_triple -fsyntax-only %s
2// RUN: %clang_cc1 -fexceptions -fcxx-exceptions -std=c++11 -triple %ms_abi_triple -verify %s
3
4namespace Test1 {
5
6// Should be accepted under the Itanium ABI (first RUN line) but rejected
7// under the Microsoft ABI (second RUN line), as Microsoft ABI requires
8// operator delete() lookups to be done when vtables are marked used.
9
10struct A {
11  void operator delete(void *); // expected-note {{member found by ambiguous name lookup}}
12};
13
14struct B {
15  void operator delete(void *); // expected-note {{member found by ambiguous name lookup}}
16};
17
18struct C : A, B {
19  ~C();
20};
21
22struct VC : A, B {
23  virtual ~VC(); // expected-error {{member 'operator delete' found in multiple base classes of different types}}
24};
25
26void f(VC vc) {
27  // This marks VC's vtable used.
28}
29
30}
31
32namespace Test2 {
33
34// In the MSVC ABI, functions must destroy their aggregate arguments.  foo
35// requires a dtor for B, but we can't implicitly define it because ~A is
36// private.  bar should be able to call A's private dtor without error, even
37// though MSVC rejects bar.
38class A {
39private:
40  ~A();
41  int a;
42};
43
44struct B : public A { // expected-note {{destructor of 'B' is implicitly deleted because base class 'Test2::A' has an inaccessible destructor}}
45  int b;
46};
47
48struct C {
49  ~C();
50  int c;
51};
52
53struct D {
54  // D has a non-trivial implicit dtor that destroys C.
55  C o;
56};
57
58void foo(B b) { } // expected-error {{attempt to use a deleted function}}
59void bar(A a) { } // no error; MSVC rejects this, but we skip the direct access check.
60void baz(D d) { } // no error
61
62}
63
64#ifdef MSVC_ABI
65namespace Test3 {
66
67class A {
68  A();
69  ~A(); // expected-note {{implicitly declared private here}}
70  friend void bar(A);
71  int a;
72};
73
74void bar(A a) { }
75void baz(A a) { } // no error; MSVC rejects this, but the standard allows it.
76
77// MSVC accepts foo() but we reject it for consistency with Itanium.  MSVC also
78// rejects this if A has a copy ctor or if we call A's ctor.
79void foo(A *a) {
80  bar(*a); // expected-error {{temporary of type 'Test3::A' has private destructor}}
81}
82}
83#endif
84
85namespace Test4 {
86// Don't try to access the dtor of an incomplete on a function declaration.
87class A;
88void foo(A a);
89}
90
91#ifdef MSVC_ABI
92namespace Test5 {
93// Do the operator delete access control check from the context of the dtor.
94class A {
95 protected:
96  void operator delete(void *);
97};
98class B : public A {
99  virtual ~B();
100};
101B *test() {
102  // Previously, marking the vtable used here would do the operator delete
103  // lookup from this context, which doesn't have access.
104  return new B;
105}
106}
107#endif
108
109namespace Test6 {
110class A {
111protected:
112  void operator delete(void *);
113};
114class B : public A {
115  virtual ~B();
116public:
117  virtual void m_fn1();
118};
119void fn1(B *b) { b->m_fn1(); }
120}
121
122namespace Test7 {
123class A {
124protected:
125  void operator delete(void *);
126};
127struct B : public A {
128  virtual ~B();
129};
130void fn1(B b) {}
131}
132