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