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