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 union IncompleteUnion; 12 13 static_assert(!__is_abstract(IncompleteUnion), "unions are never abstract"); 14 15 class C { 16 virtual void f() = 0; // expected-note {{unimplemented pure virtual method 'f'}} 17 }; 18 19 static_assert(__is_abstract(C), "C has a pure virtual function"); 20 21 class D : C { 22 }; 23 24 static_assert(__is_abstract(D), "D inherits from an abstract class"); 25 26 class E : D { 27 virtual void f(); 28 }; 29 30 static_assert(!__is_abstract(E), "E inherits from an abstract class but implements f"); 31 32 C *d = new C; // expected-error {{allocating an object of abstract class type 'C'}} 33 34 C c; // expected-error {{variable type 'C' is an abstract class}} 35 void t1(C c); // expected-error {{parameter type 'C' is an abstract class}} 36 void t2(C); // expected-error {{parameter type 'C' is an abstract class}} 37 38 struct S { 39 C c; // expected-error {{field type 'C' is an abstract class}} 40 }; 41 42 void t3(const C&); 43 44 void 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 49 C e1[2]; // expected-error {{array of abstract class type 'C'}} 50 C (*e2)[2]; // expected-error {{array of abstract class type 'C'}} 51 C (**e3)[2]; // expected-error {{array of abstract class type 'C'}} 52 53 void t4(C c[2]); // expected-error {{array of abstract class type 'C'}} 54 55 void t5(void (*)(C)); // expected-error {{parameter type 'C' is an abstract class}} 56 57 typedef void (*Func)(C); // expected-error {{parameter type 'C' is an abstract class}} 58 void t6(Func); 59 60 class 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 77 class Abstract; 78 79 void t7(Abstract a); 80 81 void t8() { 82 void h(Abstract a); 83 } 84 85 namespace N { 86 void h(Abstract a); 87 } 88 89 class Abstract { 90 virtual void f() = 0; 91 }; 92 93 // <rdar://problem/6854087> 94 class foo { 95 public: 96 virtual foo *getFoo() = 0; 97 }; 98 99 class bar : public foo { 100 public: 101 virtual bar *getFoo(); 102 }; 103 104 bar x; 105 106 // <rdar://problem/6902298> 107 class A { 108 public: 109 virtual void release() = 0; 110 virtual void release(int count) = 0; 111 virtual void retain() = 0; 112 }; 113 114 class B : public A { 115 public: 116 virtual void release(); 117 virtual void release(int count); 118 virtual void retain(); 119 }; 120 121 void foo(void) { 122 B b; 123 } 124 125 struct K { 126 int f; 127 virtual ~K(); 128 }; 129 130 struct L : public K { 131 void f(); 132 }; 133 134 // PR5222 135 namespace 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 150 namespace 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 166 namespace 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 179 namespace 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 198 namespace 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 213 namespace 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 235 namespace 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 257 namespace 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 265 namespace pr9247 { 266 struct A { 267 virtual void g(const A& input) = 0; 268 struct B { 269 C* f(int foo); 270 }; 271 }; 272 } 273 274 namespace 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 288 namespace 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