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(); }; // expected-note+ {{candidate constructor}}
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 {{no viable conversion from 'Z' to 'const Y'}}
90    const int& y12{z};
91
92    // X is not an aggregate, so constructors are considered.
93    // However, by 13.3.3.1/4, only standard conversion sequences and
94    // ellipsis conversion sequences are considered here, so this is not
95    // allowed.
96    // FIXME: It's not really clear that this is a sensible restriction for this
97    // case. g++ allows this, EDG does not.
98    const X x1{z}; // expected-error {{no matching constructor}}
99    const X& x2{z}; // expected-error {{no matching constructor}}
100  }
101
102  void testBool() {
103    struct Bool {
104      operator bool();
105    };
106
107    struct NotBool {
108      explicit operator bool(); // expected-note {{conversion to integral type 'bool'}}
109    };
110    Bool    b;
111    NotBool n;
112
113    (void) (1 + b);
114    (void) (1 + n); // expected-error {{invalid operands to binary expression ('int' and 'NotBool')}}
115
116    // 5.3.1p9:
117    (void) (!b);
118    (void) (!n);
119
120    // 5.14p1:
121    (void) (b && true);
122    (void) (n && true);
123
124    // 5.15p1:
125    (void) (b || true);
126    (void) (n || true);
127
128    // 5.16p1:
129    (void) (b ? 0 : 1);
130    (void) (n ? 0: 1);
131
132    // 5.19p5:
133    // TODO: After constexpr has been implemented
134
135    // 6.4p4:
136    if (b) {}
137    if (n) {}
138
139    // 6.4.2p2:
140    switch (b) {} // expected-warning {{switch condition has boolean value}}
141    switch (n) {} // expected-error {{switch condition type 'NotBool' requires explicit conversion to 'bool'}} \
142                     expected-warning {{switch condition has boolean value}}
143
144    // 6.5.1:
145    while (b) {}
146    while (n) {}
147
148    // 6.5.2p1:
149    do {} while (b);
150    do {} while (n);
151
152    // 6.5.3:
153    for (;b;) {}
154    for (;n;) {}
155
156    // 13.3.1.5p1:
157    bool direct1(b);
158    bool direct2(n);
159    int direct3(b);
160    int direct4(n); // expected-error {{no viable conversion}}
161    const bool &direct5(b);
162    const bool &direct6(n);
163    const int &direct7(b);
164    const int &direct8(n); // expected-error {{no viable conversion}}
165    bool directList1{b};
166    bool directList2{n};
167    int directList3{b};
168    int directList4{n}; // expected-error {{no viable conversion}}
169    const bool &directList5{b};
170    const bool &directList6{n};
171    const int &directList7{b};
172    const int &directList8{n}; // expected-error {{no viable conversion}}
173    bool copy1 = b;
174    bool copy2 = n; // expected-error {{no viable conversion}}
175    int copy3 = b;
176    int copy4 = n; // expected-error {{no viable conversion}}
177    const bool &copy5 = b;
178    const bool &copy6 = n; // expected-error {{no viable conversion}}
179    const int &copy7 = b;
180    const int &copy8 = n; // expected-error {{no viable conversion}}
181    bool copyList1 = {b};
182    bool copyList2 = {n}; // expected-error {{no viable conversion}}
183    int copyList3 = {b};
184    int copyList4 = {n}; // expected-error {{no viable conversion}}
185    const bool &copyList5 = {b};
186    const bool &copyList6 = {n}; // expected-error {{no viable conversion}}
187    const int &copyList7 = {b};
188    const int &copyList8 = {n}; // expected-error {{no viable conversion}}
189  }
190
191  void testNew()
192  {
193    // 5.3.4p6:
194    struct Int {
195      operator int();
196    };
197    struct NotInt {
198      explicit operator int(); // expected-note {{conversion to integral type 'int' declared here}}
199    };
200
201    Int    i;
202    NotInt ni;
203
204    new int[i];
205    new int[ni]; // expected-error {{array size expression of type 'NotInt' requires explicit conversion to type 'int'}}
206  }
207
208  void testDelete()
209  {
210    // 5.3.5pp2:
211    struct Ptr {
212      operator int*();
213    };
214    struct NotPtr {
215      explicit operator int*(); // expected-note {{conversion}}
216    };
217
218    Ptr    p;
219    NotPtr np;
220
221    delete p;
222    delete np; // expected-error {{converting delete expression from type 'NotPtr' to type 'int *' invokes an explicit conversion function}}
223  }
224
225  void testFunctionPointer()
226  {
227    // 13.3.1.1.2p2:
228    using Func = void(*)(int);
229
230    struct FP {
231      operator Func();
232    };
233    struct NotFP {
234      explicit operator Func();
235    };
236
237    FP    fp;
238    NotFP nfp;
239    fp(1);
240    nfp(1); // expected-error {{type 'NotFP' does not provide a call operator}}
241  }
242}
243
244namespace pr8264 {
245  struct Test {
246  explicit explicit Test(int x);  // expected-warning{{duplicate 'explicit' declaration specifier}}
247  };
248}
249
250namespace PR18777 {
251  struct S { explicit operator bool() const; } s;
252  int *p = new int(s); // expected-error {{no viable conversion}}
253}
254