blob: 0ae6c446f3da9cbee74abac0470e02ac5d698e4a [file] [log] [blame]
Daniel Dunbara5728872009-12-15 20:14:24 +00001// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++0x
Anders Carlsson67e4dd22009-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
11class C {
Mike Stump1eb44332009-09-09 15:08:12 +000012 virtual void f() = 0; // expected-note {{pure virtual function 'f'}}
Anders Carlsson67e4dd22009-03-22 01:52:17 +000013};
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 {
Mike Stump1eb44332009-09-09 15:08:12 +000023 virtual void f();
Anders Carlsson67e4dd22009-03-22 01:52:17 +000024};
25
26static_assert(!__is_abstract(E), "E inherits from an abstract class but implements f");
Anders Carlsson4681ebd2009-03-22 20:18:17 +000027
Anders Carlssonb9bbe492009-03-23 17:49:10 +000028C *d = new C; // expected-error {{allocation of an object of abstract type 'C'}}
29
Anders Carlsson4681ebd2009-03-22 20:18:17 +000030C 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};
Anders Carlssonb9bbe492009-03-23 17:49:10 +000037
Anders Carlsson11f21a02009-03-23 19:10:31 +000038void t3(const C&);
39
40void f() {
Mike Stump1eb44332009-09-09 15:08:12 +000041 C(); // expected-error {{allocation of an object of abstract type 'C'}}
42 t3(C()); // expected-error {{allocation of an object of abstract type 'C'}}
Anders Carlsson11f21a02009-03-23 19:10:31 +000043}
44
Anders Carlsson5eff73c2009-03-24 01:46:45 +000045C e1[2]; // expected-error {{variable type 'C' is an abstract class}}
46C (*e2)[2]; // expected-error {{variable type 'C' is an abstract class}}
47C (**e3)[2]; // expected-error {{variable type 'C' is an abstract class}}
Anders Carlsson11f21a02009-03-23 19:10:31 +000048
49void t4(C c[2]); // expected-error {{parameter type 'C' is an abstract class}}
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
Anders Carlsson8211eff2009-03-24 01:19:16 +000056class F {
Mike Stump1eb44332009-09-09 15:08:12 +000057 F a() { while (1) {} } // expected-error {{return type 'F' is an abstract class}}
Anders Carlsson8211eff2009-03-24 01:19:16 +000058
Mike Stump1eb44332009-09-09 15:08:12 +000059 class D {
60 void f(F c); // expected-error {{parameter type 'F' is an abstract class}}
61 };
Anders Carlsson11f21a02009-03-23 19:10:31 +000062
Mike Stump1eb44332009-09-09 15:08:12 +000063 union U {
64 void u(F c); // expected-error {{parameter type 'F' is an abstract class}}
65 };
Anders Carlsson8211eff2009-03-24 01:19:16 +000066
Mike Stump1eb44332009-09-09 15:08:12 +000067 virtual void f() = 0; // expected-note {{pure virtual function 'f'}}
Anders Carlsson8211eff2009-03-24 01:19:16 +000068};
Anders Carlssone65a3c82009-03-24 17:23:42 +000069
70class Abstract;
71
72void t7(Abstract a); // expected-error {{parameter type 'Abstract' is an abstract class}}
73
74void t8() {
Mike Stump1eb44332009-09-09 15:08:12 +000075 void h(Abstract a); // expected-error {{parameter type 'Abstract' is an abstract class}}
Anders Carlssone65a3c82009-03-24 17:23:42 +000076}
77
78namespace N {
Mike Stump1eb44332009-09-09 15:08:12 +000079void h(Abstract a); // expected-error {{parameter type 'Abstract' is an abstract class}}
Anders Carlssone65a3c82009-03-24 17:23:42 +000080}
81
82class Abstract {
Mike Stump1eb44332009-09-09 15:08:12 +000083 virtual void f() = 0; // expected-note {{pure virtual function 'f'}}
Anders Carlssone65a3c82009-03-24 17:23:42 +000084};
Anders Carlsson8ff8c222009-05-17 00:00:05 +000085
86// <rdar://problem/6854087>
87class foo {
88public:
Mike Stump1eb44332009-09-09 15:08:12 +000089 virtual foo *getFoo() = 0;
Anders Carlsson8ff8c222009-05-17 00:00:05 +000090};
91
92class bar : public foo {
93public:
Mike Stump1eb44332009-09-09 15:08:12 +000094 virtual bar *getFoo();
Anders Carlsson8ff8c222009-05-17 00:00:05 +000095};
96
97bar x;
Anders Carlssond12ef8d2009-05-30 00:52:53 +000098
99// <rdar://problem/6902298>
Mike Stump1eb44332009-09-09 15:08:12 +0000100class A {
Anders Carlssond12ef8d2009-05-30 00:52:53 +0000101public:
Mike Stump1eb44332009-09-09 15:08:12 +0000102 virtual void release() = 0;
103 virtual void release(int count) = 0;
104 virtual void retain() = 0;
Anders Carlssond12ef8d2009-05-30 00:52:53 +0000105};
106
Mike Stump1eb44332009-09-09 15:08:12 +0000107class B : public A {
Anders Carlssond12ef8d2009-05-30 00:52:53 +0000108public:
Mike Stump1eb44332009-09-09 15:08:12 +0000109 virtual void release();
110 virtual void release(int count);
111 virtual void retain();
Anders Carlssond12ef8d2009-05-30 00:52:53 +0000112};
113
Mike Stump1eb44332009-09-09 15:08:12 +0000114void foo(void) {
115 B b;
Anders Carlssond12ef8d2009-05-30 00:52:53 +0000116}
117
Anders Carlssonf89bb0f2009-05-30 17:26:39 +0000118struct K {
119 int f;
120 virtual ~K();
121};
122
123struct L : public K {
124 void f();
125};
Anders Carlsson27823022009-10-18 19:34:08 +0000126
127// PR5222
128namespace PR5222 {
129 struct A {
130 virtual A *clone() = 0;
131 };
132 struct B : public A {
133 virtual B *clone() = 0;
134 };
135 struct C : public B {
136 virtual C *clone();
137 };
138
139 C c;
140}
Sebastian Redla165da02009-11-18 21:51:29 +0000141
142// PR5550 - instantiating template didn't track overridden methods
143namespace PR5550 {
144 struct A {
145 virtual void a() = 0;
146 virtual void b() = 0;
147 };
148 template<typename T> struct B : public A {
149 virtual void b();
150 virtual void c() = 0;
151 };
152 struct C : public B<int> {
153 virtual void a();
154 virtual void c();
155 };
156 C x;
157}
Eli Friedmanff2d8782009-12-16 20:00:27 +0000158
159namespace PureImplicit {
160 // A pure virtual destructor should be implicitly overridden.
161 struct A { virtual ~A() = 0; };
162 struct B : A {};
163 B x;
164
165 // A pure virtual assignment operator should be implicitly overridden.
166 struct D;
167 struct C { virtual D& operator=(const D&) = 0; };
168 struct D : C {};
169 D y;
170}
171