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); // expected-error {{parameter type 'C' is an abstract class}}
36 void t2(C); // expected-error {{parameter type 'C' is an abstract class}}
37 
38 struct S {
39   C c; // expected-error {{field type 'C' is an abstract class}}
40 };
41 
42 void t3(const C&);
43 
f()44 void f() {
45   C(); // expected-error {{allocating an object of abstract class type 'C'}}
46   t3(C()); // expected-error {{allocating an object of abstract class type 'C'}}
47 }
48 
49 C e1[2]; // expected-error {{array of abstract class type 'C'}}
50 C (*e2)[2]; // expected-error {{array of abstract class type 'C'}}
51 C (**e3)[2]; // expected-error {{array of abstract class type 'C'}}
52 
53 void t4(C c[2]); // expected-error {{array of abstract class type 'C'}}
54 
55 void t5(void (*)(C)); // expected-error {{parameter type 'C' is an abstract class}}
56 
57 typedef void (*Func)(C); // expected-error {{parameter type 'C' is an abstract class}}
58 void t6(Func);
59 
60 class F {
a()61   F a() { while (1) {} } // expected-error {{return type 'F' is an abstract class}}
62 
63   class D {
64     void f(F c); // expected-error {{parameter type 'F' is an abstract class}}
65   };
66 
67   union U {
68     void u(F c); // expected-error {{parameter type 'F' is an abstract class}}
69   };
70 
71   virtual void f() = 0; // expected-note {{unimplemented pure virtual method 'f'}}
72 };
73 
74 // Diagnosing in these cases is prohibitively expensive.  We still
75 // diagnose at the function definition, of course.
76 
77 class Abstract;
78 
79 void t7(Abstract a);
80 
t8()81 void t8() {
82   void h(Abstract a);
83 }
84 
85 namespace N {
86 void h(Abstract a);
87 }
88 
89 class Abstract {
90   virtual void f() = 0;
91 };
92 
93 // <rdar://problem/6854087>
94 class foo {
95 public:
96   virtual foo *getFoo() = 0;
97 };
98 
99 class bar : public foo {
100 public:
101   virtual bar *getFoo();
102 };
103 
104 bar x;
105 
106 // <rdar://problem/6902298>
107 class A {
108 public:
109   virtual void release() = 0;
110   virtual void release(int count) = 0;
111   virtual void retain() = 0;
112 };
113 
114 class B : public A {
115 public:
116   virtual void release();
117   virtual void release(int count);
118   virtual void retain();
119 };
120 
foo(void)121 void foo(void) {
122   B b;
123 }
124 
125 struct K {
126  int f;
127  virtual ~K();
128 };
129 
130 struct L : public K {
131  void f();
132 };
133 
134 // PR5222
135 namespace PR5222 {
136   struct A {
137     virtual A *clone() = 0;
138   };
139   struct B : public A {
140     virtual B *clone() = 0;
141   };
142   struct C : public B {
143     virtual C *clone();
144   };
145 
146   C c;
147 }
148 
149 // PR5550 - instantiating template didn't track overridden methods
150 namespace PR5550 {
151   struct A {
152     virtual void a() = 0;
153     virtual void b() = 0;
154   };
155   template<typename T> struct B : public A {
156     virtual void b();
157     virtual void c() = 0;
158   };
159   struct C : public B<int> {
160     virtual void a();
161     virtual void c();
162   };
163   C x;
164 }
165 
166 namespace PureImplicit {
167   // A pure virtual destructor should be implicitly overridden.
168   struct A { virtual ~A() = 0; };
169   struct B : A {};
170   B x;
171 
172   // A pure virtual assignment operator should be implicitly overridden.
173   struct D;
174   struct C { virtual D& operator=(const D&) = 0; };
175   struct D : C {};
176   D y;
177 }
178 
179 namespace test1 {
180   struct A {
181     virtual void foo() = 0;
182   };
183 
184   struct B : A {
185     using A::foo;
186   };
187 
188   struct C : B {
189     void foo();
190   };
191 
test()192   void test() {
193     C c;
194   }
195 }
196 
197 // rdar://problem/8302168
198 namespace test2 {
199   struct X1 {
200     virtual void xfunc(void) = 0;  // expected-note {{unimplemented pure virtual method}}
201     void g(X1 parm7);        // expected-error {{parameter type 'test2::X1' is an abstract class}}
202     void g(X1 parm8[2]);     // expected-error {{array of abstract class type 'test2::X1'}}
203   };
204 
205   template <int N>
206   struct X2 {
207     virtual void xfunc(void) = 0;  // expected-note {{unimplemented pure virtual method}}
208     void g(X2 parm10);        // expected-error {{parameter type 'X2<N>' is an abstract class}}
209     void g(X2 parm11[2]);     // expected-error {{array of abstract class type 'X2<N>'}}
210   };
211 }
212 
213 namespace test3 {
214   struct A { // expected-note {{not complete until}}
215     A x; // expected-error {{field has incomplete type}}
216     virtual void abstract() = 0;
217   };
218 
219   struct B { // expected-note {{not complete until}}
220     virtual void abstract() = 0;
221     B x; // expected-error {{field has incomplete type}}
222   };
223 
224   struct C {
225     static C x; // expected-error {{abstract class}}
226     virtual void abstract() = 0; // expected-note {{unimplemented pure virtual method}}
227   };
228 
229   struct D {
230     virtual void abstract() = 0; // expected-note {{unimplemented pure virtual method}}
231     static D x; // expected-error {{abstract class}}
232   };
233 }
234 
235 namespace test4 {
236   template <class T> struct A {
237     A x; // expected-error {{abstract class}}
238     virtual void abstract() = 0; // expected-note {{unimplemented pure virtual method}}
239   };
240 
241   template <class T> struct B {
242     virtual void abstract() = 0; // expected-note {{unimplemented pure virtual method}}
243     B x; // expected-error {{abstract class}}
244   };
245 
246   template <class T> struct C {
247     static C x; // expected-error {{abstract class}}
248     virtual void abstract() = 0; // expected-note {{unimplemented pure virtual method}}
249   };
250 
251   template <class T> struct D {
252     virtual void abstract() = 0; // expected-note {{unimplemented pure virtual method}}
253     static D x; // expected-error {{abstract class}}
254   };
255 }
256 
257 namespace test5 {
258   struct A { A(int); virtual ~A() = 0; }; // expected-note {{pure virtual method}}
259   const A &a = 0; // expected-error {{abstract class}}
260   void f(const A &a = 0); // expected-error {{abstract class}}
261   void g(const A &a);
h()262   void h() { g(0); } // expected-error {{abstract class}}
263 }
264 
265 // PR9247: Crash on invalid in clang::Sema::ActOnFinishCXXMemberSpecification
266 namespace pr9247 {
267   struct A {
268     virtual void g(const A& input) = 0;
269     struct B {
270       C* f(int foo);
271     };
272   };
273 }
274 
275 namespace pr12658 {
276   class C {
277     public:
C(int v)278       C(int v){}
279       virtual void f() = 0; // expected-note {{unimplemented pure virtual method 'f' in 'C'}}
280   };
281 
foo(const C & c)282   void foo(const C& c ) {}
283 
bar(void)284   void bar( void ) {
285     foo(C(99)); // expected-error {{allocating an object of abstract class type 'pr12658::C'}}
286   }
287 }
288 
289 namespace pr16659 {
290   struct A {
291     A(int);
292     virtual void x() = 0; // expected-note {{unimplemented pure virtual method 'x' in 'RedundantInit'}}
293   };
294   struct B : virtual A {};
295   struct C : B {
Cpr16659::C296     C() : A(37) {}
xpr16659::C297     void x() override {}
298   };
299 
300   struct X {
301     friend class Z;
302   private:
303     X &operator=(const X&);
304   };
305   struct Y : virtual X { // expected-note {{::X' has an inaccessible copy assignment}}
306     virtual ~Y() = 0;
307   };
308   struct Z : Y {}; // expected-note {{::Y' has a deleted copy assignment}}
f(Z & a,const Z & b)309   void f(Z &a, const Z &b) { a = b; } // expected-error {{copy assignment operator is implicitly deleted}}
310 
311   struct RedundantInit : virtual A {
RedundantInitpr16659::RedundantInit312     RedundantInit() : A(0) {} // expected-warning {{initializer for virtual base class 'pr16659::A' of abstract class 'RedundantInit' will never be used}}
313   };
314 }
315 
316 struct inline_var { // expected-note {{until the closing '}'}}
317   static inline inline_var v = 0; // expected-error {{incomplete type}} expected-warning {{extension}}
318   virtual void f() = 0;
319 };
320 
321 struct var_template {
322   template<typename T>
323   static var_template v; // expected-error {{abstract class}} expected-warning {{extension}}
324   virtual void f() = 0; // expected-note {{unimplemented}}
325 };
326 
327 struct var_template_def { // expected-note {{until the closing '}'}}
328   template<typename T>
329   static inline var_template_def v = {}; // expected-error {{incomplete type}} expected-warning 2{{extension}}
330   virtual void f() = 0;
331 };
332 
333 struct friend_fn {
334   friend void g(friend_fn); // expected-error {{abstract class}}
335   virtual void f() = 0; // expected-note {{unimplemented}}
336 };
337 
338 struct friend_fn_def {
g(friend_fn_def)339   friend void g(friend_fn_def) {} // expected-error {{abstract class}}
340   virtual void f() = 0; // expected-note {{unimplemented}}
341 };
342 
343 struct friend_template {
344   template<typename T>
345   friend void g(friend_template); // expected-error {{abstract class}}
346   virtual void f() = 0; // expected-note {{unimplemented}}
347 };
348 
349 struct friend_template_def {
350   template<typename T>
g(friend_template_def)351   friend void g(friend_template_def) {} // expected-error {{abstract class}}
352   virtual void f() = 0; // expected-note {{unimplemented}}
353 };
354