blob: 412749f707ee4735be0e65b61eb6e12426c6ba7e [file] [log] [blame]
Reid Kleckner67130862014-06-12 22:39:12 +00001// 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
Reid Kleckner23f4c4b2013-06-21 12:45:15 +00003
4namespace Test1 {
Peter Collingbourneb289fe62013-05-20 14:12:25 +00005
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
Hans Wennborg3d791542014-02-24 15:58:24 +00008// operator delete() lookups to be done when vtables are marked used.
Peter Collingbourneb289fe62013-05-20 14:12:25 +00009
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};
Reid Kleckner23f4c4b2013-06-21 12:45:15 +000025
Hans Wennborg3d791542014-02-24 15:58:24 +000026void f(VC vc) {
27 // This marks VC's vtable used.
28}
29
Reid Kleckner23f4c4b2013-06-21 12:45:15 +000030}
31
32namespace 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.
Reid Kleckner23f4c4b2013-06-21 12:45:15 +000038class A {
39private:
Reid Kleckner67130862014-06-12 22:39:12 +000040 ~A();
Reid Kleckner23f4c4b2013-06-21 12:45:15 +000041 int a;
42};
43
Reid Kleckner67130862014-06-12 22:39:12 +000044struct B : public A { // expected-note {{destructor of 'B' is implicitly deleted because base class 'Test2::A' has an inaccessible destructor}}
Reid Kleckner23f4c4b2013-06-21 12:45:15 +000045 int b;
46};
47
48struct C {
49 ~C();
50 int c;
51};
52
53struct D {
54 // D has a non-trivial implicit dtor that destroys C.
55 C o;
56};
57
Reid Kleckner67130862014-06-12 22:39:12 +000058void foo(B b) { } // expected-error {{attempt to use a deleted function}}
Hans Wennborg0f3c10c2014-01-13 17:23:24 +000059void bar(A a) { } // no error; MSVC rejects this, but we skip the direct access check.
Reid Kleckner23f4c4b2013-06-21 12:45:15 +000060void baz(D d) { } // no error
61
62}
63
64#ifdef MSVC_ABI
65namespace Test3 {
66
67class A {
68 A();
Hans Wennborg0f3c10c2014-01-13 17:23:24 +000069 ~A(); // expected-note {{implicitly declared private here}}
Reid Kleckner23f4c4b2013-06-21 12:45:15 +000070 friend void bar(A);
71 int a;
72};
73
74void bar(A a) { }
Hans Wennborg0f3c10c2014-01-13 17:23:24 +000075void baz(A a) { } // no error; MSVC rejects this, but the standard allows it.
Reid Kleckner23f4c4b2013-06-21 12:45:15 +000076
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.
79void foo(A *a) {
80 bar(*a); // expected-error {{temporary of type 'Test3::A' has private destructor}}
81}
82}
83#endif
84
85namespace Test4 {
86// Don't try to access the dtor of an incomplete on a function declaration.
87class A;
88void foo(A a);
89}
Reid Kleckner67130862014-06-12 22:39:12 +000090
91#ifdef MSVC_ABI
92namespace Test5 {
93// Do the operator delete access control check from the context of the dtor.
94class A {
95 protected:
96 void operator delete(void *);
97};
98class B : public A {
99 virtual ~B();
100};
101B *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
109namespace Test6 {
110class A {
111protected:
112 void operator delete(void *);
113};
114class B : public A {
115 virtual ~B();
116public:
117 virtual void m_fn1();
118};
119void fn1(B *b) { b->m_fn1(); }
120}
121
122namespace Test7 {
123class A {
124protected:
125 void operator delete(void *);
126};
127struct B : public A {
128 virtual ~B();
129};
130void fn1(B b) {}
131}