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
11union IncompleteUnion;
12
13static_assert(!__is_abstract(IncompleteUnion), "unions are never abstract");
14
15class C {
16  virtual void f() = 0; // expected-note {{unimplemented pure virtual method 'f'}}
17};
18
19static_assert(__is_abstract(C), "C has a pure virtual function");
20
21class D : C {
22};
23
24static_assert(__is_abstract(D), "D inherits from an abstract class");
25
26class E : D {
27  virtual void f();
28};
29
30static_assert(!__is_abstract(E), "E inherits from an abstract class but implements f");
31
32C *d = new C; // expected-error {{allocating an object of abstract class type 'C'}}
33
34C c; // expected-error {{variable type 'C' is an abstract class}}
35void t1(C c); // expected-error {{parameter type 'C' is an abstract class}}
36void t2(C); // expected-error {{parameter type 'C' is an abstract class}}
37
38struct S {
39  C c; // expected-error {{field type 'C' is an abstract class}}
40};
41
42void t3(const C&);
43
44void 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
49C e1[2]; // expected-error {{array of abstract class type 'C'}}
50C (*e2)[2]; // expected-error {{array of abstract class type 'C'}}
51C (**e3)[2]; // expected-error {{array of abstract class type 'C'}}
52
53void t4(C c[2]); // expected-error {{array of abstract class type 'C'}}
54
55void t5(void (*)(C)); // expected-error {{parameter type 'C' is an abstract class}}
56
57typedef void (*Func)(C); // expected-error {{parameter type 'C' is an abstract class}}
58void t6(Func);
59
60class F {
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
77class Abstract;
78
79void t7(Abstract a);
80
81void t8() {
82  void h(Abstract a);
83}
84
85namespace N {
86void h(Abstract a);
87}
88
89class Abstract {
90  virtual void f() = 0;
91};
92
93// <rdar://problem/6854087>
94class foo {
95public:
96  virtual foo *getFoo() = 0;
97};
98
99class bar : public foo {
100public:
101  virtual bar *getFoo();
102};
103
104bar x;
105
106// <rdar://problem/6902298>
107class A {
108public:
109  virtual void release() = 0;
110  virtual void release(int count) = 0;
111  virtual void retain() = 0;
112};
113
114class B : public A {
115public:
116  virtual void release();
117  virtual void release(int count);
118  virtual void retain();
119};
120
121void foo(void) {
122  B b;
123}
124
125struct K {
126 int f;
127 virtual ~K();
128};
129
130struct L : public K {
131 void f();
132};
133
134// PR5222
135namespace 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
150namespace 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
166namespace 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
179namespace 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
192  void test() {
193    C c;
194  }
195}
196
197// rdar://problem/8302168
198namespace 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
213namespace 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
235namespace 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
257namespace 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() { f(0); } // expected-error {{abstract class}}
262}
263
264// PR9247: Crash on invalid in clang::Sema::ActOnFinishCXXMemberSpecification
265namespace pr9247 {
266  struct A {
267    virtual void g(const A& input) = 0;
268    struct B {
269      C* f(int foo);
270    };
271  };
272}
273
274namespace pr12658 {
275  class C {
276    public:
277      C(int v){}
278      virtual void f() = 0; // expected-note {{unimplemented pure virtual method 'f' in 'C'}}
279  };
280
281  void foo( C& c ) {}
282
283  void bar( void ) {
284    foo(C(99)); // expected-error {{allocating an object of abstract class type 'pr12658::C'}}
285  }
286}
287
288namespace 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 {
295    C() : A(37) {}
296    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}}
308  void f(Z &a, const Z &b) { a = b; } // expected-error {{copy assignment operator is implicitly deleted}}
309
310  struct RedundantInit : virtual A {
311    RedundantInit() : A(0) {} // expected-warning {{initializer for virtual base class 'pr16659::A' of abstract class 'RedundantInit' will never be used}}
312  };
313}
314