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