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(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