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 4 namespace 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 10 struct A { 11 void operator delete(void *); // expected-note {{member found by ambiguous name lookup}} 12 }; 13 14 struct B { 15 void operator delete(void *); // expected-note {{member found by ambiguous name lookup}} 16 }; 17 18 struct C : A, B { 19 ~C(); 20 }; 21 22 struct VC : A, B { 23 virtual ~VC(); // expected-error {{member 'operator delete' found in multiple base classes of different types}} 24 }; 25 26 void f(VC vc) { 27 // This marks VC's vtable used. 28 } 29 30 } 31 32 namespace 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. 38 class A { 39 private: 40 ~A(); 41 int a; 42 }; 43 44 struct 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 48 struct C { 49 ~C(); 50 int c; 51 }; 52 53 struct D { 54 // D has a non-trivial implicit dtor that destroys C. 55 C o; 56 }; 57 58 void foo(B b) { } // expected-error {{attempt to use a deleted function}} 59 void bar(A a) { } // no error; MSVC rejects this, but we skip the direct access check. 60 void baz(D d) { } // no error 61 62 } 63 64 #ifdef MSVC_ABI 65 namespace Test3 { 66 67 class A { 68 A(); 69 ~A(); // expected-note {{implicitly declared private here}} 70 friend void bar(A); 71 int a; 72 }; 73 74 void bar(A a) { } 75 void 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. 79 void foo(A *a) { 80 bar(*a); // expected-error {{temporary of type 'Test3::A' has private destructor}} 81 } 82 } 83 #endif 84 85 namespace Test4 { 86 // Don't try to access the dtor of an incomplete on a function declaration. 87 class A; 88 void foo(A a); 89 } 90 91 #ifdef MSVC_ABI 92 namespace Test5 { 93 // Do the operator delete access control check from the context of the dtor. 94 class A { 95 protected: 96 void operator delete(void *); 97 }; 98 class B : public A { 99 virtual ~B(); 100 }; 101 B *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 109 namespace Test6 { 110 class A { 111 protected: 112 void operator delete(void *); 113 }; 114 class B : public A { 115 virtual ~B(); 116 public: 117 virtual void m_fn1(); 118 }; 119 void fn1(B *b) { b->m_fn1(); } 120 } 121 122 namespace Test7 { 123 class A { 124 protected: 125 void operator delete(void *); 126 }; 127 struct B : public A { 128 virtual ~B(); 129 }; 130 void fn1(B b) {} 131 } 132