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