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