133 lines · cpp
1// RUN: %clang_cc1 -fexceptions -fcxx-exceptions -std=c++11 -triple %itanium_abi_triple -fsyntax-only %s2// RUN: %clang_cc1 -fexceptions -fcxx-exceptions -std=c++11 -triple %ms_abi_triple -verify %s3 4namespace Test1 {5 6// Should be accepted under the Itanium ABI (first RUN line) but rejected7// under the Microsoft ABI (second RUN line), as Microsoft ABI requires8// 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. foo36// requires a dtor for B, but we can't implicitly define it because ~A is37// private. bar should be able to call A's private dtor without error, even38// 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 '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 error62 63}64 65#ifdef MSVC_ABI66namespace 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 also79// 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#endif85 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_ABI93namespace 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 delete104 // lookup from this context, which doesn't have access.105 return new B;106}107}108#endif109 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