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