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 class C {
12 virtual void f() = 0; // expected-note {{unimplemented pure virtual method 'f'}}
13 };
14
15 static_assert(__is_abstract(C), "C has a pure virtual function");
16
17 class D : C {
18 };
19
20 static_assert(__is_abstract(D), "D inherits from an abstract class");
21
22 class E : D {
23 virtual void f();
24 };
25
26 static_assert(!__is_abstract(E), "E inherits from an abstract class but implements f");
27
28 C *d = new C; // expected-error {{allocating an object of abstract class type 'C'}}
29
30 C c; // expected-error {{variable type 'C' is an abstract class}}
31 void t1(C c); // expected-error {{parameter type 'C' is an abstract class}}
32 void t2(C); // expected-error {{parameter type 'C' is an abstract class}}
33
34 struct S {
35 C c; // expected-error {{field type 'C' is an abstract class}}
36 };
37
38 void t3(const C&);
39
f()40 void f() {
41 C(); // expected-error {{allocating an object of abstract class type 'C'}}
42 t3(C()); // expected-error {{allocating an object of abstract class type 'C'}}
43 }
44
45 C e1[2]; // expected-error {{array of abstract class type 'C'}}
46 C (*e2)[2]; // expected-error {{array of abstract class type 'C'}}
47 C (**e3)[2]; // expected-error {{array of abstract class type 'C'}}
48
49 void t4(C c[2]); // expected-error {{array of abstract class type 'C'}}
50
51 void t5(void (*)(C)); // expected-error {{parameter type 'C' is an abstract class}}
52
53 typedef void (*Func)(C); // expected-error {{parameter type 'C' is an abstract class}}
54 void t6(Func);
55
56 class F {
a()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
73 class Abstract;
74
75 void t7(Abstract a);
76
t8()77 void t8() {
78 void h(Abstract a);
79 }
80
81 namespace N {
82 void h(Abstract a);
83 }
84
85 class Abstract {
86 virtual void f() = 0;
87 };
88
89 // <rdar://problem/6854087>
90 class foo {
91 public:
92 virtual foo *getFoo() = 0;
93 };
94
95 class bar : public foo {
96 public:
97 virtual bar *getFoo();
98 };
99
100 bar x;
101
102 // <rdar://problem/6902298>
103 class A {
104 public:
105 virtual void release() = 0;
106 virtual void release(int count) = 0;
107 virtual void retain() = 0;
108 };
109
110 class B : public A {
111 public:
112 virtual void release();
113 virtual void release(int count);
114 virtual void retain();
115 };
116
foo(void)117 void foo(void) {
118 B b;
119 }
120
121 struct K {
122 int f;
123 virtual ~K();
124 };
125
126 struct L : public K {
127 void f();
128 };
129
130 // PR5222
131 namespace 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
146 namespace 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
162 namespace 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
175 namespace 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
test()188 void test() {
189 C c;
190 }
191 }
192
193 // rdar://problem/8302168
194 namespace 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
209 namespace 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
231 namespace 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
253 namespace test5 {
254 struct A { A(int); virtual ~A() = 0; }; // expected-note {{pure virtual method}}
255 const A &a = 0; // expected-error {{abstract class}}
256 void f(const A &a = 0); // expected-error {{abstract class}}
g()257 void g() { f(0); } // expected-error {{abstract class}}
258 }
259
260 // PR9247: Crash on invalid in clang::Sema::ActOnFinishCXXMemberSpecification
261 namespace pr9247 {
262 struct A {
263 virtual void g(const A& input) = 0;
264 struct B {
265 C* f(int foo);
266 };
267 };
268 }
269
270 namespace pr12658 {
271 class C {
272 public:
C(int v)273 C(int v){}
274 virtual void f() = 0; // expected-note {{unimplemented pure virtual method 'f' in 'C'}}
275 };
276
foo(C & c)277 void foo( C& c ) {}
278
bar(void)279 void bar( void ) {
280 foo(C(99)); // expected-error {{allocating an object of abstract class type 'pr12658::C'}}
281 }
282 }
283
284 namespace pr16659 {
285 struct A {
286 A(int);
287 virtual void x() = 0; // expected-note {{unimplemented pure virtual method 'x' in 'RedundantInit'}}
288 };
289 struct B : virtual A {};
290 struct C : B {
Cpr16659::C291 C() : A(37) {}
xpr16659::C292 void x() override {}
293 };
294
295 struct X {
296 friend class Z;
297 private:
298 X &operator=(const X&);
299 };
300 struct Y : virtual X { // expected-note {{::X' has an inaccessible copy assignment}}
301 virtual ~Y() = 0;
302 };
303 struct Z : Y {}; // expected-note {{::Y' has a deleted copy assignment}}
f(Z & a,const Z & b)304 void f(Z &a, const Z &b) { a = b; } // expected-error {{copy assignment operator is implicitly deleted}}
305
306 struct RedundantInit : virtual A {
RedundantInitpr16659::RedundantInit307 RedundantInit() : A(0) {} // expected-warning {{initializer for virtual base class 'pr16659::A' of abstract class 'RedundantInit' will never be used}}
308 };
309 }
310