forked from OSchip/llvm-project
				
			
		
			
				
	
	
		
			310 lines
		
	
	
		
			7.4 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			310 lines
		
	
	
		
			7.4 KiB
		
	
	
	
		
			C++
		
	
	
	
// 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}}
 | 
						|
  };
 | 
						|
}
 |