xref: /aosp_15_r20/external/clang/test/SemaCXX/abstract.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
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