blob: 71680d4dde442a6df59d7c5dc81a87787bb95171 [file] [log] [blame]
Anders Carlsson7a6e13a2010-01-24 17:15:04 +00001// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s
2namespace 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}} \
44 expected-note {{candidate constructor (the implicit copy constructor) not viable: no known conversion from 'Conversion::Z' to 'const Conversion::Y &' for 1st argument}} \
45 expected-note {{candidate constructor (the implicit copy constructor) not viable: no known conversion from 'Conversion::Z' to 'const Conversion::Y' for 1st argument}} \
46 expected-note {{andidate constructor (the implicit default constructor) not viable: requires 0 arguments, but 1 was provided}} \
47 expected-note {{candidate constructor (the implicit copy constructor) not viable: no known conversion from 'Conversion::Z' to 'const Conversion::Y' for 1st argument}} \
48 expected-note {{candidate constructor (the implicit default constructor) not viable: requires 0 arguments, but 1 was provided}} \
49 expected-note {{candidate constructor (the implicit copy constructor) not viable: no known conversion from 'Conversion::Z' to 'const Conversion::Y' for 1st argument}} \
50 expected-note {{candidate constructor (the implicit default constructor) not viable: requires 0 arguments, but 1 was provided}}
51 struct Z {
52 explicit operator Y() const;
53 explicit operator int() const;
54 };
55
56 Z z;
57 // 13.3.1.4p1 & 8.5p16:
58 Y y2 = z; // expected-error {{no viable conversion from 'Conversion::Z' to 'Conversion::Y'}}
59 // FIXME: These are well-formed per C++0x 13.3.1.4p1 (see DR899).
60 Y y3 = (Y)z; // expected-error {{no matching conversion for C-style cast from 'Conversion::Z' to 'Conversion::Y''}}
61 Y y4 = Y(z); // expected-error {{no matching conversion for functional-style cast from 'Conversion::Z' to 'Conversion::Y'}}
62 Y y5 = static_cast<Y>(z); // expected-error {{no matching conversion for static_cast from 'Conversion::Z' to 'Conversion::Y'}}
63 // 13.3.1.5p1 & 8.5p16:
64 int i1 = (int)z;
65 int i2 = int(z);
66 int i3 = static_cast<int>(z);
67 int i4(z);
68 // 13.3.1.6p1 & 8.5.3p5:
69 const Y& y6 = z; // expected-error {{no viable conversion from 'Conversion::Z' to 'const Conversion::Y'}}
70 const int& y7(z);
71 }
72
73 void testBool() {
74 struct Bool {
75 operator bool();
76 };
77
78 struct NotBool {
79 explicit operator bool(); // expected-note {{conversion to integral type 'bool'}}
80 };
81 Bool b;
82 NotBool n;
83
84 (void) (1 + b);
85 (void) (1 + n); // expected-error {{invalid operands to binary expression ('int' and 'Conversion::NotBool')}}
86
87 // 5.3.1p9:
88 (void) (!b);
89 (void) (!n);
90
91 // 5.14p1:
92 (void) (b && true);
93 (void) (n && true);
94
95 // 5.15p1:
96 (void) (b || true);
97 (void) (n || true);
98
99 // 5.16p1:
100 (void) (b ? 0 : 1);
101 (void) (n ? 0: 1);
102
103 // 5.19p5:
104 // TODO: After constexpr has been implemented
105
106 // 6.4p4:
107 if (b) {}
108 if (n) {}
109
110 // 6.4.2p2:
111 switch (b) {} // expected-warning {{switch condition has boolean value}}
112 switch (n) {} // expected-error {{switch condition type 'Conversion::NotBool' requires explicit conversion to 'bool'}} \
113 expected-warning {{switch condition has boolean value}}
114
115 // 6.5.1:
116 while (b) {}
117 while (n) {}
118
119 // 6.5.2p1:
120 do {} while (b);
121 do {} while (n);
122
123 // 6.5.3:
124 for (;b;) {}
125 for (;n;) {}
126 }
127
128 void testNew()
129 {
130 // 5.3.4p6:
131 struct Int {
132 operator int();
133 };
134 struct NotInt {
135 explicit operator int(); // expected-note {{conversion to integral type 'int' declared here}}
136 };
137
138 Int i;
139 NotInt ni;
140
141 new int[i];
142 new int[ni]; // expected-error {{array size expression of type 'Conversion::NotInt' requires explicit conversion to type 'int'}}
143 }
144
145 void testDelete()
146 {
147 // 5.3.5pp2:
148 struct Ptr {
149 operator int*();
150 };
151 struct NotPtr {
152 explicit operator int*();
153 };
154
155 Ptr p;
156 NotPtr np;
157
158 delete p;
159 delete np; // expected-error {{cannot delete expression of type 'Conversion::NotPtr'}}
160 }
161
162 void testFunctionPointer()
163 {
164 // 13.3.1.1.2p2:
165 using Func = void(*)(int);
166
167 struct FP {
168 operator Func();
169 };
170 struct NotFP {
171 explicit operator Func();
172 };
173
174 FP fp;
175 NotFP nfp;
176 fp(1);
177 nfp(1); // expected-error {{type 'Conversion::NotFP' does not provide a call operator}}
178 }
Anders Carlsson7a6e13a2010-01-24 17:15:04 +0000179}