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