1 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
2 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++2a %s
3 
4 namespace Constructor {
5 struct A {
6   A(int);
7 };
8 
9 struct B { // expected-note+ {{candidate}}
10   explicit B(int); // expected-note {{not a candidate}}
11 };
12 
B(int)13 B::B(int) { } // expected-note+ {{here}}
14 
15 struct C {
16   void f(const A&);
17   void f(const B&);
18 };
19 
f(C c)20 void f(C c) {
21   c.f(10);
22 }
23 
24 A a0 = 0;
25 A a1(0);
26 A &&a2 = 0;
27 A &&a3(0);
28 A a4{0};
29 A &&a5 = {0};
30 A &&a6{0};
31 
32 B b0 = 0; // expected-error {{no viable conversion}}
33 B b1(0);
34 B &&b2 = 0; // expected-error {{could not bind}}
35 B &&b3(0); // expected-error {{could not bind}}
36 B b4{0};
37 B &&b5 = {0}; // expected-error {{chosen constructor is explicit}}
38 B &&b6{0};
39 
40 struct S {
41   template <bool b = true>
42   explicit S();
43 };
44 
45 struct T : S {
46   //  T();
47 };
48 
49 struct U : T {
50   U();
51 };
U()52 U::U() {}
53 
54 }
55 
56 namespace Conversion {
57   struct A {
58     operator int();
59     explicit operator bool();
60   };
61 
operator bool()62   A::operator bool() { return false; }
63 
64   struct B {
65     void f(int);
66     void f(bool);
67   };
68 
f(A a,B b)69   void f(A a, B b) {
70     b.f(a);
71   }
72 
testExplicit()73   void testExplicit()
74   {
75     // Taken from 12.3.2p2
76     class X { X(); };
77     class Y { }; // expected-note+ {{candidate constructor (the implicit}}
78 
79     struct Z {
80       explicit operator X() const;
81       explicit operator Y() const; // expected-note 2{{not a candidate}}
82       explicit operator int() const; // expected-note {{not a candidate}}
83     };
84 
85     Z z;
86     // 13.3.1.4p1 & 8.5p16:
87     Y y2 = z; // expected-error {{no viable conversion from 'Z' to 'Y'}}
88     Y y2b(z);
89     Y y3 = (Y)z;
90     Y y4 = Y(z);
91     Y y5 = static_cast<Y>(z);
92     // 13.3.1.5p1 & 8.5p16:
93     int i1 = (int)z;
94     int i2 = int(z);
95     int i3 = static_cast<int>(z);
96     int i4(z);
97     // 13.3.1.6p1 & 8.5.3p5:
98     const Y& y6 = z; // expected-error {{no viable conversion from 'Z' to 'const Y'}}
99     const int& y7 = z; // expected-error {{no viable conversion from 'Z' to 'const int'}}
100     const Y& y8(z);
101     const int& y9(z);
102 
103     // Y is an aggregate, so aggregate-initialization is performed and the
104     // conversion function is not considered.
105     const Y y10{z}; // expected-error {{excess elements}}
106     const Y& y11{z}; // expected-error {{excess elements}} expected-note {{in initialization of temporary of type 'const Y'}}
107     const int& y12{z};
108 
109     // X is not an aggregate, so constructors are considered,
110     // per 13.3.3.1/4 & DR1467.
111     const X x1{z};
112     const X& x2{z};
113   }
114 
testBool()115   void testBool() {
116     struct Bool {
117       operator bool();
118     };
119 
120     struct NotBool {
121       explicit operator bool(); // expected-note {{conversion to integral type 'bool'}} expected-note 4{{explicit conversion function is not a candidate}}
122     };
123     Bool    b;
124     NotBool n;
125 
126     (void) (1 + b);
127     (void) (1 + n); // expected-error {{invalid operands to binary expression ('int' and 'NotBool')}}
128 
129     // 5.3.1p9:
130     (void) (!b);
131     (void) (!n);
132 
133     // 5.14p1:
134     (void) (b && true);
135     (void) (n && true);
136 
137     // 5.15p1:
138     (void) (b || true);
139     (void) (n || true);
140 
141     // 5.16p1:
142     (void) (b ? 0 : 1);
143     (void) (n ? 0: 1);
144 
145     // 5.19p5:
146     // TODO: After constexpr has been implemented
147 
148     // 6.4p4:
149     if (b) {}
150     if (n) {}
151 
152     // 6.4.2p2:
153     switch (b) {} // expected-warning {{switch condition has boolean value}}
154     switch (n) {} // expected-error {{switch condition type 'NotBool' requires explicit conversion to 'bool'}} \
155                      expected-warning {{switch condition has boolean value}}
156 
157     // 6.5.1:
158     while (b) {}
159     while (n) {}
160 
161     // 6.5.2p1:
162     do {} while (b);
163     do {} while (n);
164 
165     // 6.5.3:
166     for (;b;) {}
167     for (;n;) {}
168 
169     // 13.3.1.5p1:
170     bool direct1(b);
171     bool direct2(n);
172     int direct3(b);
173     int direct4(n); // expected-error {{no viable conversion}}
174     const bool &direct5(b);
175     const bool &direct6(n);
176     const int &direct7(b);
177     const int &direct8(n); // expected-error {{no viable conversion}}
178     bool directList1{b};
179     bool directList2{n};
180     int directList3{b};
181     int directList4{n}; // expected-error {{no viable conversion}}
182     const bool &directList5{b};
183     const bool &directList6{n};
184     const int &directList7{b};
185     const int &directList8{n}; // expected-error {{no viable conversion}}
186     bool copy1 = b;
187     bool copy2 = n; // expected-error {{no viable conversion}}
188     int copy3 = b;
189     int copy4 = n; // expected-error {{no viable conversion}}
190     const bool &copy5 = b;
191     const bool &copy6 = n; // expected-error {{no viable conversion}}
192     const int &copy7 = b;
193     const int &copy8 = n; // expected-error {{no viable conversion}}
194     bool copyList1 = {b};
195     bool copyList2 = {n}; // expected-error {{no viable conversion}}
196     int copyList3 = {b};
197     int copyList4 = {n}; // expected-error {{no viable conversion}}
198     const bool &copyList5 = {b};
199     const bool &copyList6 = {n}; // expected-error {{no viable conversion}}
200     const int &copyList7 = {b};
201     const int &copyList8 = {n}; // expected-error {{no viable conversion}}
202   }
203 
204 #if __cplusplus < 201707L
testNew()205   void testNew()
206   {
207     // 5.3.4p6:
208     struct Int {
209       operator int();
210     };
211     struct NotInt {
212       explicit operator int(); // expected-note {{conversion to integral type 'int' declared here}}
213     };
214 
215     Int    i;
216     NotInt ni;
217 
218     new int[i];
219     new int[ni]; // expected-error {{array size expression of type 'NotInt' requires explicit conversion to type 'int'}}
220   }
221 #endif
222 
testDelete()223   void testDelete()
224   {
225     // 5.3.5pp2:
226     struct Ptr {
227       operator int*();
228     };
229     struct NotPtr {
230       explicit operator int*(); // expected-note {{conversion}}
231     };
232 
233     Ptr    p;
234     NotPtr np;
235 
236     delete p;
237     delete np; // expected-error {{converting delete expression from type 'NotPtr' to type 'int *' invokes an explicit conversion function}}
238   }
239 
testFunctionPointer()240   void testFunctionPointer()
241   {
242     // 13.3.1.1.2p2:
243     using Func = void(*)(int);
244 
245     struct FP {
246       operator Func();
247     };
248     struct NotFP {
249       explicit operator Func();
250     };
251 
252     FP    fp;
253     NotFP nfp;
254     fp(1);
255     nfp(1); // expected-error {{type 'NotFP' does not provide a call operator}}
256   }
257 }
258 
259 namespace pr8264 {
260   struct Test {
261   explicit explicit Test(int x);  // expected-warning{{duplicate 'explicit' declaration specifier}}
262   };
263 }
264 
265 namespace PR18777 {
266   struct S { explicit operator bool() const; } s;
267   int *p = new int(s); // expected-error {{no viable conversion}}
268 }
269