blob: 12f0ca2643efcafae745a37bba42c8071c8797a1 [file] [log] [blame]
Richard Smith762bb9d2011-10-13 22:29:44 +00001// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
Anders Carlsson7a6e13a2010-01-24 17:15:04 +00002namespace Constructor {
3struct A {
4 A(int);
5};
6
7struct B {
8 explicit B(int);
9};
10
11B::B(int) { }
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}
22
23namespace Conversion {
24 struct A {
25 operator int();
26 explicit operator bool();
27 };
28
29 A::operator bool() { return false; }
30
31 struct B {
32 void f(int);
33 void f(bool);
34 };
35
36 void f(A a, B b) {
37 b.f(a);
38 }
Douglas Gregorbf6e3172011-07-23 18:59:35 +000039
40 void testExplicit()
41 {
42 // Taken from 12.3.2p2
43 class Y { }; // expected-note {{candidate constructor (the implicit copy constructor) not viable: no known conversion from 'Conversion::Z' to 'const Conversion::Y &' for 1st argument}} \
Sebastian Redl85ea7aa2011-08-30 19:58:05 +000044 expected-note {{candidate constructor (the implicit move constructor) not viable: no known conversion from 'Conversion::Z' to 'Conversion::Y &&' for 1st argument}} \
Douglas Gregorbf6e3172011-07-23 18:59:35 +000045 expected-note {{candidate constructor (the implicit copy constructor) not viable: no known conversion from 'Conversion::Z' to 'const Conversion::Y &' for 1st argument}} \
Sebastian Redl85ea7aa2011-08-30 19:58:05 +000046 expected-note {{candidate constructor (the implicit move constructor) not viable: no known conversion from 'Conversion::Z' to 'Conversion::Y' for 1st argument}} \
Douglas Gregorbf6e3172011-07-23 18:59:35 +000047 expected-note {{candidate constructor (the implicit copy constructor) not viable: no known conversion from 'Conversion::Z' to 'const Conversion::Y' for 1st argument}} \
Sebastian Redl85ea7aa2011-08-30 19:58:05 +000048 expected-note {{candidate constructor (the implicit move constructor) not viable: no known conversion from 'Conversion::Z' to 'Conversion::Y' for 1st argument}} \
Douglas Gregorbf6e3172011-07-23 18:59:35 +000049 expected-note {{candidate constructor (the implicit default constructor) not viable: requires 0 arguments, but 1 was provided}} \
50 expected-note {{candidate constructor (the implicit copy constructor) not viable: no known conversion from 'Conversion::Z' to 'const Conversion::Y' for 1st argument}} \
Sebastian Redl85ea7aa2011-08-30 19:58:05 +000051 expected-note {{candidate constructor (the implicit move constructor) not viable: no known conversion from 'Conversion::Z' to 'Conversion::Y' for 1st argument}} \
52 expected-note {{candidate constructor (the implicit default constructor) not viable: requires 0 arguments, but 1 was provided}} \
53 expected-note {{candidate constructor (the implicit copy constructor) not viable: no known conversion from 'Conversion::Z' to 'const Conversion::Y' for 1st argument}} \
54 expected-note {{candidate constructor (the implicit move constructor) not viable: no known conversion from 'Conversion::Z' to 'Conversion::Y &&' for 1st argument}} \
Douglas Gregorbf6e3172011-07-23 18:59:35 +000055 expected-note {{candidate constructor (the implicit default constructor) not viable: requires 0 arguments, but 1 was provided}}
56 struct Z {
57 explicit operator Y() const;
58 explicit operator int() const;
59 };
60
61 Z z;
62 // 13.3.1.4p1 & 8.5p16:
63 Y y2 = z; // expected-error {{no viable conversion from 'Conversion::Z' to 'Conversion::Y'}}
64 // FIXME: These are well-formed per C++0x 13.3.1.4p1 (see DR899).
Richard Trieu2fe9b7f2011-12-15 00:38:15 +000065 Y y3 = (Y)z; // expected-error {{no matching conversion for C-style cast from 'Conversion::Z' to 'Conversion::Y'}}
Douglas Gregorbf6e3172011-07-23 18:59:35 +000066 Y y4 = Y(z); // expected-error {{no matching conversion for functional-style cast from 'Conversion::Z' to 'Conversion::Y'}}
67 Y y5 = static_cast<Y>(z); // expected-error {{no matching conversion for static_cast from 'Conversion::Z' to 'Conversion::Y'}}
68 // 13.3.1.5p1 & 8.5p16:
69 int i1 = (int)z;
70 int i2 = int(z);
71 int i3 = static_cast<int>(z);
72 int i4(z);
73 // 13.3.1.6p1 & 8.5.3p5:
74 const Y& y6 = z; // expected-error {{no viable conversion from 'Conversion::Z' to 'const Conversion::Y'}}
75 const int& y7(z);
76 }
77
78 void testBool() {
79 struct Bool {
80 operator bool();
81 };
82
83 struct NotBool {
84 explicit operator bool(); // expected-note {{conversion to integral type 'bool'}}
85 };
86 Bool b;
87 NotBool n;
88
89 (void) (1 + b);
90 (void) (1 + n); // expected-error {{invalid operands to binary expression ('int' and 'Conversion::NotBool')}}
91
92 // 5.3.1p9:
93 (void) (!b);
94 (void) (!n);
95
96 // 5.14p1:
97 (void) (b && true);
98 (void) (n && true);
99
100 // 5.15p1:
101 (void) (b || true);
102 (void) (n || true);
103
104 // 5.16p1:
105 (void) (b ? 0 : 1);
106 (void) (n ? 0: 1);
107
108 // 5.19p5:
109 // TODO: After constexpr has been implemented
110
111 // 6.4p4:
112 if (b) {}
113 if (n) {}
114
115 // 6.4.2p2:
116 switch (b) {} // expected-warning {{switch condition has boolean value}}
117 switch (n) {} // expected-error {{switch condition type 'Conversion::NotBool' requires explicit conversion to 'bool'}} \
118 expected-warning {{switch condition has boolean value}}
119
120 // 6.5.1:
121 while (b) {}
122 while (n) {}
123
124 // 6.5.2p1:
125 do {} while (b);
126 do {} while (n);
127
128 // 6.5.3:
129 for (;b;) {}
130 for (;n;) {}
131 }
132
133 void testNew()
134 {
135 // 5.3.4p6:
136 struct Int {
137 operator int();
138 };
139 struct NotInt {
140 explicit operator int(); // expected-note {{conversion to integral type 'int' declared here}}
141 };
142
143 Int i;
144 NotInt ni;
145
146 new int[i];
147 new int[ni]; // expected-error {{array size expression of type 'Conversion::NotInt' requires explicit conversion to type 'int'}}
148 }
149
150 void testDelete()
151 {
152 // 5.3.5pp2:
153 struct Ptr {
154 operator int*();
155 };
156 struct NotPtr {
157 explicit operator int*();
158 };
159
160 Ptr p;
161 NotPtr np;
162
163 delete p;
164 delete np; // expected-error {{cannot delete expression of type 'Conversion::NotPtr'}}
165 }
166
167 void testFunctionPointer()
168 {
169 // 13.3.1.1.2p2:
170 using Func = void(*)(int);
171
172 struct FP {
173 operator Func();
174 };
175 struct NotFP {
176 explicit operator Func();
177 };
178
179 FP fp;
180 NotFP nfp;
181 fp(1);
182 nfp(1); // expected-error {{type 'Conversion::NotFP' does not provide a call operator}}
183 }
Anders Carlsson7a6e13a2010-01-24 17:15:04 +0000184}