Home | History | Annotate | Download | only in SemaTemplate
      1 // RUN: %clang_cc1 -triple %itanium_abi_triple -fsyntax-only -verify %s
      2 // RUN: %clang_cc1 -triple %ms_abi_triple -DMSABI -fsyntax-only -verify %s
      3 
      4 namespace PR5557 {
      5 template <class T> struct A {
      6   A(); // expected-note{{instantiation}}
      7   virtual int a(T x);
      8 };
      9 template<class T> A<T>::A() {}
     10 
     11 template<class T> int A<T>::a(T x) {
     12   return *x; // expected-error{{requires pointer operand}}
     13 }
     14 
     15 void f() {
     16   A<int> x; // expected-note{{instantiation}}
     17 }
     18 
     19 template<typename T>
     20 struct X {
     21   virtual void f();
     22 };
     23 
     24 template<>
     25 void X<int>::f() { }
     26 }
     27 
     28 // Like PR5557, but with a defined destructor instead of a defined constructor.
     29 namespace PR5557_dtor {
     30 template <class T> struct A {
     31   A(); // Don't have an implicit constructor.
     32   ~A(); // expected-note{{instantiation}}
     33   virtual int a(T x);
     34 };
     35 template<class T> A<T>::~A() {}
     36 
     37 template<class T> int A<T>::a(T x) {
     38   return *x; // expected-error{{requires pointer operand}}
     39 }
     40 
     41 void f() {
     42   A<int> x; // expected-note{{instantiation}}
     43 }
     44 }
     45 
     46 template<typename T>
     47 struct Base {
     48   virtual ~Base() {
     49     int *ptr = 0;
     50     T t = ptr; // expected-error{{cannot initialize}}
     51   }
     52 };
     53 
     54 template<typename T>
     55 struct Derived : Base<T> {
     56   virtual void foo() { }
     57 };
     58 
     59 template struct Derived<int>; // expected-note {{in instantiation of member function 'Base<int>::~Base' requested here}}
     60 
     61 template<typename T>
     62 struct HasOutOfLineKey {
     63   HasOutOfLineKey() { } // expected-note{{in instantiation of member function 'HasOutOfLineKey<int>::f' requested here}}
     64   virtual T *f(float *fp);
     65 };
     66 
     67 template<typename T>
     68 T *HasOutOfLineKey<T>::f(float *fp) {
     69   return fp; // expected-error{{cannot initialize return object of type 'int *' with an lvalue of type 'float *'}}
     70 }
     71 
     72 HasOutOfLineKey<int> out_of_line; // expected-note{{in instantiation of member function 'HasOutOfLineKey<int>::HasOutOfLineKey' requested here}}
     73 
     74 namespace std {
     75   class type_info;
     76 }
     77 
     78 namespace PR7114 {
     79   class A { virtual ~A(); }; // expected-note{{declared private here}}
     80 
     81   template<typename T>
     82   class B {
     83   public:
     84     class Inner : public A { }; // expected-error{{base class 'PR7114::A' has private destructor}}
     85     static Inner i;
     86     static const unsigned value = sizeof(i) == 4;
     87   };
     88 
     89   int f() { return B<int>::value; }
     90 
     91 #ifdef MSABI
     92   void test_typeid(B<float>::Inner bfi) { // expected-note{{implicit destructor}}
     93     (void)typeid(bfi);
     94 #else
     95   void test_typeid(B<float>::Inner bfi) {
     96     (void)typeid(bfi); // expected-note{{implicit destructor}}
     97 #endif
     98   }
     99 
    100   template<typename T>
    101   struct X : A {
    102     void f() { }
    103   };
    104 
    105   void test_X(X<int> &xi, X<float> &xf) {
    106     xi.f();
    107   }
    108 }
    109 
    110 namespace DynamicCast {
    111   struct Y {};
    112   template<typename T> struct X : virtual Y {
    113     virtual void foo() { T x; }
    114   };
    115   template<typename T> struct X2 : virtual Y {
    116     virtual void foo() { T x; }
    117   };
    118   Y* f(X<void>* x) { return dynamic_cast<Y*>(x); }
    119   Y* f2(X<void>* x) { return dynamic_cast<Y*>(x); }
    120 }
    121 
    122 namespace avoid_using_vtable {
    123 // We shouldn't emit the vtable for this code, in any ABI.  If we emit the
    124 // vtable, we emit an implicit virtual dtor, which calls ~RefPtr, which requires
    125 // a complete type for DeclaredOnly.
    126 //
    127 // Previously we would reference the vtable in the MS C++ ABI, even though we
    128 // don't need to emit either the ctor or the dtor.  In the Itanium C++ ABI, the
    129 // 'trace' method is the key function, so even though we use the vtable, we
    130 // don't emit it.
    131 
    132 template <typename T>
    133 struct RefPtr {
    134   T *m_ptr;
    135   ~RefPtr() { m_ptr->deref(); }
    136 };
    137 struct DeclaredOnly;
    138 struct Base {
    139   virtual ~Base();
    140 };
    141 
    142 struct AvoidVTable : Base {
    143   RefPtr<DeclaredOnly> m_insertionStyle;
    144   virtual void trace();
    145   AvoidVTable();
    146 };
    147 // Don't call the dtor, because that will emit an implicit dtor, and require a
    148 // complete type for DeclaredOnly.
    149 void foo() { new AvoidVTable; }
    150 }
    151 
    152 namespace vtable_uses_incomplete {
    153 // Opposite of the previous test that avoids a vtable, this one tests that we
    154 // use the vtable when the ctor is defined inline.
    155 template <typename T>
    156 struct RefPtr {
    157   T *m_ptr;
    158   ~RefPtr() { m_ptr->deref(); }  // expected-error {{member access into incomplete type 'vtable_uses_incomplete::DeclaredOnly'}}
    159 };
    160 struct DeclaredOnly; // expected-note {{forward declaration of 'vtable_uses_incomplete::DeclaredOnly'}}
    161 struct Base {
    162   virtual ~Base();
    163 };
    164 
    165 struct UsesVTable : Base {
    166   RefPtr<DeclaredOnly> m_insertionStyle;
    167   virtual void trace();
    168   UsesVTable() {} // expected-note {{in instantiation of member function 'vtable_uses_incomplete::RefPtr<vtable_uses_incomplete::DeclaredOnly>::~RefPtr' requested here}}
    169 };
    170 }
    171