blob: 477463771e8869c9a3422d4be7a6fc22c3896f09 [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}} \
Douglas Gregored878af2012-02-24 23:56:31 +000046 expected-note {{candidate constructor (the implicit move constructor) not viable: no known conversion from 'Conversion::Z' to 'Conversion::Y &&' for 1st argument}}
47
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:
55 Y y2 = z; // expected-error {{no viable conversion from 'Conversion::Z' to 'Conversion::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:
65 const Y& y6 = z; // expected-error {{no viable conversion from 'Conversion::Z' to 'const Conversion::Y'}}
66 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);
81 (void) (1 + n); // expected-error {{invalid operands to binary expression ('int' and 'Conversion::NotBool')}}
82
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}}
108 switch (n) {} // expected-error {{switch condition type 'Conversion::NotBool' requires explicit conversion to 'bool'}} \
109 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];
138 new int[ni]; // expected-error {{array size expression of type 'Conversion::NotInt' requires explicit conversion to type 'int'}}
139 }
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;
155 delete np; // expected-error {{cannot delete expression of type 'Conversion::NotPtr'}}
156 }
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);
173 nfp(1); // expected-error {{type 'Conversion::NotFP' does not provide a call operator}}
174 }
Anders Carlsson7a6e13a2010-01-24 17:15:04 +0000175}