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