1// RUN: %clang_cc1 -fsyntax-only -verify %s 2class X { 3public: 4 operator bool(); 5 operator int() const; 6 7 bool f() { 8 return operator bool(); 9 } 10 11 float g() { 12 return operator float(); // expected-error{{use of undeclared 'operator float'}} 13 } 14 15 static operator short(); // expected-error{{conversion function must be a non-static member function}} 16}; 17 18operator int(); // expected-error{{conversion function must be a non-static member function}} 19 20operator int; // expected-error{{'operator int' cannot be the name of a variable or data member}} 21 22typedef int func_type(int); 23typedef int array_type[10]; 24 25class Y { 26public: 27 void operator bool(int, ...) const; // expected-error{{conversion function cannot have a return type}} \ 28 // expected-error{{conversion function cannot have any parameters}} 29 30 operator float(...) const; // expected-error{{conversion function cannot be variadic}} 31 32 33 operator func_type(); // expected-error{{conversion function cannot convert to a function type}} 34 operator array_type(); // expected-error{{conversion function cannot convert to an array type}} 35}; 36 37 38typedef int INT; 39typedef INT* INT_PTR; 40 41class Z { 42 operator int(); // expected-note {{previous declaration is here}} 43 operator int**(); // expected-note {{previous declaration is here}} 44 45 operator INT(); // expected-error{{conversion function cannot be redeclared}} 46 operator INT_PTR*(); // expected-error{{conversion function cannot be redeclared}} 47}; 48 49 50class A { }; 51 52class B : public A { 53public: 54 operator A&() const; // expected-warning{{conversion function converting 'B' to its base class 'A' will never be used}} 55 operator const void() const; // expected-warning{{conversion function converting 'B' to 'const void' will never be used}} 56 operator const B(); // expected-warning{{conversion function converting 'B' to itself will never be used}} 57}; 58 59// This used to crash Clang. 60struct Flip; 61struct Flop { 62 Flop(); 63 Flop(const Flip&); // expected-note{{candidate constructor}} 64}; 65struct Flip { 66 operator Flop() const; // expected-note{{candidate function}} 67}; 68Flop flop = Flip(); // expected-error {{conversion from 'Flip' to 'Flop' is ambiguous}} 69 70// This tests that we don't add the second conversion declaration to the list of user conversions 71struct C { 72 operator const char *() const; 73}; 74 75C::operator const char*() const { return 0; } 76 77void f(const C& c) { 78 const char* v = c; 79} 80 81// Test. Conversion in base class is visible in derived class. 82class XB { 83public: 84 operator int(); // expected-note {{candidate function}} 85}; 86 87class Yb : public XB { 88public: 89 operator char(); // expected-note {{candidate function}} 90}; 91 92void f(Yb& a) { 93 if (a) { } // expected-error {{conversion from 'Yb' to 'bool' is ambiguous}} 94 int i = a; // OK. calls XB::operator int(); 95 char ch = a; // OK. calls Yb::operator char(); 96} 97 98// Test conversion + copy construction. 99class AutoPtrRef { }; 100 101class AutoPtr { 102 AutoPtr(AutoPtr &); // expected-note{{declared private here}} 103 104public: 105 AutoPtr(); 106 AutoPtr(AutoPtrRef); 107 108 operator AutoPtrRef(); 109}; 110 111AutoPtr make_auto_ptr(); 112 113AutoPtr test_auto_ptr(bool Cond) { 114 AutoPtr p1( make_auto_ptr() ); 115 116 AutoPtr p; 117 if (Cond) 118 return p; // expected-error{{calling a private constructor}} 119 120 return AutoPtr(); 121} 122 123struct A1 { 124 A1(const char *); 125 ~A1(); 126 127private: 128 A1(const A1&); // expected-note 2 {{declared private here}} 129}; 130 131A1 f() { 132 // FIXME: redundant diagnostics! 133 return "Hello"; // expected-error {{calling a private constructor}} expected-warning {{an accessible copy constructor}} 134} 135 136namespace source_locations { 137 template<typename T> 138 struct sneaky_int { 139 typedef int type; 140 }; 141 142 template<typename T, typename U> 143 struct A { }; 144 145 template<typename T> 146 struct A<T, T> : A<T, int> { }; 147 148 struct E { 149 template<typename T> 150 operator A<T, typename sneaky_int<T>::type>&() const; // expected-note{{candidate function}} 151 }; 152 153 void f() { 154 A<float, float> &af = E(); // expected-error{{no viable conversion}} 155 A<float, int> &af2 = E(); 156 const A<float, int> &caf2 = E(); 157 } 158 159 // Check 160 template<typename T> 161 struct E2 { 162 operator T 163 * // expected-error{{pointer to a reference}} 164 () const; 165 }; 166 167 E2<int&> e2i; // expected-note{{in instantiation}} 168} 169 170namespace crazy_declarators { 171 struct A { 172 (&operator bool())(); // expected-error {{must use a typedef to declare a conversion to 'bool (&)()'}} 173 174 // FIXME: This diagnostic is misleading (the correct spelling 175 // would be 'operator int*'), but it's a corner case of a 176 // rarely-used syntax extension. 177 *operator int(); // expected-error {{must use a typedef to declare a conversion to 'int *'}} 178 }; 179} 180 181namespace smart_ptr { 182 class Y { 183 class YRef { }; 184 185 Y(Y&); 186 187 public: 188 Y(); 189 Y(YRef); 190 191 operator YRef(); // expected-note{{candidate function}} 192 }; 193 194 struct X { // expected-note{{candidate constructor (the implicit copy constructor) not}} 195 explicit X(Y); 196 }; 197 198 Y make_Y(); 199 200 X f() { 201 X x = make_Y(); // expected-error{{no viable conversion from 'smart_ptr::Y' to 'smart_ptr::X'}} 202 X x2(make_Y()); 203 return X(Y()); 204 } 205} 206 207struct Any { 208 Any(...); 209}; 210 211struct Other { 212 Other(const Other &); 213 Other(); 214}; 215 216void test_any() { 217 Any any = Other(); // expected-error{{cannot pass object of non-POD type 'Other' through variadic constructor; call will abort at runtime}} 218} 219 220namespace PR7055 { 221 // Make sure that we don't allow too many conversions in an 222 // auto_ptr-like template. In particular, we can't create multiple 223 // temporary objects when binding to a reference. 224 struct auto_ptr { 225 struct auto_ptr_ref { }; 226 227 auto_ptr(auto_ptr&); 228 auto_ptr(auto_ptr_ref); 229 explicit auto_ptr(int *); 230 231 operator auto_ptr_ref(); 232 }; 233 234 struct X { 235 X(auto_ptr); 236 }; 237 238 X f() { 239 X x(auto_ptr(new int)); 240 return X(auto_ptr(new int)); 241 } 242 243 auto_ptr foo(); 244 245 X e(foo()); 246 247 struct Y { 248 Y(X); 249 }; 250 251 Y f2(foo()); 252} 253 254namespace PR7934 { 255 typedef unsigned char uint8; 256 257 struct MutablePtr { 258 MutablePtr() : ptr(0) {} 259 void *ptr; 260 261 operator void*() { return ptr; } 262 263 private: 264 operator uint8*() { return reinterpret_cast<uint8*>(ptr); } 265 operator const char*() const { return reinterpret_cast<const char*>(ptr); } 266 }; 267 268 void fake_memcpy(const void *); 269 270 void use() { 271 MutablePtr ptr; 272 fake_memcpy(ptr); 273 } 274} 275 276namespace rdar8018274 { 277 struct X { }; 278 struct Y { 279 operator const struct X *() const; 280 }; 281 282 struct Z : Y { 283 operator struct X * (); 284 }; 285 286 void test() { 287 Z x; 288 (void) (x != __null); 289 } 290 291 292 struct Base { 293 operator int(); 294 }; 295 296 struct Derived1 : Base { }; 297 298 struct Derived2 : Base { }; 299 300 struct SuperDerived : Derived1, Derived2 { 301 using Derived1::operator int; 302 }; 303 304 struct UeberDerived : SuperDerived { 305 operator long(); 306 }; 307 308 void test2(UeberDerived ud) { 309 int i = ud; // expected-error{{ambiguous conversion from derived class 'rdar8018274::SuperDerived' to base class 'rdar8018274::Base'}} 310 } 311 312 struct Base2 { 313 operator int(); 314 }; 315 316 struct Base3 { 317 operator int(); 318 }; 319 320 struct Derived23 : Base2, Base3 { 321 using Base2::operator int; 322 }; 323 324 struct ExtraDerived23 : Derived23 { }; 325 326 void test3(ExtraDerived23 ed) { 327 int i = ed; 328 } 329} 330 331namespace PR8065 { 332 template <typename T> struct Iterator; 333 template <typename T> struct Container; 334 335 template<> 336 struct Iterator<int> { 337 typedef Container<int> container_type; 338 }; 339 340 template <typename T> 341 struct Container { 342 typedef typename Iterator<T>::container_type X; 343 operator X(void) { return X(); } 344 }; 345 346 Container<int> test; 347} 348 349namespace PR8034 { 350 struct C { 351 operator int(); 352 353 private: 354 template <typename T> operator T(); 355 }; 356 int x = C().operator int(); 357} 358 359namespace PR9336 { 360 template<class T> 361 struct generic_list 362 { 363 template<class Container> 364 operator Container() 365 { 366 Container ar; 367 T* i; 368 ar[0]=*i; 369 return ar; 370 } 371 }; 372 373 template<class T> 374 struct array 375 { 376 T& operator[](int); 377 const T& operator[](int)const; 378 }; 379 380 generic_list<generic_list<int> > l; 381 array<array<int> > a = l; 382} 383 384namespace PR8800 { 385 struct A; 386 struct C { 387 operator A&(); 388 }; 389 void f() { 390 C c; 391 A& a1(c); 392 A& a2 = c; 393 A& a3 = static_cast<A&>(c); 394 A& a4 = (A&)c; 395 } 396} 397 398namespace PR12712 { 399 struct A {}; 400 struct B { 401 operator A(); 402 operator A() const; 403 }; 404 struct C : B {}; 405 406 A f(const C c) { return c; } 407} 408