abstract.cpp revision 45f11b78750590b1b1bcec6746c7639a256ce2a2
1// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++0x
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
11class C {
12  virtual void f() = 0; // expected-note {{unimplemented pure virtual method 'f'}}
13};
14
15static_assert(__is_abstract(C), "C has a pure virtual function");
16
17class D : C {
18};
19
20static_assert(__is_abstract(D), "D inherits from an abstract class");
21
22class E : D {
23  virtual void f();
24};
25
26static_assert(!__is_abstract(E), "E inherits from an abstract class but implements f");
27
28C *d = new C; // expected-error {{allocating an object of type 'C', which is an abstract class}}
29
30C c; // expected-error {{variable type 'C' is an abstract class}}
31void t1(C c); // expected-error {{parameter type 'C' is an abstract class}}
32void t2(C); // expected-error {{parameter type 'C' is an abstract class}}
33
34struct S {
35  C c; // expected-error {{field type 'C' is an abstract class}}
36};
37
38void t3(const C&);
39
40void f() {
41  C(); // expected-error {{allocating an object of type 'C', which is an abstract class}}
42  t3(C()); // expected-error {{allocating an object of type 'C', which is an abstract class}}
43}
44
45C e1[2]; // expected-error {{array of abstract class type 'C'}}
46C (*e2)[2]; // expected-error {{array of abstract class type 'C'}}
47C (**e3)[2]; // expected-error {{array of abstract class type 'C'}}
48
49void t4(C c[2]); // expected-error {{array of abstract class type 'C'}}
50
51void t5(void (*)(C)); // expected-error {{parameter type 'C' is an abstract class}}
52
53typedef void (*Func)(C); // expected-error {{parameter type 'C' is an abstract class}}
54void t6(Func);
55
56class F {
57  F a() { while (1) {} } // expected-error {{return type 'F' is an abstract class}}
58
59  class D {
60    void f(F c); // expected-error {{parameter type 'F' is an abstract class}}
61  };
62
63  union U {
64    void u(F c); // expected-error {{parameter type 'F' is an abstract class}}
65  };
66
67  virtual void f() = 0; // expected-note {{unimplemented pure virtual method 'f'}}
68};
69
70// Diagnosing in these cases is prohibitively expensive.  We still
71// diagnose at the function definition, of course.
72
73class Abstract;
74
75void t7(Abstract a);
76
77void t8() {
78  void h(Abstract a);
79}
80
81namespace N {
82void h(Abstract a);
83}
84
85class Abstract {
86  virtual void f() = 0;
87};
88
89// <rdar://problem/6854087>
90class foo {
91public:
92  virtual foo *getFoo() = 0;
93};
94
95class bar : public foo {
96public:
97  virtual bar *getFoo();
98};
99
100bar x;
101
102// <rdar://problem/6902298>
103class A {
104public:
105  virtual void release() = 0;
106  virtual void release(int count) = 0;
107  virtual void retain() = 0;
108};
109
110class B : public A {
111public:
112  virtual void release();
113  virtual void release(int count);
114  virtual void retain();
115};
116
117void foo(void) {
118  B b;
119}
120
121struct K {
122 int f;
123 virtual ~K();
124};
125
126struct L : public K {
127 void f();
128};
129
130// PR5222
131namespace PR5222 {
132  struct A {
133    virtual A *clone() = 0;
134  };
135  struct B : public A {
136    virtual B *clone() = 0;
137  };
138  struct C : public B {
139    virtual C *clone();
140  };
141
142  C c;
143}
144
145// PR5550 - instantiating template didn't track overridden methods
146namespace PR5550 {
147  struct A {
148    virtual void a() = 0;
149    virtual void b() = 0;
150  };
151  template<typename T> struct B : public A {
152    virtual void b();
153    virtual void c() = 0;
154  };
155  struct C : public B<int> {
156    virtual void a();
157    virtual void c();
158  };
159  C x;
160}
161
162namespace PureImplicit {
163  // A pure virtual destructor should be implicitly overridden.
164  struct A { virtual ~A() = 0; };
165  struct B : A {};
166  B x;
167
168  // A pure virtual assignment operator should be implicitly overridden.
169  struct D;
170  struct C { virtual D& operator=(const D&) = 0; };
171  struct D : C {};
172  D y;
173}
174
175namespace test1 {
176  struct A {
177    virtual void foo() = 0;
178  };
179
180  struct B : A {
181    using A::foo;
182  };
183
184  struct C : B {
185    void foo();
186  };
187
188  void test() {
189    C c;
190  }
191}
192
193// rdar://problem/8302168
194namespace test2 {
195  struct X1 {
196    virtual void xfunc(void) = 0;  // expected-note {{unimplemented pure virtual method}}
197    void g(X1 parm7);        // expected-error {{parameter type 'test2::X1' is an abstract class}}
198    void g(X1 parm8[2]);     // expected-error {{array of abstract class type 'test2::X1'}}
199  };
200
201  template <int N>
202  struct X2 {
203    virtual void xfunc(void) = 0;  // expected-note {{unimplemented pure virtual method}}
204    void g(X2 parm10);        // expected-error {{parameter type 'X2<N>' is an abstract class}}
205    void g(X2 parm11[2]);     // expected-error {{array of abstract class type 'X2<N>'}}
206  };
207}
208
209namespace test3 {
210  struct A { // expected-note {{not complete until}}
211    A x; // expected-error {{field has incomplete type}}
212    virtual void abstract() = 0;
213  };
214
215  struct B { // expected-note {{not complete until}}
216    virtual void abstract() = 0;
217    B x; // expected-error {{field has incomplete type}}
218  };
219
220  struct C {
221    static C x; // expected-error {{abstract class}}
222    virtual void abstract() = 0; // expected-note {{unimplemented pure virtual method}}
223  };
224
225  struct D {
226    virtual void abstract() = 0; // expected-note {{unimplemented pure virtual method}}
227    static D x; // expected-error {{abstract class}}
228  };
229}
230
231namespace test4 {
232  template <class T> struct A {
233    A x; // expected-error {{abstract class}}
234    virtual void abstract() = 0; // expected-note {{unimplemented pure virtual method}}
235  };
236
237  template <class T> struct B {
238    virtual void abstract() = 0; // expected-note {{unimplemented pure virtual method}}
239    B x; // expected-error {{abstract class}}
240  };
241
242  template <class T> struct C {
243    static C x; // expected-error {{abstract class}}
244    virtual void abstract() = 0; // expected-note {{unimplemented pure virtual method}}
245  };
246
247  template <class T> struct D {
248    virtual void abstract() = 0; // expected-note {{unimplemented pure virtual method}}
249    static D x; // expected-error {{abstract class}}
250  };
251}
252