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}}
g()261   void g() { f(0); } // expected-error {{abstract class}}
262 }
263 
264 // PR9247: Crash on invalid in clang::Sema::ActOnFinishCXXMemberSpecification
265 namespace pr9247 {
266   struct A {
267     virtual void g(const A& input) = 0;
268     struct B {
269       C* f(int foo);
270     };
271   };
272 }
273 
274 namespace pr12658 {
275   class C {
276     public:
C(int v)277       C(int v){}
278       virtual void f() = 0; // expected-note {{unimplemented pure virtual method 'f' in 'C'}}
279   };
280 
foo(C & c)281   void foo( C& c ) {}
282 
bar(void)283   void bar( void ) {
284     foo(C(99)); // expected-error {{allocating an object of abstract class type 'pr12658::C'}}
285   }
286 }
287 
288 namespace pr16659 {
289   struct A {
290     A(int);
291     virtual void x() = 0; // expected-note {{unimplemented pure virtual method 'x' in 'RedundantInit'}}
292   };
293   struct B : virtual A {};
294   struct C : B {
Cpr16659::C295     C() : A(37) {}
xpr16659::C296     void x() override {}
297   };
298 
299   struct X {
300     friend class Z;
301   private:
302     X &operator=(const X&);
303   };
304   struct Y : virtual X { // expected-note {{::X' has an inaccessible copy assignment}}
305     virtual ~Y() = 0;
306   };
307   struct Z : Y {}; // expected-note {{::Y' has a deleted copy assignment}}
f(Z & a,const Z & b)308   void f(Z &a, const Z &b) { a = b; } // expected-error {{copy assignment operator is implicitly deleted}}
309 
310   struct RedundantInit : virtual A {
RedundantInitpr16659::RedundantInit311     RedundantInit() : A(0) {} // expected-warning {{initializer for virtual base class 'pr16659::A' of abstract class 'RedundantInit' will never be used}}
312   };
313 }
314