1 // RUN: %clang_cc1 -fsyntax-only -verify %s 2 class X { 3 public: 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 16 operator int(); // expected-error{{conversion function must be a non-static member function}} 17 18 operator int; // expected-error{{'operator int' cannot be the name of a variable or data member}} 19 20 typedef int func_type(int); 21 typedef int array_type[10]; 22 23 class Y { 24 public: 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 36 typedef int INT; 37 typedef INT* INT_PTR; 38 39 class 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 48 class A { }; 49 50 class B : public A { 51 public: 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 'void const' 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. 58 struct Flip; 59 struct Flop { 60 Flop(); 61 Flop(const Flip&); // expected-note{{candidate constructor}} 62 }; 63 struct Flip { 64 operator Flop() const; // expected-note{{candidate function}} 65 }; 66 Flop 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 69 struct C { 70 operator const char *() const; 71 }; 72 73 C::operator const char*() const { return 0; } 74 75 void f(const C& c) { 76 const char* v = c; 77 } 78 79 // Test. Conversion in base class is visible in derived class. 80 class XB { 81 public: 82 operator int(); // expected-note {{candidate function}} 83 }; 84 85 class Yb : public XB { 86 public: 87 operator char(); // expected-note {{candidate function}} 88 }; 89 90 void 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. 97 class AutoPtrRef { }; 98 99 class AutoPtr { 100 // FIXME: Using 'unavailable' since we do not have access control yet. 101 // FIXME: The error message isn't so good. 102 AutoPtr(AutoPtr &) __attribute__((unavailable)); // expected-note{{explicitly marked}} 103 104 public: 105 AutoPtr(); 106 AutoPtr(AutoPtrRef); 107 108 operator AutoPtrRef(); 109 }; 110 111 AutoPtr make_auto_ptr(); 112 113 AutoPtr test_auto_ptr(bool Cond) { 114 AutoPtr p1( make_auto_ptr() ); 115 116 AutoPtr p; 117 if (Cond) 118 return p; // expected-error{{call to deleted constructor}} 119 120 return AutoPtr(); 121 } 122 123 struct A1 { 124 A1(const char *); 125 ~A1(); 126 127 private: 128 A1(const A1&) __attribute__((unavailable)); // expected-note{{here}} 129 }; 130 131 A1 f() { 132 return "Hello"; // expected-error{{invokes deleted constructor}} 133 } 134 135 namespace source_locations { 136 template<typename T> 137 struct sneaky_int { 138 typedef int type; 139 }; 140 141 template<typename T, typename U> 142 struct A { }; 143 144 template<typename T> 145 struct A<T, T> : A<T, int> { }; 146 147 struct E { 148 template<typename T> 149 operator A<T, typename sneaky_int<T>::type>&() const; // expected-note{{candidate function}} 150 }; 151 152 void f() { 153 A<float, float> &af = E(); // expected-error{{no viable conversion}} 154 A<float, int> &af2 = E(); 155 const A<float, int> &caf2 = E(); 156 } 157 158 // Check 159 template<typename T> 160 struct E2 { 161 operator T 162 * // expected-error{{pointer to a reference}} 163 () const; 164 }; 165 166 E2<int&> e2i; // expected-note{{in instantiation}} 167 } 168 169 namespace crazy_declarators { 170 struct A { 171 (&operator bool())(); // expected-error {{must use a typedef to declare a conversion to 'bool (&)()'}} 172 173 // FIXME: This diagnostic is misleading (the correct spelling 174 // would be 'operator int*'), but it's a corner case of a 175 // rarely-used syntax extension. 176 *operator int(); // expected-error {{must use a typedef to declare a conversion to 'int *'}} 177 }; 178 } 179 180 namespace smart_ptr { 181 class Y { 182 class YRef { }; 183 184 Y(Y&); 185 186 public: 187 Y(); 188 Y(YRef); 189 190 operator YRef(); // expected-note{{candidate function}} 191 }; 192 193 struct X { // expected-note{{candidate constructor (the implicit copy constructor) not}} 194 explicit X(Y); 195 }; 196 197 Y make_Y(); 198 199 X f() { 200 X x = make_Y(); // expected-error{{no viable conversion from 'smart_ptr::Y' to 'smart_ptr::X'}} 201 X x2(make_Y()); 202 return X(Y()); 203 } 204 } 205 206 struct Any { 207 Any(...); 208 }; 209 210 struct Other { 211 Other(const Other &); 212 Other(); 213 }; 214 215 void test_any() { 216 Any any = Other(); // expected-error{{cannot pass object of non-POD type 'Other' through variadic constructor; call will abort at runtime}} 217 } 218