1 // RUN: %clang_cc1 -fsyntax-only -Wbind-to-temporary-copy -verify %s 2 class X { 3 public: 4 operator bool(); 5 operator int() const; 6 f()7 bool f() { 8 return operator bool(); 9 } 10 g()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 18 operator int(); // expected-error{{conversion function must be a non-static member function}} 19 20 operator int; // expected-error{{'operator int' cannot be the name of a variable or data member}} 21 22 typedef int func_type(int); 23 typedef int array_type[10]; 24 25 class Y { 26 public: 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 41 typedef int INT; 42 typedef INT* INT_PTR; 43 44 class 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 53 class A { }; 54 55 class B : public A { 56 public: 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. 63 struct Flip; 64 struct Flop { 65 Flop(); 66 Flop(const Flip&); // expected-note{{candidate constructor}} 67 }; 68 struct Flip { 69 operator Flop() const; // expected-note{{candidate function}} 70 }; 71 Flop 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 74 struct C { 75 operator const char *() const; 76 }; 77 operator const char*() const78 C::operator const char*() const { return 0; } 79 f(const C & c)80 void f(const C& c) { 81 const char* v = c; 82 } 83 84 // Test. Conversion in base class is visible in derived class. 85 class XB { 86 public: 87 operator int(); // expected-note {{candidate function}} 88 }; 89 90 class Yb : public XB { 91 public: 92 operator char(); // expected-note {{candidate function}} 93 }; 94 f(Yb & a)95 void 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. 102 class AutoPtrRef { }; 103 104 class AutoPtr { 105 AutoPtr(AutoPtr &); // expected-note{{declared private here}} 106 107 public: 108 AutoPtr(); 109 AutoPtr(AutoPtrRef); 110 111 operator AutoPtrRef(); 112 }; 113 114 AutoPtr make_auto_ptr(); 115 test_auto_ptr(bool Cond)116 AutoPtr 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 126 struct A1 { 127 A1(const char *); 128 ~A1(); 129 130 private: 131 A1(const A1&); // expected-note 2 {{declared private here}} 132 }; 133 f()134 A1 f() { 135 // FIXME: redundant diagnostics! 136 return "Hello"; // expected-error {{calling a private constructor}} expected-warning {{an accessible copy constructor}} 137 } 138 139 namespace 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 f()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 173 namespace crazy_declarators { 174 struct A { 175 (&operator bool())(); // expected-error {{use a typedef to declare a conversion to 'bool (&)()'}} 176 *operator int(); // expected-error {{put the complete type after 'operator'}} 177 // No suggestion of using a typedef here; that's not possible. 178 template<typename T> (&operator T())(); // expected-error-re {{cannot specify any part of a return type in the declaration of a conversion function{{$}}}} 179 }; 180 } 181 182 namespace smart_ptr { 183 class Y { 184 class YRef { }; 185 186 Y(Y&); 187 188 public: 189 Y(); 190 Y(YRef); 191 192 operator YRef(); // expected-note{{candidate function}} 193 }; 194 195 struct X { // expected-note{{candidate constructor (the implicit copy constructor) not}} 196 explicit X(Y); 197 }; 198 199 Y make_Y(); 200 f()201 X f() { 202 X x = make_Y(); // expected-error{{no viable conversion from 'smart_ptr::Y' to 'smart_ptr::X'}} 203 X x2(make_Y()); 204 return X(Y()); 205 } 206 } 207 208 struct Any { 209 Any(...); 210 }; 211 212 struct Other { 213 Other(const Other &); 214 Other(); 215 }; 216 test_any()217 void test_any() { 218 Any any = Other(); // expected-error{{cannot pass object of non-POD type 'Other' through variadic constructor; call will abort at runtime}} 219 } 220 221 namespace PR7055 { 222 // Make sure that we don't allow too many conversions in an 223 // auto_ptr-like template. In particular, we can't create multiple 224 // temporary objects when binding to a reference. 225 struct auto_ptr { 226 struct auto_ptr_ref { }; 227 228 auto_ptr(auto_ptr&); 229 auto_ptr(auto_ptr_ref); 230 explicit auto_ptr(int *); 231 232 operator auto_ptr_ref(); 233 }; 234 235 struct X { 236 X(auto_ptr); 237 }; 238 f()239 X f() { 240 X x(auto_ptr(new int)); 241 return X(auto_ptr(new int)); 242 } 243 244 auto_ptr foo(); 245 246 X e(foo()); 247 248 struct Y { 249 Y(X); 250 }; 251 252 Y f2(foo()); 253 } 254 255 namespace PR7934 { 256 typedef unsigned char uint8; 257 258 struct MutablePtr { MutablePtrPR7934::MutablePtr259 MutablePtr() : ptr(0) {} 260 void *ptr; 261 operator void*PR7934::MutablePtr262 operator void*() { return ptr; } 263 264 private: operator uint8*PR7934::MutablePtr265 operator uint8*() { return reinterpret_cast<uint8*>(ptr); } operator const char*PR7934::MutablePtr266 operator const char*() const { return reinterpret_cast<const char*>(ptr); } 267 }; 268 269 void fake_memcpy(const void *); 270 use()271 void use() { 272 MutablePtr ptr; 273 fake_memcpy(ptr); 274 } 275 } 276 277 namespace rdar8018274 { 278 struct X { }; 279 struct Y { 280 operator const struct X *() const; 281 }; 282 283 struct Z : Y { 284 operator struct X * (); 285 }; 286 test()287 void test() { 288 Z x; 289 (void) (x != __null); 290 } 291 292 293 struct Base { 294 operator int(); 295 }; 296 297 struct Derived1 : Base { }; 298 299 struct Derived2 : Base { }; 300 301 struct SuperDerived : Derived1, Derived2 { 302 using Derived1::operator int; 303 }; 304 305 struct UeberDerived : SuperDerived { 306 operator long(); 307 }; 308 test2(UeberDerived ud)309 void test2(UeberDerived ud) { 310 int i = ud; // expected-error{{ambiguous conversion from derived class 'rdar8018274::SuperDerived' to base class 'rdar8018274::Base'}} 311 } 312 313 struct Base2 { 314 operator int(); 315 }; 316 317 struct Base3 { 318 operator int(); 319 }; 320 321 struct Derived23 : Base2, Base3 { 322 using Base2::operator int; 323 }; 324 325 struct ExtraDerived23 : Derived23 { }; 326 test3(ExtraDerived23 ed)327 void test3(ExtraDerived23 ed) { 328 int i = ed; 329 } 330 } 331 332 namespace PR8065 { 333 template <typename T> struct Iterator; 334 template <typename T> struct Container; 335 336 template<> 337 struct Iterator<int> { 338 typedef Container<int> container_type; 339 }; 340 341 template <typename T> 342 struct Container { 343 typedef typename Iterator<T>::container_type X; operator XPR8065::Container344 operator X(void) { return X(); } 345 }; 346 347 Container<int> test; 348 } 349 350 namespace PR8034 { 351 struct C { 352 operator int(); 353 354 private: 355 template <typename T> operator T(); 356 }; 357 int x = C().operator int(); 358 } 359 360 namespace PR9336 { 361 template<class T> 362 struct generic_list 363 { 364 template<class Container> operator ContainerPR9336::generic_list365 operator Container() 366 { 367 Container ar; 368 T* i; 369 ar[0]=*i; 370 return ar; 371 } 372 }; 373 374 template<class T> 375 struct array 376 { 377 T& operator[](int); 378 const T& operator[](int)const; 379 }; 380 381 generic_list<generic_list<int> > l; 382 array<array<int> > a = l; 383 } 384 385 namespace PR8800 { 386 struct A; 387 struct C { 388 operator A&(); 389 }; f()390 void f() { 391 C c; 392 A& a1(c); 393 A& a2 = c; 394 A& a3 = static_cast<A&>(c); 395 A& a4 = (A&)c; 396 } 397 } 398 399 namespace PR12712 { 400 struct A {}; 401 struct B { 402 operator A(); 403 operator A() const; 404 }; 405 struct C : B {}; 406 f(const C c)407 A f(const C c) { return c; } 408 } 409 410 namespace PR18234 { 411 struct A { 412 operator enum E { e } (); // expected-error {{'PR18234::A::E' cannot be defined in a type specifier}} 413 operator struct S { int n; } (); // expected-error {{'PR18234::A::S' cannot be defined in a type specifier}} 414 } a; 415 A::S s = a; 416 A::E e = a; // expected-note {{here}} 417 bool k1 = e == A::e; // expected-error {{no member named 'e'}} 418 bool k2 = e.n == 0; 419 } 420