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() { 27 // This marks VC's vtable used. 28 VC vc; 29} 30 31} 32 33namespace Test2 { 34 35// In the MSVC ABI, functions must destroy their aggregate arguments. foo 36// requires a dtor for B, but we can't implicitly define it because ~A is 37// private. bar should be able to call A's private dtor without error, even 38// though MSVC rejects bar. 39class A { 40private: 41 ~A(); 42 int a; 43}; 44 45struct B : public A { // expected-note {{destructor of 'B' is implicitly deleted because base class 'Test2::A' has an inaccessible destructor}} 46 int b; 47}; 48 49struct C { 50 ~C(); 51 int c; 52}; 53 54struct D { 55 // D has a non-trivial implicit dtor that destroys C. 56 C o; 57}; 58 59void foo(B b) { } // expected-error {{attempt to use a deleted function}} 60void bar(A a) { } // no error; MSVC rejects this, but we skip the direct access check. 61void baz(D d) { } // no error 62 63} 64 65#ifdef MSVC_ABI 66namespace Test3 { 67 68class A { 69 A(); 70 ~A(); // expected-note {{implicitly declared private here}} 71 friend void bar(A); 72 int a; 73}; 74 75void bar(A a) { } 76void baz(A a) { } // no error; MSVC rejects this, but the standard allows it. 77 78// MSVC accepts foo() but we reject it for consistency with Itanium. MSVC also 79// rejects this if A has a copy ctor or if we call A's ctor. 80void foo(A *a) { 81 bar(*a); // expected-error {{temporary of type 'Test3::A' has private destructor}} 82} 83} 84#endif 85 86namespace Test4 { 87// Don't try to access the dtor of an incomplete on a function declaration. 88class A; 89void foo(A a); 90} 91 92#ifdef MSVC_ABI 93namespace Test5 { 94// Do the operator delete access control check from the context of the dtor. 95class A { 96 protected: 97 void operator delete(void *); 98}; 99class B : public A { 100 virtual ~B(); 101}; 102B *test() { 103 // Previously, marking the vtable used here would do the operator delete 104 // lookup from this context, which doesn't have access. 105 return new B; 106} 107} 108#endif 109 110namespace Test6 { 111class A { 112protected: 113 void operator delete(void *); 114}; 115class B : public A { 116 virtual ~B(); 117public: 118 virtual void m_fn1(); 119}; 120void fn1(B *b) { b->m_fn1(); } 121} 122 123namespace Test7 { 124class A { 125protected: 126 void operator delete(void *); 127}; 128struct B : public A { 129 virtual ~B(); 130}; 131void fn1(B b) {} 132} 133