1 | // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s |
2 | namespace Constructor { |
3 | struct A { |
4 | A(int); |
5 | }; |
6 | |
7 | struct B { // expected-note+ {{candidate}} |
8 | explicit B(int); |
9 | }; |
10 | |
11 | B::B(int) { } // expected-note+ {{here}} |
12 | |
13 | struct C { |
14 | void f(const A&); |
15 | void f(const B&); |
16 | }; |
17 | |
18 | void f(C c) { |
19 | c.f(10); |
20 | } |
21 | |
22 | A a0 = 0; |
23 | A a1(0); |
24 | A &&a2 = 0; |
25 | A &&a3(0); |
26 | A a4{0}; |
27 | A &&a5 = {0}; |
28 | A &&a6{0}; |
29 | |
30 | B b0 = 0; // expected-error {{no viable conversion}} |
31 | B b1(0); |
32 | B &&b2 = 0; // expected-error {{could not bind}} |
33 | B &&b3(0); // expected-error {{could not bind}} |
34 | B b4{0}; |
35 | B &&b5 = {0}; // expected-error {{chosen constructor is explicit}} |
36 | B &&b6{0}; |
37 | } |
38 | |
39 | namespace 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 ©5 = b; |
174 | const bool ©6 = n; // expected-error {{no viable conversion}} |
175 | const int ©7 = b; |
176 | const int ©8 = 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 ©List5 = {b}; |
182 | const bool ©List6 = {n}; // expected-error {{no viable conversion}} |
183 | const int ©List7 = {b}; |
184 | const int ©List8 = {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 | |
240 | namespace pr8264 { |
241 | struct Test { |
242 | explicit explicit Test(int x); // expected-warning{{duplicate 'explicit' declaration specifier}} |
243 | }; |
244 | } |
245 | |
246 | namespace PR18777 { |
247 | struct S { explicit operator bool() const; } s; |
248 | int *p = new int(s); // expected-error {{no viable conversion}} |
249 | } |
250 | |