1*67e74705SXin Li // RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11 -Wabstract-vbase-init
2*67e74705SXin Li
3*67e74705SXin Li #ifndef __GXX_EXPERIMENTAL_CXX0X__
4*67e74705SXin Li #define __CONCAT(__X, __Y) __CONCAT1(__X, __Y)
5*67e74705SXin Li #define __CONCAT1(__X, __Y) __X ## __Y
6*67e74705SXin Li
7*67e74705SXin Li #define static_assert(__b, __m) \
8*67e74705SXin Li typedef int __CONCAT(__sa, __LINE__)[__b ? 1 : -1]
9*67e74705SXin Li #endif
10*67e74705SXin Li
11*67e74705SXin Li union IncompleteUnion;
12*67e74705SXin Li
13*67e74705SXin Li static_assert(!__is_abstract(IncompleteUnion), "unions are never abstract");
14*67e74705SXin Li
15*67e74705SXin Li class C {
16*67e74705SXin Li virtual void f() = 0; // expected-note {{unimplemented pure virtual method 'f'}}
17*67e74705SXin Li };
18*67e74705SXin Li
19*67e74705SXin Li static_assert(__is_abstract(C), "C has a pure virtual function");
20*67e74705SXin Li
21*67e74705SXin Li class D : C {
22*67e74705SXin Li };
23*67e74705SXin Li
24*67e74705SXin Li static_assert(__is_abstract(D), "D inherits from an abstract class");
25*67e74705SXin Li
26*67e74705SXin Li class E : D {
27*67e74705SXin Li virtual void f();
28*67e74705SXin Li };
29*67e74705SXin Li
30*67e74705SXin Li static_assert(!__is_abstract(E), "E inherits from an abstract class but implements f");
31*67e74705SXin Li
32*67e74705SXin Li C *d = new C; // expected-error {{allocating an object of abstract class type 'C'}}
33*67e74705SXin Li
34*67e74705SXin Li C c; // expected-error {{variable type 'C' is an abstract class}}
35*67e74705SXin Li void t1(C c); // expected-error {{parameter type 'C' is an abstract class}}
36*67e74705SXin Li void t2(C); // expected-error {{parameter type 'C' is an abstract class}}
37*67e74705SXin Li
38*67e74705SXin Li struct S {
39*67e74705SXin Li C c; // expected-error {{field type 'C' is an abstract class}}
40*67e74705SXin Li };
41*67e74705SXin Li
42*67e74705SXin Li void t3(const C&);
43*67e74705SXin Li
f()44*67e74705SXin Li void f() {
45*67e74705SXin Li C(); // expected-error {{allocating an object of abstract class type 'C'}}
46*67e74705SXin Li t3(C()); // expected-error {{allocating an object of abstract class type 'C'}}
47*67e74705SXin Li }
48*67e74705SXin Li
49*67e74705SXin Li C e1[2]; // expected-error {{array of abstract class type 'C'}}
50*67e74705SXin Li C (*e2)[2]; // expected-error {{array of abstract class type 'C'}}
51*67e74705SXin Li C (**e3)[2]; // expected-error {{array of abstract class type 'C'}}
52*67e74705SXin Li
53*67e74705SXin Li void t4(C c[2]); // expected-error {{array of abstract class type 'C'}}
54*67e74705SXin Li
55*67e74705SXin Li void t5(void (*)(C)); // expected-error {{parameter type 'C' is an abstract class}}
56*67e74705SXin Li
57*67e74705SXin Li typedef void (*Func)(C); // expected-error {{parameter type 'C' is an abstract class}}
58*67e74705SXin Li void t6(Func);
59*67e74705SXin Li
60*67e74705SXin Li class F {
a()61*67e74705SXin Li F a() { while (1) {} } // expected-error {{return type 'F' is an abstract class}}
62*67e74705SXin Li
63*67e74705SXin Li class D {
64*67e74705SXin Li void f(F c); // expected-error {{parameter type 'F' is an abstract class}}
65*67e74705SXin Li };
66*67e74705SXin Li
67*67e74705SXin Li union U {
68*67e74705SXin Li void u(F c); // expected-error {{parameter type 'F' is an abstract class}}
69*67e74705SXin Li };
70*67e74705SXin Li
71*67e74705SXin Li virtual void f() = 0; // expected-note {{unimplemented pure virtual method 'f'}}
72*67e74705SXin Li };
73*67e74705SXin Li
74*67e74705SXin Li // Diagnosing in these cases is prohibitively expensive. We still
75*67e74705SXin Li // diagnose at the function definition, of course.
76*67e74705SXin Li
77*67e74705SXin Li class Abstract;
78*67e74705SXin Li
79*67e74705SXin Li void t7(Abstract a);
80*67e74705SXin Li
t8()81*67e74705SXin Li void t8() {
82*67e74705SXin Li void h(Abstract a);
83*67e74705SXin Li }
84*67e74705SXin Li
85*67e74705SXin Li namespace N {
86*67e74705SXin Li void h(Abstract a);
87*67e74705SXin Li }
88*67e74705SXin Li
89*67e74705SXin Li class Abstract {
90*67e74705SXin Li virtual void f() = 0;
91*67e74705SXin Li };
92*67e74705SXin Li
93*67e74705SXin Li // <rdar://problem/6854087>
94*67e74705SXin Li class foo {
95*67e74705SXin Li public:
96*67e74705SXin Li virtual foo *getFoo() = 0;
97*67e74705SXin Li };
98*67e74705SXin Li
99*67e74705SXin Li class bar : public foo {
100*67e74705SXin Li public:
101*67e74705SXin Li virtual bar *getFoo();
102*67e74705SXin Li };
103*67e74705SXin Li
104*67e74705SXin Li bar x;
105*67e74705SXin Li
106*67e74705SXin Li // <rdar://problem/6902298>
107*67e74705SXin Li class A {
108*67e74705SXin Li public:
109*67e74705SXin Li virtual void release() = 0;
110*67e74705SXin Li virtual void release(int count) = 0;
111*67e74705SXin Li virtual void retain() = 0;
112*67e74705SXin Li };
113*67e74705SXin Li
114*67e74705SXin Li class B : public A {
115*67e74705SXin Li public:
116*67e74705SXin Li virtual void release();
117*67e74705SXin Li virtual void release(int count);
118*67e74705SXin Li virtual void retain();
119*67e74705SXin Li };
120*67e74705SXin Li
foo(void)121*67e74705SXin Li void foo(void) {
122*67e74705SXin Li B b;
123*67e74705SXin Li }
124*67e74705SXin Li
125*67e74705SXin Li struct K {
126*67e74705SXin Li int f;
127*67e74705SXin Li virtual ~K();
128*67e74705SXin Li };
129*67e74705SXin Li
130*67e74705SXin Li struct L : public K {
131*67e74705SXin Li void f();
132*67e74705SXin Li };
133*67e74705SXin Li
134*67e74705SXin Li // PR5222
135*67e74705SXin Li namespace PR5222 {
136*67e74705SXin Li struct A {
137*67e74705SXin Li virtual A *clone() = 0;
138*67e74705SXin Li };
139*67e74705SXin Li struct B : public A {
140*67e74705SXin Li virtual B *clone() = 0;
141*67e74705SXin Li };
142*67e74705SXin Li struct C : public B {
143*67e74705SXin Li virtual C *clone();
144*67e74705SXin Li };
145*67e74705SXin Li
146*67e74705SXin Li C c;
147*67e74705SXin Li }
148*67e74705SXin Li
149*67e74705SXin Li // PR5550 - instantiating template didn't track overridden methods
150*67e74705SXin Li namespace PR5550 {
151*67e74705SXin Li struct A {
152*67e74705SXin Li virtual void a() = 0;
153*67e74705SXin Li virtual void b() = 0;
154*67e74705SXin Li };
155*67e74705SXin Li template<typename T> struct B : public A {
156*67e74705SXin Li virtual void b();
157*67e74705SXin Li virtual void c() = 0;
158*67e74705SXin Li };
159*67e74705SXin Li struct C : public B<int> {
160*67e74705SXin Li virtual void a();
161*67e74705SXin Li virtual void c();
162*67e74705SXin Li };
163*67e74705SXin Li C x;
164*67e74705SXin Li }
165*67e74705SXin Li
166*67e74705SXin Li namespace PureImplicit {
167*67e74705SXin Li // A pure virtual destructor should be implicitly overridden.
168*67e74705SXin Li struct A { virtual ~A() = 0; };
169*67e74705SXin Li struct B : A {};
170*67e74705SXin Li B x;
171*67e74705SXin Li
172*67e74705SXin Li // A pure virtual assignment operator should be implicitly overridden.
173*67e74705SXin Li struct D;
174*67e74705SXin Li struct C { virtual D& operator=(const D&) = 0; };
175*67e74705SXin Li struct D : C {};
176*67e74705SXin Li D y;
177*67e74705SXin Li }
178*67e74705SXin Li
179*67e74705SXin Li namespace test1 {
180*67e74705SXin Li struct A {
181*67e74705SXin Li virtual void foo() = 0;
182*67e74705SXin Li };
183*67e74705SXin Li
184*67e74705SXin Li struct B : A {
185*67e74705SXin Li using A::foo;
186*67e74705SXin Li };
187*67e74705SXin Li
188*67e74705SXin Li struct C : B {
189*67e74705SXin Li void foo();
190*67e74705SXin Li };
191*67e74705SXin Li
test()192*67e74705SXin Li void test() {
193*67e74705SXin Li C c;
194*67e74705SXin Li }
195*67e74705SXin Li }
196*67e74705SXin Li
197*67e74705SXin Li // rdar://problem/8302168
198*67e74705SXin Li namespace test2 {
199*67e74705SXin Li struct X1 {
200*67e74705SXin Li virtual void xfunc(void) = 0; // expected-note {{unimplemented pure virtual method}}
201*67e74705SXin Li void g(X1 parm7); // expected-error {{parameter type 'test2::X1' is an abstract class}}
202*67e74705SXin Li void g(X1 parm8[2]); // expected-error {{array of abstract class type 'test2::X1'}}
203*67e74705SXin Li };
204*67e74705SXin Li
205*67e74705SXin Li template <int N>
206*67e74705SXin Li struct X2 {
207*67e74705SXin Li virtual void xfunc(void) = 0; // expected-note {{unimplemented pure virtual method}}
208*67e74705SXin Li void g(X2 parm10); // expected-error {{parameter type 'X2<N>' is an abstract class}}
209*67e74705SXin Li void g(X2 parm11[2]); // expected-error {{array of abstract class type 'X2<N>'}}
210*67e74705SXin Li };
211*67e74705SXin Li }
212*67e74705SXin Li
213*67e74705SXin Li namespace test3 {
214*67e74705SXin Li struct A { // expected-note {{not complete until}}
215*67e74705SXin Li A x; // expected-error {{field has incomplete type}}
216*67e74705SXin Li virtual void abstract() = 0;
217*67e74705SXin Li };
218*67e74705SXin Li
219*67e74705SXin Li struct B { // expected-note {{not complete until}}
220*67e74705SXin Li virtual void abstract() = 0;
221*67e74705SXin Li B x; // expected-error {{field has incomplete type}}
222*67e74705SXin Li };
223*67e74705SXin Li
224*67e74705SXin Li struct C {
225*67e74705SXin Li static C x; // expected-error {{abstract class}}
226*67e74705SXin Li virtual void abstract() = 0; // expected-note {{unimplemented pure virtual method}}
227*67e74705SXin Li };
228*67e74705SXin Li
229*67e74705SXin Li struct D {
230*67e74705SXin Li virtual void abstract() = 0; // expected-note {{unimplemented pure virtual method}}
231*67e74705SXin Li static D x; // expected-error {{abstract class}}
232*67e74705SXin Li };
233*67e74705SXin Li }
234*67e74705SXin Li
235*67e74705SXin Li namespace test4 {
236*67e74705SXin Li template <class T> struct A {
237*67e74705SXin Li A x; // expected-error {{abstract class}}
238*67e74705SXin Li virtual void abstract() = 0; // expected-note {{unimplemented pure virtual method}}
239*67e74705SXin Li };
240*67e74705SXin Li
241*67e74705SXin Li template <class T> struct B {
242*67e74705SXin Li virtual void abstract() = 0; // expected-note {{unimplemented pure virtual method}}
243*67e74705SXin Li B x; // expected-error {{abstract class}}
244*67e74705SXin Li };
245*67e74705SXin Li
246*67e74705SXin Li template <class T> struct C {
247*67e74705SXin Li static C x; // expected-error {{abstract class}}
248*67e74705SXin Li virtual void abstract() = 0; // expected-note {{unimplemented pure virtual method}}
249*67e74705SXin Li };
250*67e74705SXin Li
251*67e74705SXin Li template <class T> struct D {
252*67e74705SXin Li virtual void abstract() = 0; // expected-note {{unimplemented pure virtual method}}
253*67e74705SXin Li static D x; // expected-error {{abstract class}}
254*67e74705SXin Li };
255*67e74705SXin Li }
256*67e74705SXin Li
257*67e74705SXin Li namespace test5 {
258*67e74705SXin Li struct A { A(int); virtual ~A() = 0; }; // expected-note {{pure virtual method}}
259*67e74705SXin Li const A &a = 0; // expected-error {{abstract class}}
260*67e74705SXin Li void f(const A &a = 0); // expected-error {{abstract class}}
g()261*67e74705SXin Li void g() { f(0); } // expected-error {{abstract class}}
262*67e74705SXin Li }
263*67e74705SXin Li
264*67e74705SXin Li // PR9247: Crash on invalid in clang::Sema::ActOnFinishCXXMemberSpecification
265*67e74705SXin Li namespace pr9247 {
266*67e74705SXin Li struct A {
267*67e74705SXin Li virtual void g(const A& input) = 0;
268*67e74705SXin Li struct B {
269*67e74705SXin Li C* f(int foo);
270*67e74705SXin Li };
271*67e74705SXin Li };
272*67e74705SXin Li }
273*67e74705SXin Li
274*67e74705SXin Li namespace pr12658 {
275*67e74705SXin Li class C {
276*67e74705SXin Li public:
C(int v)277*67e74705SXin Li C(int v){}
278*67e74705SXin Li virtual void f() = 0; // expected-note {{unimplemented pure virtual method 'f' in 'C'}}
279*67e74705SXin Li };
280*67e74705SXin Li
foo(C & c)281*67e74705SXin Li void foo( C& c ) {}
282*67e74705SXin Li
bar(void)283*67e74705SXin Li void bar( void ) {
284*67e74705SXin Li foo(C(99)); // expected-error {{allocating an object of abstract class type 'pr12658::C'}}
285*67e74705SXin Li }
286*67e74705SXin Li }
287*67e74705SXin Li
288*67e74705SXin Li namespace pr16659 {
289*67e74705SXin Li struct A {
290*67e74705SXin Li A(int);
291*67e74705SXin Li virtual void x() = 0; // expected-note {{unimplemented pure virtual method 'x' in 'RedundantInit'}}
292*67e74705SXin Li };
293*67e74705SXin Li struct B : virtual A {};
294*67e74705SXin Li struct C : B {
Cpr16659::C295*67e74705SXin Li C() : A(37) {}
xpr16659::C296*67e74705SXin Li void x() override {}
297*67e74705SXin Li };
298*67e74705SXin Li
299*67e74705SXin Li struct X {
300*67e74705SXin Li friend class Z;
301*67e74705SXin Li private:
302*67e74705SXin Li X &operator=(const X&);
303*67e74705SXin Li };
304*67e74705SXin Li struct Y : virtual X { // expected-note {{::X' has an inaccessible copy assignment}}
305*67e74705SXin Li virtual ~Y() = 0;
306*67e74705SXin Li };
307*67e74705SXin Li struct Z : Y {}; // expected-note {{::Y' has a deleted copy assignment}}
f(Z & a,const Z & b)308*67e74705SXin Li void f(Z &a, const Z &b) { a = b; } // expected-error {{copy assignment operator is implicitly deleted}}
309*67e74705SXin Li
310*67e74705SXin Li struct RedundantInit : virtual A {
RedundantInitpr16659::RedundantInit311*67e74705SXin Li RedundantInit() : A(0) {} // expected-warning {{initializer for virtual base class 'pr16659::A' of abstract class 'RedundantInit' will never be used}}
312*67e74705SXin Li };
313*67e74705SXin Li }
314