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