// 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
union IncompleteUnion;
static_assert(!__is_abstract(IncompleteUnion), "unions are never abstract");
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);
void t2(C);
void t3(C c){} // expected-error {{parameter type 'C' is an abstract class}}
void t4(C){} // expected-error {{parameter type 'C' is an abstract class}}
struct S {
C c; // expected-error {{field type 'C' is an abstract class}}
};
void t5(const C&);
void f() {
C(); // expected-error {{allocating an object of abstract class type 'C'}}
t5(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 t6(C c[2]); // expected-error {{array of abstract class type 'C'}}
void t7(void (*)(C));
typedef void (*Func)(C);
void t8(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}}
void g(F c);
void h(F c) = delete;
};
union U {
void u(F c){} // expected-error {{parameter type 'F' is an abstract class}}
void v(F c);
void w(F c) = delete;
};
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 t8(Abstract a);
void t9() {
void h(Abstract a);
}
namespace N {
void h(Abstract a);
}
class Abstract {
virtual void f() = 0;
};
class foo {
public:
virtual foo *getFoo() = 0;
};
class bar : public foo {
public:
virtual bar *getFoo();
};
bar x;
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;
}
}
namespace test2 {
struct X1 {
virtual void xfunc(void) = 0; // expected-note {{unimplemented pure virtual method}}
void g(X1 parm7){} // expected-error {{parameter type 'X1' is an abstract class}}
void g(X1 parm8[2]){} // expected-error {{parameter type 'X1' is an abstract class}}
};
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 {{parameter type 'X2<N>' is an abstract class}}
};
}
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(const A &a);
void h() { g(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(const C& c ) {}
void bar( void ) {
foo(C(99)); // expected-error {{allocating an object of abstract class type '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 {{class 'X' has an inaccessible copy assignment}}
virtual ~Y() = 0;
};
struct Z : Y {}; // expected-note {{class '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 'A' of abstract class 'RedundantInit' will never be used}}
};
}
struct inline_var { // expected-note {{until the closing '}'}}
static inline inline_var v = 0; // expected-error {{incomplete type}} expected-warning {{extension}}
virtual void f() = 0;
};
struct var_template {
template<typename T>
static var_template v; // expected-error {{abstract class}} expected-warning {{extension}}
virtual void f() = 0; // expected-note {{unimplemented}}
};
struct var_template_def { // expected-note {{until the closing '}'}}
template<typename T>
static inline var_template_def v = {}; // expected-error {{incomplete type}} expected-warning 2{{extension}}
virtual void f() = 0;
};
struct friend_fn {
friend void g(friend_fn);
virtual void f() = 0;
};
struct friend_fn_def {
friend void g(friend_fn_def) {} // expected-error {{abstract class}}
virtual void f() = 0; // expected-note {{unimplemented}}
};
struct friend_template {
template<typename T>
friend void g(friend_template);
virtual void f() = 0;
};
struct friend_template_def {
template<typename T>
friend void g(friend_template_def) {} // expected-error {{abstract class}}
virtual void f() = 0; // expected-note {{unimplemented}}
};
namespace GH63012 {
struct foo {
virtual ~foo() = 0;
};
void f(foo) = delete;
foo i() = delete;
void h(foo);
foo g();
struct S {
virtual void func() = 0; // expected-note {{unimplemented pure virtual method 'func' in 'S'}}
};
void S::func() {}
static_assert(__is_abstract(S), "");
struct T {
void func(S) = delete;
void other(S);
void yet_another(S) {} // expected-error{{parameter type 'S' is an abstract class}}
};
}