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