381 lines · cpp
1// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11 -Wabstract-vbase-init2 3#ifndef __GXX_EXPERIMENTAL_CXX0X__4#define __CONCAT(__X, __Y) __CONCAT1(__X, __Y)5#define __CONCAT1(__X, __Y) __X ## __Y6 7#define static_assert(__b, __m) \8 typedef int __CONCAT(__sa, __LINE__)[__b ? 1 : -1]9#endif10 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);36void t2(C);37void t3(C c){} // expected-error {{parameter type 'C' is an abstract class}}38void t4(C){} // expected-error {{parameter type 'C' is an abstract class}}39 40struct S {41 C c; // expected-error {{field type 'C' is an abstract class}}42};43 44void t5(const C&);45 46void f() {47 C(); // expected-error {{allocating an object of abstract class type 'C'}}48 t5(C()); // expected-error {{allocating an object of abstract class type 'C'}}49}50 51C e1[2]; // expected-error {{array of abstract class type 'C'}}52C (*e2)[2]; // expected-error {{array of abstract class type 'C'}}53C (**e3)[2]; // expected-error {{array of abstract class type 'C'}}54 55void t6(C c[2]); // expected-error {{array of abstract class type 'C'}}56 57void t7(void (*)(C));58 59typedef void (*Func)(C);60void t8(Func);61 62class F {63 F a() { while (1) {} } // expected-error {{return type 'F' is an abstract class}}64 65 class D {66 void f(F c){} // expected-error {{parameter type 'F' is an abstract class}}67 void g(F c);68 void h(F c) = delete;69 };70 71 union U {72 void u(F c){} // expected-error {{parameter type 'F' is an abstract class}}73 void v(F c);74 void w(F c) = delete;75 };76 77 virtual void f() = 0; // expected-note {{unimplemented pure virtual method 'f'}}78};79 80// Diagnosing in these cases is prohibitively expensive. We still81// diagnose at the function definition, of course.82 83class Abstract;84 85void t8(Abstract a);86 87void t9() {88 void h(Abstract a);89}90 91namespace N {92void h(Abstract a);93}94 95class Abstract {96 virtual void f() = 0;97};98 99class foo {100public:101 virtual foo *getFoo() = 0;102};103 104class bar : public foo {105public:106 virtual bar *getFoo();107};108 109bar x;110 111class A {112public:113 virtual void release() = 0;114 virtual void release(int count) = 0;115 virtual void retain() = 0;116};117 118class B : public A {119public:120 virtual void release();121 virtual void release(int count);122 virtual void retain();123};124 125void foo(void) {126 B b;127}128 129struct K {130 int f;131 virtual ~K();132};133 134struct L : public K {135 void f();136};137 138// PR5222139namespace PR5222 {140 struct A {141 virtual A *clone() = 0;142 };143 struct B : public A {144 virtual B *clone() = 0;145 };146 struct C : public B {147 virtual C *clone();148 };149 150 C c;151}152 153// PR5550 - instantiating template didn't track overridden methods154namespace PR5550 {155 struct A {156 virtual void a() = 0;157 virtual void b() = 0;158 };159 template<typename T> struct B : public A {160 virtual void b();161 virtual void c() = 0;162 };163 struct C : public B<int> {164 virtual void a();165 virtual void c();166 };167 C x;168}169 170namespace PureImplicit {171 // A pure virtual destructor should be implicitly overridden.172 struct A { virtual ~A() = 0; };173 struct B : A {};174 B x;175 176 // A pure virtual assignment operator should be implicitly overridden.177 struct D;178 struct C { virtual D& operator=(const D&) = 0; };179 struct D : C {};180 D y;181}182 183namespace test1 {184 struct A {185 virtual void foo() = 0;186 };187 188 struct B : A {189 using A::foo;190 };191 192 struct C : B {193 void foo();194 };195 196 void test() {197 C c;198 }199}200 201namespace test2 {202 struct X1 {203 virtual void xfunc(void) = 0; // expected-note {{unimplemented pure virtual method}}204 void g(X1 parm7){} // expected-error {{parameter type 'X1' is an abstract class}}205 void g(X1 parm8[2]){} // expected-error {{parameter type 'X1' is an abstract class}}206 };207 208 template <int N>209 struct X2 {210 virtual void xfunc(void) = 0; // expected-note {{unimplemented pure virtual method}}211 void g(X2 parm10){} // expected-error {{parameter type 'X2<N>' is an abstract class}}212 void g(X2 parm11[2]) {} // expected-error {{parameter type 'X2<N>' is an abstract class}}213 };214}215 216namespace test3 {217 struct A { // expected-note {{not complete until}}218 A x; // expected-error {{field has incomplete type}}219 virtual void abstract() = 0;220 };221 222 struct B { // expected-note {{not complete until}}223 virtual void abstract() = 0;224 B x; // expected-error {{field has incomplete type}}225 };226 227 struct C {228 static C x; // expected-error {{abstract class}}229 virtual void abstract() = 0; // expected-note {{unimplemented pure virtual method}}230 };231 232 struct D {233 virtual void abstract() = 0; // expected-note {{unimplemented pure virtual method}}234 static D x; // expected-error {{abstract class}}235 };236}237 238namespace test4 {239 template <class T> struct A {240 A x; // expected-error {{abstract class}}241 virtual void abstract() = 0; // expected-note {{unimplemented pure virtual method}}242 };243 244 template <class T> struct B {245 virtual void abstract() = 0; // expected-note {{unimplemented pure virtual method}}246 B x; // expected-error {{abstract class}}247 };248 249 template <class T> struct C {250 static C x; // expected-error {{abstract class}}251 virtual void abstract() = 0; // expected-note {{unimplemented pure virtual method}}252 };253 254 template <class T> struct D {255 virtual void abstract() = 0; // expected-note {{unimplemented pure virtual method}}256 static D x; // expected-error {{abstract class}}257 };258}259 260namespace test5 {261 struct A { A(int); virtual ~A() = 0; }; // expected-note {{pure virtual method}}262 const A &a = 0; // expected-error {{abstract class}}263 void f(const A &a = 0); // expected-error {{abstract class}}264 void g(const A &a);265 void h() { g(0); } // expected-error {{abstract class}}266}267 268// PR9247: Crash on invalid in clang::Sema::ActOnFinishCXXMemberSpecification269namespace pr9247 {270 struct A {271 virtual void g(const A& input) = 0;272 struct B {273 C* f(int foo);274 };275 };276}277 278namespace pr12658 {279 class C {280 public:281 C(int v){}282 virtual void f() = 0; // expected-note {{unimplemented pure virtual method 'f' in 'C'}}283 };284 285 void foo(const C& c ) {}286 287 void bar( void ) {288 foo(C(99)); // expected-error {{allocating an object of abstract class type 'C'}}289 }290}291 292namespace pr16659 {293 struct A {294 A(int);295 virtual void x() = 0; // expected-note {{unimplemented pure virtual method 'x' in 'RedundantInit'}}296 };297 struct B : virtual A {};298 struct C : B {299 C() : A(37) {}300 void x() override {}301 };302 303 struct X {304 friend class Z;305 private:306 X &operator=(const X&);307 };308 struct Y : virtual X { // expected-note {{class 'X' has an inaccessible copy assignment}}309 virtual ~Y() = 0;310 };311 struct Z : Y {}; // expected-note {{class 'Y' has a deleted copy assignment}}312 void f(Z &a, const Z &b) { a = b; } // expected-error {{copy assignment operator is implicitly deleted}}313 314 struct RedundantInit : virtual A {315 RedundantInit() : A(0) {} // expected-warning {{initializer for virtual base class 'A' of abstract class 'RedundantInit' will never be used}}316 };317}318 319struct inline_var { // expected-note {{until the closing '}'}}320 static inline inline_var v = 0; // expected-error {{incomplete type}} expected-warning {{extension}}321 virtual void f() = 0;322};323 324struct var_template {325 template<typename T>326 static var_template v; // expected-error {{abstract class}} expected-warning {{extension}}327 virtual void f() = 0; // expected-note {{unimplemented}}328};329 330struct var_template_def { // expected-note {{until the closing '}'}}331 template<typename T>332 static inline var_template_def v = {}; // expected-error {{incomplete type}} expected-warning 2{{extension}}333 virtual void f() = 0;334};335 336struct friend_fn {337 friend void g(friend_fn);338 virtual void f() = 0;339};340 341struct friend_fn_def {342 friend void g(friend_fn_def) {} // expected-error {{abstract class}}343 virtual void f() = 0; // expected-note {{unimplemented}}344};345 346struct friend_template {347 template<typename T>348 friend void g(friend_template);349 virtual void f() = 0;350};351 352struct friend_template_def {353 template<typename T>354 friend void g(friend_template_def) {} // expected-error {{abstract class}}355 virtual void f() = 0; // expected-note {{unimplemented}}356};357 358namespace GH63012 {359struct foo {360 virtual ~foo() = 0;361};362void f(foo) = delete;363foo i() = delete;364void h(foo);365foo g();366 367struct S {368 virtual void func() = 0; // expected-note {{unimplemented pure virtual method 'func' in 'S'}}369};370void S::func() {}371 372static_assert(__is_abstract(S), "");373 374struct T {375 void func(S) = delete;376 void other(S);377 void yet_another(S) {} // expected-error{{parameter type 'S' is an abstract class}}378};379 380}381