blob: ffd36be5b7970c52dc894339f7757f6508b283eb [file] [log] [blame]
Richard Smithbc46e432013-07-22 02:56:56 +00001// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11 -Wabstract-vbase-init
Anders Carlsson7cbd8fb2009-03-22 01:52:17 +00002
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
David Majnemer213bea32015-11-16 06:58:51 +000011union IncompleteUnion;
12
13static_assert(!__is_abstract(IncompleteUnion), "unions are never abstract");
14
Anders Carlsson7cbd8fb2009-03-22 01:52:17 +000015class C {
Chandler Carruth98e3c562011-02-18 23:59:51 +000016 virtual void f() = 0; // expected-note {{unimplemented pure virtual method 'f'}}
Anders Carlsson7cbd8fb2009-03-22 01:52:17 +000017};
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 {
Mike Stump11289f42009-09-09 15:08:12 +000027 virtual void f();
Anders Carlsson7cbd8fb2009-03-22 01:52:17 +000028};
29
30static_assert(!__is_abstract(E), "E inherits from an abstract class but implements f");
Anders Carlsson576cc6f2009-03-22 20:18:17 +000031
Chandler Carruthfc1ad1f2011-02-19 00:12:23 +000032C *d = new C; // expected-error {{allocating an object of abstract class type 'C'}}
Anders Carlsson0d5ca292009-03-23 17:49:10 +000033
Anders Carlsson576cc6f2009-03-22 20:18:17 +000034C 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};
Anders Carlsson0d5ca292009-03-23 17:49:10 +000041
Anders Carlssoneb0c5322009-03-23 19:10:31 +000042void t3(const C&);
43
44void f() {
Chandler Carruthfc1ad1f2011-02-19 00:12:23 +000045 C(); // expected-error {{allocating an object of abstract class type 'C'}}
46 t3(C()); // expected-error {{allocating an object of abstract class type 'C'}}
Anders Carlssoneb0c5322009-03-23 19:10:31 +000047}
48
Douglas Gregor7d8072e2010-04-27 19:38:14 +000049C 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'}}
Anders Carlssoneb0c5322009-03-23 19:10:31 +000052
Douglas Gregor7d8072e2010-04-27 19:38:14 +000053void t4(C c[2]); // expected-error {{array of abstract class type 'C'}}
Anders Carlssoneb0c5322009-03-23 19:10:31 +000054
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
Anders Carlssonb5a27b42009-03-24 01:19:16 +000060class F {
Mike Stump11289f42009-09-09 15:08:12 +000061 F a() { while (1) {} } // expected-error {{return type 'F' is an abstract class}}
Anders Carlssonb5a27b42009-03-24 01:19:16 +000062
Mike Stump11289f42009-09-09 15:08:12 +000063 class D {
64 void f(F c); // expected-error {{parameter type 'F' is an abstract class}}
65 };
Anders Carlssoneb0c5322009-03-23 19:10:31 +000066
Mike Stump11289f42009-09-09 15:08:12 +000067 union U {
68 void u(F c); // expected-error {{parameter type 'F' is an abstract class}}
69 };
Anders Carlssonb5a27b42009-03-24 01:19:16 +000070
Chandler Carruth98e3c562011-02-18 23:59:51 +000071 virtual void f() = 0; // expected-note {{unimplemented pure virtual method 'f'}}
Anders Carlssonb5a27b42009-03-24 01:19:16 +000072};
Anders Carlssonb57738b2009-03-24 17:23:42 +000073
John McCall02db245d2010-08-18 09:41:07 +000074// Diagnosing in these cases is prohibitively expensive. We still
75// diagnose at the function definition, of course.
76
Anders Carlssonb57738b2009-03-24 17:23:42 +000077class Abstract;
78
John McCall02db245d2010-08-18 09:41:07 +000079void t7(Abstract a);
Anders Carlssonb57738b2009-03-24 17:23:42 +000080
81void t8() {
John McCall02db245d2010-08-18 09:41:07 +000082 void h(Abstract a);
Anders Carlssonb57738b2009-03-24 17:23:42 +000083}
84
85namespace N {
John McCall02db245d2010-08-18 09:41:07 +000086void h(Abstract a);
Anders Carlssonb57738b2009-03-24 17:23:42 +000087}
88
89class Abstract {
John McCall02db245d2010-08-18 09:41:07 +000090 virtual void f() = 0;
Anders Carlssonb57738b2009-03-24 17:23:42 +000091};
Anders Carlsson3c012712009-05-17 00:00:05 +000092
93// <rdar://problem/6854087>
94class foo {
95public:
Mike Stump11289f42009-09-09 15:08:12 +000096 virtual foo *getFoo() = 0;
Anders Carlsson3c012712009-05-17 00:00:05 +000097};
98
99class bar : public foo {
100public:
Mike Stump11289f42009-09-09 15:08:12 +0000101 virtual bar *getFoo();
Anders Carlsson3c012712009-05-17 00:00:05 +0000102};
103
104bar x;
Anders Carlsson65d58202009-05-30 00:52:53 +0000105
106// <rdar://problem/6902298>
Mike Stump11289f42009-09-09 15:08:12 +0000107class A {
Anders Carlsson65d58202009-05-30 00:52:53 +0000108public:
Mike Stump11289f42009-09-09 15:08:12 +0000109 virtual void release() = 0;
110 virtual void release(int count) = 0;
111 virtual void retain() = 0;
Anders Carlsson65d58202009-05-30 00:52:53 +0000112};
113
Mike Stump11289f42009-09-09 15:08:12 +0000114class B : public A {
Anders Carlsson65d58202009-05-30 00:52:53 +0000115public:
Mike Stump11289f42009-09-09 15:08:12 +0000116 virtual void release();
117 virtual void release(int count);
118 virtual void retain();
Anders Carlsson65d58202009-05-30 00:52:53 +0000119};
120
Mike Stump11289f42009-09-09 15:08:12 +0000121void foo(void) {
122 B b;
Anders Carlsson65d58202009-05-30 00:52:53 +0000123}
124
Anders Carlsson36b75a42009-05-30 17:26:39 +0000125struct K {
126 int f;
127 virtual ~K();
128};
129
130struct L : public K {
131 void f();
132};
Anders Carlsson700179432009-10-18 19:34:08 +0000133
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}
Sebastian Redld5b24532009-11-18 21:51:29 +0000148
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}
Eli Friedman5dd02a0f2009-12-16 20:00:27 +0000165
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}
John McCall38e5f432010-06-16 09:33:39 +0000178
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}
John McCall02db245d2010-08-18 09:41:07 +0000196
197// rdar://problem/8302168
198namespace test2 {
199 struct X1 {
Chandler Carruth98e3c562011-02-18 23:59:51 +0000200 virtual void xfunc(void) = 0; // expected-note {{unimplemented pure virtual method}}
John McCall02db245d2010-08-18 09:41:07 +0000201 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 {
Chandler Carruth98e3c562011-02-18 23:59:51 +0000207 virtual void xfunc(void) = 0; // expected-note {{unimplemented pure virtual method}}
John McCall02db245d2010-08-18 09:41:07 +0000208 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}
John McCall8f428932010-08-18 09:58:15 +0000212
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}}
Chandler Carruth98e3c562011-02-18 23:59:51 +0000226 virtual void abstract() = 0; // expected-note {{unimplemented pure virtual method}}
John McCall8f428932010-08-18 09:58:15 +0000227 };
228
229 struct D {
Chandler Carruth98e3c562011-02-18 23:59:51 +0000230 virtual void abstract() = 0; // expected-note {{unimplemented pure virtual method}}
John McCall8f428932010-08-18 09:58:15 +0000231 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}}
Chandler Carruth98e3c562011-02-18 23:59:51 +0000238 virtual void abstract() = 0; // expected-note {{unimplemented pure virtual method}}
John McCall8f428932010-08-18 09:58:15 +0000239 };
240
241 template <class T> struct B {
Chandler Carruth98e3c562011-02-18 23:59:51 +0000242 virtual void abstract() = 0; // expected-note {{unimplemented pure virtual method}}
John McCall8f428932010-08-18 09:58:15 +0000243 B x; // expected-error {{abstract class}}
244 };
245
246 template <class T> struct C {
247 static C x; // expected-error {{abstract class}}
Chandler Carruth98e3c562011-02-18 23:59:51 +0000248 virtual void abstract() = 0; // expected-note {{unimplemented pure virtual method}}
John McCall8f428932010-08-18 09:58:15 +0000249 };
250
251 template <class T> struct D {
Chandler Carruth98e3c562011-02-18 23:59:51 +0000252 virtual void abstract() = 0; // expected-note {{unimplemented pure virtual method}}
John McCall8f428932010-08-18 09:58:15 +0000253 static D x; // expected-error {{abstract class}}
254 };
255}
Douglas Gregor385d3fd2011-02-22 23:21:06 +0000256
Richard Smith72d74052013-07-20 19:41:36 +0000257namespace 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
Douglas Gregor385d3fd2011-02-22 23:21:06 +0000264// 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}
Aaron Ballmanea032142012-05-07 00:02:00 +0000273
274namespace pr12658 {
David Majnemerb1004102014-03-02 18:46:05 +0000275 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'}}
Aaron Ballmanea032142012-05-07 00:02:00 +0000285 }
286}
Richard Smithbc46e432013-07-22 02:56:56 +0000287
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}