abstract.cpp revision 52a02758fb81723e16c46721152c6ad0528b2fc3
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 {{pure virtual function '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 {{allocation of an object of abstract type 'C'}}
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 {{allocation of an object of abstract type 'C'}}
42  t3(C()); // expected-error {{allocation of an object of abstract type 'C'}}
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 {{pure virtual function 'f'}}
68};
69
70class Abstract;
71
72void t7(Abstract a); // expected-error {{parameter type 'Abstract' is an abstract class}}
73
74void t8() {
75  void h(Abstract a); // expected-error {{parameter type 'Abstract' is an abstract class}}
76}
77
78namespace N {
79void h(Abstract a); // expected-error {{parameter type 'Abstract' is an abstract class}}
80}
81
82class Abstract {
83  virtual void f() = 0; // expected-note {{pure virtual function 'f'}}
84};
85
86// <rdar://problem/6854087>
87class foo {
88public:
89  virtual foo *getFoo() = 0;
90};
91
92class bar : public foo {
93public:
94  virtual bar *getFoo();
95};
96
97bar x;
98
99// <rdar://problem/6902298>
100class A {
101public:
102  virtual void release() = 0;
103  virtual void release(int count) = 0;
104  virtual void retain() = 0;
105};
106
107class B : public A {
108public:
109  virtual void release();
110  virtual void release(int count);
111  virtual void retain();
112};
113
114void foo(void) {
115  B b;
116}
117
118struct K {
119 int f;
120 virtual ~K();
121};
122
123struct L : public K {
124 void f();
125};
126
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}
141
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}
158
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
172namespace test1 {
173  struct A {
174    virtual void foo() = 0;
175  };
176
177  struct B : A {
178    using A::foo;
179  };
180
181  struct C : B {
182    void foo();
183  };
184
185  void test() {
186    C c;
187  }
188}
189