forked from OSchip/llvm-project
				
			
		
			
				
	
	
		
			262 lines
		
	
	
		
			6.0 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			262 lines
		
	
	
		
			6.0 KiB
		
	
	
	
		
			C++
		
	
	
	
| // RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++0x
 | |
| 
 | |
| #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);
 | |
|     };
 | |
|   };
 | |
| }
 |