| // RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11 -Wabstract-vbase-init |
| |
| #ifndef __GXX_EXPERIMENTAL_CXX0X__ |
| #define __CONCAT(__X, __Y) __CONCAT1(__X, __Y) |
| #define __CONCAT1(__X, __Y) __X ## __Y |
| |
| #define static_assert(__b, __m) \ |
| typedef int __CONCAT(__sa, __LINE__)[__b ? 1 : -1] |
| #endif |
| |
| class C { |
| virtual void f() = 0; // expected-note {{unimplemented pure virtual method 'f'}} |
| }; |
| |
| static_assert(__is_abstract(C), "C has a pure virtual function"); |
| |
| class D : C { |
| }; |
| |
| static_assert(__is_abstract(D), "D inherits from an abstract class"); |
| |
| class E : D { |
| virtual void f(); |
| }; |
| |
| static_assert(!__is_abstract(E), "E inherits from an abstract class but implements f"); |
| |
| C *d = new C; // expected-error {{allocating an object of abstract class type 'C'}} |
| |
| C c; // expected-error {{variable type 'C' is an abstract class}} |
| void t1(C c); // expected-error {{parameter type 'C' is an abstract class}} |
| void t2(C); // expected-error {{parameter type 'C' is an abstract class}} |
| |
| struct S { |
| C c; // expected-error {{field type 'C' is an abstract class}} |
| }; |
| |
| void t3(const C&); |
| |
| void f() { |
| C(); // expected-error {{allocating an object of abstract class type 'C'}} |
| t3(C()); // expected-error {{allocating an object of abstract class type 'C'}} |
| } |
| |
| C e1[2]; // expected-error {{array of abstract class type 'C'}} |
| C (*e2)[2]; // expected-error {{array of abstract class type 'C'}} |
| C (**e3)[2]; // expected-error {{array of abstract class type 'C'}} |
| |
| void t4(C c[2]); // expected-error {{array of abstract class type 'C'}} |
| |
| void t5(void (*)(C)); // expected-error {{parameter type 'C' is an abstract class}} |
| |
| typedef void (*Func)(C); // expected-error {{parameter type 'C' is an abstract class}} |
| void t6(Func); |
| |
| class F { |
| F a() { while (1) {} } // expected-error {{return type 'F' is an abstract class}} |
| |
| class D { |
| void f(F c); // expected-error {{parameter type 'F' is an abstract class}} |
| }; |
| |
| union U { |
| void u(F c); // expected-error {{parameter type 'F' is an abstract class}} |
| }; |
| |
| virtual void f() = 0; // expected-note {{unimplemented pure virtual method 'f'}} |
| }; |
| |
| // Diagnosing in these cases is prohibitively expensive. We still |
| // diagnose at the function definition, of course. |
| |
| class Abstract; |
| |
| void t7(Abstract a); |
| |
| void t8() { |
| void h(Abstract a); |
| } |
| |
| namespace N { |
| void h(Abstract a); |
| } |
| |
| class Abstract { |
| virtual void f() = 0; |
| }; |
| |
| // <rdar://problem/6854087> |
| class foo { |
| public: |
| virtual foo *getFoo() = 0; |
| }; |
| |
| class bar : public foo { |
| public: |
| virtual bar *getFoo(); |
| }; |
| |
| bar x; |
| |
| // <rdar://problem/6902298> |
| class A { |
| public: |
| virtual void release() = 0; |
| virtual void release(int count) = 0; |
| virtual void retain() = 0; |
| }; |
| |
| class B : public A { |
| public: |
| virtual void release(); |
| virtual void release(int count); |
| virtual void retain(); |
| }; |
| |
| void foo(void) { |
| B b; |
| } |
| |
| struct K { |
| int f; |
| virtual ~K(); |
| }; |
| |
| struct L : public K { |
| void f(); |
| }; |
| |
| // PR5222 |
| namespace PR5222 { |
| struct A { |
| virtual A *clone() = 0; |
| }; |
| struct B : public A { |
| virtual B *clone() = 0; |
| }; |
| struct C : public B { |
| virtual C *clone(); |
| }; |
| |
| C c; |
| } |
| |
| // PR5550 - instantiating template didn't track overridden methods |
| namespace PR5550 { |
| struct A { |
| virtual void a() = 0; |
| virtual void b() = 0; |
| }; |
| template<typename T> struct B : public A { |
| virtual void b(); |
| virtual void c() = 0; |
| }; |
| struct C : public B<int> { |
| virtual void a(); |
| virtual void c(); |
| }; |
| C x; |
| } |
| |
| namespace PureImplicit { |
| // A pure virtual destructor should be implicitly overridden. |
| struct A { virtual ~A() = 0; }; |
| struct B : A {}; |
| B x; |
| |
| // A pure virtual assignment operator should be implicitly overridden. |
| struct D; |
| struct C { virtual D& operator=(const D&) = 0; }; |
| struct D : C {}; |
| D y; |
| } |
| |
| namespace test1 { |
| struct A { |
| virtual void foo() = 0; |
| }; |
| |
| struct B : A { |
| using A::foo; |
| }; |
| |
| struct C : B { |
| void foo(); |
| }; |
| |
| void test() { |
| C c; |
| } |
| } |
| |
| // rdar://problem/8302168 |
| namespace test2 { |
| struct X1 { |
| virtual void xfunc(void) = 0; // expected-note {{unimplemented pure virtual method}} |
| void g(X1 parm7); // expected-error {{parameter type 'test2::X1' is an abstract class}} |
| void g(X1 parm8[2]); // expected-error {{array of abstract class type 'test2::X1'}} |
| }; |
| |
| template <int N> |
| struct X2 { |
| virtual void xfunc(void) = 0; // expected-note {{unimplemented pure virtual method}} |
| void g(X2 parm10); // expected-error {{parameter type 'X2<N>' is an abstract class}} |
| void g(X2 parm11[2]); // expected-error {{array of abstract class type 'X2<N>'}} |
| }; |
| } |
| |
| namespace test3 { |
| struct A { // expected-note {{not complete until}} |
| A x; // expected-error {{field has incomplete type}} |
| virtual void abstract() = 0; |
| }; |
| |
| struct B { // expected-note {{not complete until}} |
| virtual void abstract() = 0; |
| B x; // expected-error {{field has incomplete type}} |
| }; |
| |
| struct C { |
| static C x; // expected-error {{abstract class}} |
| virtual void abstract() = 0; // expected-note {{unimplemented pure virtual method}} |
| }; |
| |
| struct D { |
| virtual void abstract() = 0; // expected-note {{unimplemented pure virtual method}} |
| static D x; // expected-error {{abstract class}} |
| }; |
| } |
| |
| namespace test4 { |
| template <class T> struct A { |
| A x; // expected-error {{abstract class}} |
| virtual void abstract() = 0; // expected-note {{unimplemented pure virtual method}} |
| }; |
| |
| template <class T> struct B { |
| virtual void abstract() = 0; // expected-note {{unimplemented pure virtual method}} |
| B x; // expected-error {{abstract class}} |
| }; |
| |
| template <class T> struct C { |
| static C x; // expected-error {{abstract class}} |
| virtual void abstract() = 0; // expected-note {{unimplemented pure virtual method}} |
| }; |
| |
| template <class T> struct D { |
| virtual void abstract() = 0; // expected-note {{unimplemented pure virtual method}} |
| static D x; // expected-error {{abstract class}} |
| }; |
| } |
| |
| namespace test5 { |
| struct A { A(int); virtual ~A() = 0; }; // expected-note {{pure virtual method}} |
| const A &a = 0; // expected-error {{abstract class}} |
| void f(const A &a = 0); // expected-error {{abstract class}} |
| void g() { f(0); } // expected-error {{abstract class}} |
| } |
| |
| // PR9247: Crash on invalid in clang::Sema::ActOnFinishCXXMemberSpecification |
| namespace pr9247 { |
| struct A { |
| virtual void g(const A& input) = 0; |
| struct B { |
| C* f(int foo); |
| }; |
| }; |
| } |
| |
| namespace pr12658 { |
| class C {
|
| public:
|
| C(int v){}
|
| virtual void f() = 0; // expected-note {{unimplemented pure virtual method 'f' in 'C'}}
|
| };
|
|
|
| void foo( C& c ) {}
|
|
|
| void bar( void ) {
|
| foo(C(99)); // expected-error {{allocating an object of abstract class type 'pr12658::C'}}
|
| } |
| } |
| |
| namespace pr16659 { |
| struct A { |
| A(int); |
| virtual void x() = 0; // expected-note {{unimplemented pure virtual method 'x' in 'RedundantInit'}} |
| }; |
| struct B : virtual A {}; |
| struct C : B { |
| C() : A(37) {} |
| void x() override {} |
| }; |
| |
| struct X { |
| friend class Z; |
| private: |
| X &operator=(const X&); |
| }; |
| struct Y : virtual X { // expected-note {{::X' has an inaccessible copy assignment}} |
| virtual ~Y() = 0; |
| }; |
| struct Z : Y {}; // expected-note {{::Y' has a deleted copy assignment}} |
| void f(Z &a, const Z &b) { a = b; } // expected-error {{copy assignment operator is implicitly deleted}} |
| |
| struct RedundantInit : virtual A { |
| RedundantInit() : A(0) {} // expected-warning {{initializer for virtual base class 'pr16659::A' of abstract class 'RedundantInit' will never be used}} |
| }; |
| } |