diff options
Diffstat (limited to 'clang/test/SemaCXX/abstract.cpp')
-rw-r--r-- | clang/test/SemaCXX/abstract.cpp | 261 |
1 files changed, 261 insertions, 0 deletions
diff --git a/clang/test/SemaCXX/abstract.cpp b/clang/test/SemaCXX/abstract.cpp new file mode 100644 index 0000000..b164d9e --- /dev/null +++ b/clang/test/SemaCXX/abstract.cpp @@ -0,0 +1,261 @@ +// 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); + }; + }; +} |