Home | History | Annotate | Download | only in SemaCXX
      1 // RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11 -Wabstract-vbase-init
      2 
      3 #ifndef __GXX_EXPERIMENTAL_CXX0X__
      4 #define __CONCAT(__X, __Y) __CONCAT1(__X, __Y)
      5 #define __CONCAT1(__X, __Y) __X ## __Y
      6 
      7 #define static_assert(__b, __m) \
      8   typedef int __CONCAT(__sa, __LINE__)[__b ? 1 : -1]
      9 #endif
     10 
     11 union IncompleteUnion;
     12 
     13 static_assert(!__is_abstract(IncompleteUnion), "unions are never abstract");
     14 
     15 class C {
     16   virtual void f() = 0; // expected-note {{unimplemented pure virtual method 'f'}}
     17 };
     18 
     19 static_assert(__is_abstract(C), "C has a pure virtual function");
     20 
     21 class D : C {
     22 };
     23 
     24 static_assert(__is_abstract(D), "D inherits from an abstract class");
     25 
     26 class E : D {
     27   virtual void f();
     28 };
     29 
     30 static_assert(!__is_abstract(E), "E inherits from an abstract class but implements f");
     31 
     32 C *d = new C; // expected-error {{allocating an object of abstract class type 'C'}}
     33 
     34 C c; // expected-error {{variable type 'C' is an abstract class}}
     35 void t1(C c); // expected-error {{parameter type 'C' is an abstract class}}
     36 void t2(C); // expected-error {{parameter type 'C' is an abstract class}}
     37 
     38 struct S {
     39   C c; // expected-error {{field type 'C' is an abstract class}}
     40 };
     41 
     42 void t3(const C&);
     43 
     44 void f() {
     45   C(); // expected-error {{allocating an object of abstract class type 'C'}}
     46   t3(C()); // expected-error {{allocating an object of abstract class type 'C'}}
     47 }
     48 
     49 C e1[2]; // expected-error {{array of abstract class type 'C'}}
     50 C (*e2)[2]; // expected-error {{array of abstract class type 'C'}}
     51 C (**e3)[2]; // expected-error {{array of abstract class type 'C'}}
     52 
     53 void t4(C c[2]); // expected-error {{array of abstract class type 'C'}}
     54 
     55 void t5(void (*)(C)); // expected-error {{parameter type 'C' is an abstract class}}
     56 
     57 typedef void (*Func)(C); // expected-error {{parameter type 'C' is an abstract class}}
     58 void t6(Func);
     59 
     60 class F {
     61   F a() { while (1) {} } // expected-error {{return type 'F' is an abstract class}}
     62 
     63   class D {
     64     void f(F c); // expected-error {{parameter type 'F' is an abstract class}}
     65   };
     66 
     67   union U {
     68     void u(F c); // expected-error {{parameter type 'F' is an abstract class}}
     69   };
     70 
     71   virtual void f() = 0; // expected-note {{unimplemented pure virtual method 'f'}}
     72 };
     73 
     74 // Diagnosing in these cases is prohibitively expensive.  We still
     75 // diagnose at the function definition, of course.
     76 
     77 class Abstract;
     78 
     79 void t7(Abstract a);
     80 
     81 void t8() {
     82   void h(Abstract a);
     83 }
     84 
     85 namespace N {
     86 void h(Abstract a);
     87 }
     88 
     89 class Abstract {
     90   virtual void f() = 0;
     91 };
     92 
     93 // <rdar://problem/6854087>
     94 class foo {
     95 public:
     96   virtual foo *getFoo() = 0;
     97 };
     98 
     99 class bar : public foo {
    100 public:
    101   virtual bar *getFoo();
    102 };
    103 
    104 bar x;
    105 
    106 // <rdar://problem/6902298>
    107 class A {
    108 public:
    109   virtual void release() = 0;
    110   virtual void release(int count) = 0;
    111   virtual void retain() = 0;
    112 };
    113 
    114 class B : public A {
    115 public:
    116   virtual void release();
    117   virtual void release(int count);
    118   virtual void retain();
    119 };
    120 
    121 void foo(void) {
    122   B b;
    123 }
    124 
    125 struct K {
    126  int f;
    127  virtual ~K();
    128 };
    129 
    130 struct L : public K {
    131  void f();
    132 };
    133 
    134 // PR5222
    135 namespace PR5222 {
    136   struct A {
    137     virtual A *clone() = 0;
    138   };
    139   struct B : public A {
    140     virtual B *clone() = 0;
    141   };
    142   struct C : public B {
    143     virtual C *clone();
    144   };
    145 
    146   C c;
    147 }
    148 
    149 // PR5550 - instantiating template didn't track overridden methods
    150 namespace PR5550 {
    151   struct A {
    152     virtual void a() = 0;
    153     virtual void b() = 0;
    154   };
    155   template<typename T> struct B : public A {
    156     virtual void b();
    157     virtual void c() = 0;
    158   };
    159   struct C : public B<int> {
    160     virtual void a();
    161     virtual void c();
    162   };
    163   C x;
    164 }
    165 
    166 namespace PureImplicit {
    167   // A pure virtual destructor should be implicitly overridden.
    168   struct A { virtual ~A() = 0; };
    169   struct B : A {};
    170   B x;
    171 
    172   // A pure virtual assignment operator should be implicitly overridden.
    173   struct D;
    174   struct C { virtual D& operator=(const D&) = 0; };
    175   struct D : C {};
    176   D y;
    177 }
    178 
    179 namespace test1 {
    180   struct A {
    181     virtual void foo() = 0;
    182   };
    183 
    184   struct B : A {
    185     using A::foo;
    186   };
    187 
    188   struct C : B {
    189     void foo();
    190   };
    191 
    192   void test() {
    193     C c;
    194   }
    195 }
    196 
    197 // rdar://problem/8302168
    198 namespace test2 {
    199   struct X1 {
    200     virtual void xfunc(void) = 0;  // expected-note {{unimplemented pure virtual method}}
    201     void g(X1 parm7);        // expected-error {{parameter type 'test2::X1' is an abstract class}}
    202     void g(X1 parm8[2]);     // expected-error {{array of abstract class type 'test2::X1'}}
    203   };
    204 
    205   template <int N>
    206   struct X2 {
    207     virtual void xfunc(void) = 0;  // expected-note {{unimplemented pure virtual method}}
    208     void g(X2 parm10);        // expected-error {{parameter type 'X2<N>' is an abstract class}}
    209     void g(X2 parm11[2]);     // expected-error {{array of abstract class type 'X2<N>'}}
    210   };
    211 }
    212 
    213 namespace test3 {
    214   struct A { // expected-note {{not complete until}}
    215     A x; // expected-error {{field has incomplete type}}
    216     virtual void abstract() = 0;
    217   };
    218 
    219   struct B { // expected-note {{not complete until}}
    220     virtual void abstract() = 0;
    221     B x; // expected-error {{field has incomplete type}}
    222   };
    223 
    224   struct C {
    225     static C x; // expected-error {{abstract class}}
    226     virtual void abstract() = 0; // expected-note {{unimplemented pure virtual method}}
    227   };
    228 
    229   struct D {
    230     virtual void abstract() = 0; // expected-note {{unimplemented pure virtual method}}
    231     static D x; // expected-error {{abstract class}}
    232   };
    233 }
    234 
    235 namespace test4 {
    236   template <class T> struct A {
    237     A x; // expected-error {{abstract class}}
    238     virtual void abstract() = 0; // expected-note {{unimplemented pure virtual method}}
    239   };
    240 
    241   template <class T> struct B {
    242     virtual void abstract() = 0; // expected-note {{unimplemented pure virtual method}}
    243     B x; // expected-error {{abstract class}}
    244   };
    245 
    246   template <class T> struct C {
    247     static C x; // expected-error {{abstract class}}
    248     virtual void abstract() = 0; // expected-note {{unimplemented pure virtual method}}
    249   };
    250 
    251   template <class T> struct D {
    252     virtual void abstract() = 0; // expected-note {{unimplemented pure virtual method}}
    253     static D x; // expected-error {{abstract class}}
    254   };
    255 }
    256 
    257 namespace test5 {
    258   struct A { A(int); virtual ~A() = 0; }; // expected-note {{pure virtual method}}
    259   const A &a = 0; // expected-error {{abstract class}}
    260   void f(const A &a = 0); // expected-error {{abstract class}}
    261   void g() { f(0); } // expected-error {{abstract class}}
    262 }
    263 
    264 // PR9247: Crash on invalid in clang::Sema::ActOnFinishCXXMemberSpecification
    265 namespace pr9247 {
    266   struct A {
    267     virtual void g(const A& input) = 0;
    268     struct B {
    269       C* f(int foo);
    270     };
    271   };
    272 }
    273 
    274 namespace pr12658 {
    275   class C {
    276     public:
    277       C(int v){}
    278       virtual void f() = 0; // expected-note {{unimplemented pure virtual method 'f' in 'C'}}
    279   };
    280 
    281   void foo( C& c ) {}
    282 
    283   void bar( void ) {
    284     foo(C(99)); // expected-error {{allocating an object of abstract class type 'pr12658::C'}}
    285   }
    286 }
    287 
    288 namespace pr16659 {
    289   struct A {
    290     A(int);
    291     virtual void x() = 0; // expected-note {{unimplemented pure virtual method 'x' in 'RedundantInit'}}
    292   };
    293   struct B : virtual A {};
    294   struct C : B {
    295     C() : A(37) {}
    296     void x() override {}
    297   };
    298 
    299   struct X {
    300     friend class Z;
    301   private:
    302     X &operator=(const X&);
    303   };
    304   struct Y : virtual X { // expected-note {{::X' has an inaccessible copy assignment}}
    305     virtual ~Y() = 0;
    306   };
    307   struct Z : Y {}; // expected-note {{::Y' has a deleted copy assignment}}
    308   void f(Z &a, const Z &b) { a = b; } // expected-error {{copy assignment operator is implicitly deleted}}
    309 
    310   struct RedundantInit : virtual A {
    311     RedundantInit() : A(0) {} // expected-warning {{initializer for virtual base class 'pr16659::A' of abstract class 'RedundantInit' will never be used}}
    312   };
    313 }
    314