summaryrefslogtreecommitdiff
path: root/clang/test/SemaCXX/abstract.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/test/SemaCXX/abstract.cpp')
-rw-r--r--clang/test/SemaCXX/abstract.cpp261
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);
+ };
+ };
+}