blob: 5ce2cf19132ca1d3ebfb467f8bbc36a2df46877b [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
Eli Friedman9dd686d2012-10-24 20:28:18 +000043 class Y { }; // expected-note {{candidate constructor (the implicit copy constructor) not viable: no known conversion from 'Z' to 'const Y &' for 1st argument}} \
44 expected-note {{candidate constructor (the implicit move constructor) not viable: no known conversion from 'Z' to 'Y &&' for 1st argument}} \
45 expected-note {{candidate constructor (the implicit copy constructor) not viable: no known conversion from 'Z' to 'const Y &' for 1st argument}} \
46 expected-note {{candidate constructor (the implicit move constructor) not viable: no known conversion from 'Z' to 'Y &&' for 1st argument}}
Douglas Gregored878af2012-02-24 23:56:31 +000047
Douglas Gregorbf6e3172011-07-23 18:59:35 +000048 struct Z {
49 explicit operator Y() const;
50 explicit operator int() const;
51 };
52
53 Z z;
54 // 13.3.1.4p1 & 8.5p16:
Eli Friedman9dd686d2012-10-24 20:28:18 +000055 Y y2 = z; // expected-error {{no viable conversion from 'Z' to 'Y'}}
Douglas Gregored878af2012-02-24 23:56:31 +000056 Y y3 = (Y)z;
57 Y y4 = Y(z);
58 Y y5 = static_cast<Y>(z);
Douglas Gregorbf6e3172011-07-23 18:59:35 +000059 // 13.3.1.5p1 & 8.5p16:
60 int i1 = (int)z;
61 int i2 = int(z);
62 int i3 = static_cast<int>(z);
63 int i4(z);
64 // 13.3.1.6p1 & 8.5.3p5:
Eli Friedman9dd686d2012-10-24 20:28:18 +000065 const Y& y6 = z; // expected-error {{no viable conversion from 'Z' to 'const Y'}}
Douglas Gregorbf6e3172011-07-23 18:59:35 +000066 const int& y7(z);
67 }
68
69 void testBool() {
70 struct Bool {
71 operator bool();
72 };
73
74 struct NotBool {
75 explicit operator bool(); // expected-note {{conversion to integral type 'bool'}}
76 };
77 Bool b;
78 NotBool n;
79
80 (void) (1 + b);
Eli Friedman9dd686d2012-10-24 20:28:18 +000081 (void) (1 + n); // expected-error {{invalid operands to binary expression ('int' and 'NotBool')}}
Douglas Gregorbf6e3172011-07-23 18:59:35 +000082
83 // 5.3.1p9:
84 (void) (!b);
85 (void) (!n);
86
87 // 5.14p1:
88 (void) (b && true);
89 (void) (n && true);
90
91 // 5.15p1:
92 (void) (b || true);
93 (void) (n || true);
94
95 // 5.16p1:
96 (void) (b ? 0 : 1);
97 (void) (n ? 0: 1);
98
99 // 5.19p5:
100 // TODO: After constexpr has been implemented
101
102 // 6.4p4:
103 if (b) {}
104 if (n) {}
105
106 // 6.4.2p2:
107 switch (b) {} // expected-warning {{switch condition has boolean value}}
Eli Friedman9dd686d2012-10-24 20:28:18 +0000108 switch (n) {} // expected-error {{switch condition type 'NotBool' requires explicit conversion to 'bool'}} \
Douglas Gregorbf6e3172011-07-23 18:59:35 +0000109 expected-warning {{switch condition has boolean value}}
110
111 // 6.5.1:
112 while (b) {}
113 while (n) {}
114
115 // 6.5.2p1:
116 do {} while (b);
117 do {} while (n);
118
119 // 6.5.3:
120 for (;b;) {}
121 for (;n;) {}
122 }
123
124 void testNew()
125 {
126 // 5.3.4p6:
127 struct Int {
128 operator int();
129 };
130 struct NotInt {
131 explicit operator int(); // expected-note {{conversion to integral type 'int' declared here}}
132 };
133
134 Int i;
135 NotInt ni;
136
137 new int[i];
Eli Friedman9dd686d2012-10-24 20:28:18 +0000138 new int[ni]; // expected-error {{array size expression of type 'NotInt' requires explicit conversion to type 'int'}}
Douglas Gregorbf6e3172011-07-23 18:59:35 +0000139 }
140
141 void testDelete()
142 {
143 // 5.3.5pp2:
144 struct Ptr {
145 operator int*();
146 };
147 struct NotPtr {
148 explicit operator int*();
149 };
150
151 Ptr p;
152 NotPtr np;
153
154 delete p;
Eli Friedman9dd686d2012-10-24 20:28:18 +0000155 delete np; // expected-error {{cannot delete expression of type 'NotPtr'}}
Douglas Gregorbf6e3172011-07-23 18:59:35 +0000156 }
157
158 void testFunctionPointer()
159 {
160 // 13.3.1.1.2p2:
161 using Func = void(*)(int);
162
163 struct FP {
164 operator Func();
165 };
166 struct NotFP {
167 explicit operator Func();
168 };
169
170 FP fp;
171 NotFP nfp;
172 fp(1);
Eli Friedman9dd686d2012-10-24 20:28:18 +0000173 nfp(1); // expected-error {{type 'NotFP' does not provide a call operator}}
Douglas Gregorbf6e3172011-07-23 18:59:35 +0000174 }
Anders Carlsson7a6e13a2010-01-24 17:15:04 +0000175}