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