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