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 11union IncompleteUnion; 12 13static_assert(!__is_abstract(IncompleteUnion), "unions are never abstract"); 14 15class C { 16 virtual void f() = 0; // expected-note {{unimplemented pure virtual method 'f'}} 17}; 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 { 27 virtual void f(); 28}; 29 30static_assert(!__is_abstract(E), "E inherits from an abstract class but implements f"); 31 32C *d = new C; // expected-error {{allocating an object of abstract class type 'C'}} 33 34C 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}; 41 42void t3(const C&); 43 44void f() { 45 C(); // expected-error {{allocating an object of abstract class type 'C'}} 46 t3(C()); // expected-error {{allocating an object of abstract class type 'C'}} 47} 48 49C 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'}} 52 53void t4(C c[2]); // expected-error {{array of abstract class type 'C'}} 54 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 60class F { 61 F a() { while (1) {} } // expected-error {{return type 'F' is an abstract class}} 62 63 class D { 64 void f(F c); // expected-error {{parameter type 'F' is an abstract class}} 65 }; 66 67 union U { 68 void u(F c); // expected-error {{parameter type 'F' is an abstract class}} 69 }; 70 71 virtual void f() = 0; // expected-note {{unimplemented pure virtual method 'f'}} 72}; 73 74// Diagnosing in these cases is prohibitively expensive. We still 75// diagnose at the function definition, of course. 76 77class Abstract; 78 79void t7(Abstract a); 80 81void t8() { 82 void h(Abstract a); 83} 84 85namespace N { 86void h(Abstract a); 87} 88 89class Abstract { 90 virtual void f() = 0; 91}; 92 93// <rdar://problem/6854087> 94class foo { 95public: 96 virtual foo *getFoo() = 0; 97}; 98 99class bar : public foo { 100public: 101 virtual bar *getFoo(); 102}; 103 104bar x; 105 106// <rdar://problem/6902298> 107class A { 108public: 109 virtual void release() = 0; 110 virtual void release(int count) = 0; 111 virtual void retain() = 0; 112}; 113 114class B : public A { 115public: 116 virtual void release(); 117 virtual void release(int count); 118 virtual void retain(); 119}; 120 121void foo(void) { 122 B b; 123} 124 125struct K { 126 int f; 127 virtual ~K(); 128}; 129 130struct L : public K { 131 void f(); 132}; 133 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} 148 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} 165 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} 178 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} 196 197// rdar://problem/8302168 198namespace test2 { 199 struct X1 { 200 virtual void xfunc(void) = 0; // expected-note {{unimplemented pure virtual method}} 201 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 { 207 virtual void xfunc(void) = 0; // expected-note {{unimplemented pure virtual method}} 208 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} 212 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}} 226 virtual void abstract() = 0; // expected-note {{unimplemented pure virtual method}} 227 }; 228 229 struct D { 230 virtual void abstract() = 0; // expected-note {{unimplemented pure virtual method}} 231 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}} 238 virtual void abstract() = 0; // expected-note {{unimplemented pure virtual method}} 239 }; 240 241 template <class T> struct B { 242 virtual void abstract() = 0; // expected-note {{unimplemented pure virtual method}} 243 B x; // expected-error {{abstract class}} 244 }; 245 246 template <class T> struct C { 247 static C x; // expected-error {{abstract class}} 248 virtual void abstract() = 0; // expected-note {{unimplemented pure virtual method}} 249 }; 250 251 template <class T> struct D { 252 virtual void abstract() = 0; // expected-note {{unimplemented pure virtual method}} 253 static D x; // expected-error {{abstract class}} 254 }; 255} 256 257namespace 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 264// 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} 273 274namespace pr12658 { 275 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'}} 285 } 286} 287 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} 314