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 4namespace PR5557 { 5template <class T> struct A { 6 A(); // expected-note{{instantiation}} 7 virtual int a(T x); 8}; 9template<class T> A<T>::A() {} 10 11template<class T> int A<T>::a(T x) { 12 return *x; // expected-error{{requires pointer operand}} 13} 14 15void f() { 16 A<int> x; // expected-note{{instantiation}} 17} 18 19template<typename T> 20struct X { 21 virtual void f(); 22}; 23 24template<> 25void X<int>::f() { } 26} 27 28// Like PR5557, but with a defined destructor instead of a defined constructor. 29namespace PR5557_dtor { 30template <class T> struct A { 31 A(); // Don't have an implicit constructor. 32 ~A(); // expected-note{{instantiation}} 33 virtual int a(T x); 34}; 35template<class T> A<T>::~A() {} 36 37template<class T> int A<T>::a(T x) { 38 return *x; // expected-error{{requires pointer operand}} 39} 40 41void f() { 42 A<int> x; // expected-note{{instantiation}} 43} 44} 45 46template<typename T> 47struct Base { 48 virtual ~Base() { 49 int *ptr = 0; 50 T t = ptr; // expected-error{{cannot initialize}} 51 } 52}; 53 54template<typename T> 55struct Derived : Base<T> { 56 virtual void foo() { } 57}; 58 59template struct Derived<int>; // expected-note {{in instantiation of member function 'Base<int>::~Base' requested here}} 60 61template<typename T> 62struct HasOutOfLineKey { 63 HasOutOfLineKey() { } // expected-note{{in instantiation of member function 'HasOutOfLineKey<int>::f' requested here}} 64 virtual T *f(float *fp); 65}; 66 67template<typename T> 68T *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 72HasOutOfLineKey<int> out_of_line; // expected-note{{in instantiation of member function 'HasOutOfLineKey<int>::HasOutOfLineKey' requested here}} 73 74namespace std { 75 class type_info; 76} 77 78namespace 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 110namespace 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 122namespace 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 132template <typename T> 133struct RefPtr { 134 T *m_ptr; 135 ~RefPtr() { m_ptr->deref(); } 136}; 137struct DeclaredOnly; 138struct Base { 139 virtual ~Base(); 140}; 141 142struct 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. 149void foo() { new AvoidVTable; } 150} 151 152namespace 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. 155template <typename T> 156struct RefPtr { 157 T *m_ptr; 158 ~RefPtr() { m_ptr->deref(); } // expected-error {{member access into incomplete type 'vtable_uses_incomplete::DeclaredOnly'}} 159}; 160struct DeclaredOnly; // expected-note {{forward declaration of 'vtable_uses_incomplete::DeclaredOnly'}} 161struct Base { 162 virtual ~Base(); 163}; 164 165struct 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