// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11 #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}} }; } // 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); }; }; }