reference, declarationdefinition
definition → references, declarations, derived classes, virtual overrides
reference to multiple definitions → definitions
unreferenced
    1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113
  114
  115
  116
  117
  118
  119
  120
  121
  122
  123
  124
  125
  126
  127
  128
  129
  130
  131
  132
// RUN: %clang_cc1 -fexceptions -fcxx-exceptions -std=c++11 -triple %itanium_abi_triple -fsyntax-only %s
// RUN: %clang_cc1 -fexceptions -fcxx-exceptions -std=c++11 -triple %ms_abi_triple -verify %s

namespace Test1 {

// Should be accepted under the Itanium ABI (first RUN line) but rejected
// under the Microsoft ABI (second RUN line), as Microsoft ABI requires
// operator delete() lookups to be done when vtables are marked used.

struct A {
  void operator delete(void *); // expected-note {{member found by ambiguous name lookup}}
};

struct B {
  void operator delete(void *); // expected-note {{member found by ambiguous name lookup}}
};

struct C : A, B {
  ~C();
};

struct VC : A, B {
  virtual ~VC(); // expected-error {{member 'operator delete' found in multiple base classes of different types}}
};

void f() {
  // This marks VC's vtable used.
  VC vc;
}

}

namespace Test2 {

// In the MSVC ABI, functions must destroy their aggregate arguments.  foo
// requires a dtor for B, but we can't implicitly define it because ~A is
// private.  bar should be able to call A's private dtor without error, even
// though MSVC rejects bar.
class A {
private:
  ~A();
  int a;
};

struct B : public A { // expected-note {{destructor of 'B' is implicitly deleted because base class 'Test2::A' has an inaccessible destructor}}
  int b;
};

struct C {
  ~C();
  int c;
};

struct D {
  // D has a non-trivial implicit dtor that destroys C.
  C o;
};

void foo(B b) { } // expected-error {{attempt to use a deleted function}}
void bar(A a) { } // no error; MSVC rejects this, but we skip the direct access check.
void baz(D d) { } // no error

}

#ifdef MSVC_ABI
namespace Test3 {

class A {
  A();
  ~A(); // expected-note {{implicitly declared private here}}
  friend void bar(A);
  int a;
};

void bar(A a) { }
void baz(A a) { } // no error; MSVC rejects this, but the standard allows it.

// MSVC accepts foo() but we reject it for consistency with Itanium.  MSVC also
// rejects this if A has a copy ctor or if we call A's ctor.
void foo(A *a) {
  bar(*a); // expected-error {{temporary of type 'Test3::A' has private destructor}}
}
}
#endif

namespace Test4 {
// Don't try to access the dtor of an incomplete on a function declaration.
class A;
void foo(A a);
}

#ifdef MSVC_ABI
namespace Test5 {
// Do the operator delete access control check from the context of the dtor.
class A {
 protected:
  void operator delete(void *);
};
class B : public A {
  virtual ~B();
};
B *test() {
  // Previously, marking the vtable used here would do the operator delete
  // lookup from this context, which doesn't have access.
  return new B;
}
}
#endif

namespace Test6 {
class A {
protected:
  void operator delete(void *);
};
class B : public A {
  virtual ~B();
public:
  virtual void m_fn1();
};
void fn1(B *b) { b->m_fn1(); }
}

namespace Test7 {
class A {
protected:
  void operator delete(void *);
};
struct B : public A {
  virtual ~B();
};
void fn1(B b) {}
}