Richard Smith | 76b9027 | 2019-05-09 03:59:21 +0000 | [diff] [blame] | 1 | // RUN: %clang_cc1 -std=c++2a -fsyntax-only %s -verify |
| 2 | |
| 3 | template <bool b, auto val> struct enable_ifv {}; |
| 4 | |
| 5 | template <auto val> struct enable_ifv<true, val> { |
| 6 | static constexpr auto value = val; |
| 7 | }; |
| 8 | |
| 9 | template <typename T1, typename T2> struct is_same { |
| 10 | static constexpr bool value = false; |
| 11 | }; |
| 12 | |
| 13 | template <typename T> struct is_same<T, T> { |
| 14 | static constexpr bool value = true; |
| 15 | }; |
| 16 | |
| 17 | namespace special_cases |
| 18 | { |
| 19 | |
| 20 | template<int a> |
| 21 | struct A { |
| 22 | // expected-note@-1+ {{candidate constructor}} |
| 23 | explicit(1 << a) |
| 24 | // expected-note@-1 {{negative shift count -1}} |
| 25 | // expected-error@-2 {{explicit specifier argument is not a constant expression}} |
| 26 | A(int); |
| 27 | }; |
| 28 | |
| 29 | A<-1> a(0); |
| 30 | // expected-error@-1 {{no matching constructor}} |
| 31 | // expected-note@-2 {{in instantiation of template class}} |
| 32 | |
| 33 | template<int a> |
| 34 | struct B { |
| 35 | explicit(b) |
| 36 | // expected-error@-1 {{use of undeclared identifier}} |
| 37 | B(int); |
| 38 | }; |
| 39 | |
| 40 | template<int a> |
| 41 | struct B1 { |
| 42 | explicit(a +) |
| 43 | // expected-error@-1 {{expected expression}} |
| 44 | B1(int); |
| 45 | }; |
| 46 | |
| 47 | struct B2 { |
| 48 | explicit(false) explicit |
| 49 | B2(int); |
| 50 | // expected-error@-2 {{duplicate 'explicit' declaration specifier}} |
| 51 | }; |
| 52 | |
| 53 | template<int a> |
| 54 | struct C { |
| 55 | // expected-note@-1 {{candidate constructor}} expected-note@-1 {{candidate constructor}} |
| 56 | // expected-note@-2 {{candidate constructor}} expected-note@-2 {{candidate constructor}} |
| 57 | explicit(a == 0) |
| 58 | C(int), |
| 59 | C(double); |
| 60 | }; |
| 61 | |
| 62 | C<0> c0 = 0.0; // expected-error {{no viable conversion}} |
| 63 | C<0> c1 = 0; // expected-error {{no viable conversion}} |
| 64 | C<1> c2 = 0.0; |
| 65 | C<1> c3 = 0; |
| 66 | |
| 67 | explicit(false) void f(int);// expected-error {{'explicit' can only be specified inside the class definition}} |
| 68 | |
| 69 | struct D { |
| 70 | explicit(false) void f(int);// expected-error {{'explicit' can only be applied to a constructor or conversion function}} |
| 71 | }; |
| 72 | |
| 73 | template <typename T> struct E { |
| 74 | // expected-note@-1+ {{candidate constructor}} |
| 75 | explicit((T{}, false)) |
| 76 | // expected-error@-1 {{illegal initializer type 'void'}} |
| 77 | E(int); |
| 78 | }; |
| 79 | |
| 80 | E<void> e = 1; |
| 81 | // expected-error@-1 {{no viable conversion}} |
| 82 | // expected-note@-2 {{in instantiation of}} |
| 83 | |
| 84 | } |
| 85 | |
| 86 | namespace trailling_object { |
| 87 | |
| 88 | template<bool b> |
| 89 | struct B { |
| 90 | explicit(b) B(int) {} |
| 91 | }; |
| 92 | |
| 93 | template<bool b> |
| 94 | struct A : B<b> { |
| 95 | explicit(b) A(int) : B<b>(0) {} |
| 96 | }; |
| 97 | |
| 98 | A<true> a(0); |
| 99 | |
| 100 | } |
| 101 | |
| 102 | namespace constructor1 { |
| 103 | |
| 104 | template<bool b> |
| 105 | struct A { |
| 106 | // expected-note@-1+ {{candidate constructor}} |
| 107 | // expected-note@-2+ {{candidate function}} |
| 108 | explicit(b) A(int, int = 0); |
| 109 | // expected-note@-1+ {{explicit constructor declared here}} |
| 110 | }; |
| 111 | |
| 112 | template<bool b> |
| 113 | A<b>::A(int, int) {} |
| 114 | |
| 115 | void f() |
| 116 | { |
| 117 | A<true> a0 = 0; // expected-error {{no viable conversion}} |
| 118 | A<true> a1( 0); |
| 119 | A<true> && a2 = 0;// expected-error {{could not bind}} |
| 120 | A<true> && a3( 0);// expected-error {{could not bind}} |
| 121 | A<true> a4{ 0}; |
| 122 | A<true> && a5 = { 0};// expected-error {{chosen constructor is explicit}} |
| 123 | A<true> && a6{ 0}; |
| 124 | A<true> a7 = { 0}; // expected-error {{chosen constructor is explicit in copy-initialization}} |
| 125 | |
| 126 | a0 = 0; |
| 127 | a1 = { 0}; // expected-error {{no viable overloaded '='}} |
| 128 | a2 = A<true>( 0); |
| 129 | a3 = A<true>{ 0}; |
| 130 | |
| 131 | A<false> c0 = ((short)0); |
| 132 | A<false> c1( ((short)0)); |
| 133 | A<false> && c2 = ((short)0); |
| 134 | A<false> && c3( ((short)0)); |
| 135 | A<false> c4{ ((short)0)}; |
| 136 | A<false> && c5 = { ((short)0)}; |
| 137 | A<false> && c6{ ((short)0)}; |
| 138 | |
| 139 | A<true> d1( 0, 0); |
| 140 | A<true> d2{ 0, 0}; |
| 141 | A<true> d3 = { 0, 0}; // expected-error {{chosen constructor is explicit in copy-initialization}} |
| 142 | |
| 143 | d1 = { 0, 0}; // expected-error {{no viable overloaded '='}} |
| 144 | d2 = A<true>( 0, 0); |
| 145 | d3 = A<true>{ 0, 0}; |
| 146 | } |
| 147 | } |
| 148 | |
| 149 | namespace constructor2 { |
| 150 | |
| 151 | template<bool a, typename T1> |
| 152 | struct A { |
| 153 | // expected-note@-1 {{candidate constructor}} expected-note@-1 {{candidate constructor}} |
| 154 | // expected-note@-2 {{candidate constructor}} expected-note@-2 {{candidate constructor}} |
| 155 | template<typename T2> |
| 156 | explicit(a ^ is_same<T1, T2>::value) |
| 157 | // expected-note@-1+ {{explicit(bool) specifier resolved to true}} |
| 158 | A(T2) {} |
| 159 | // expected-note@-1+ {{explicit constructor declared here}} |
| 160 | // expected-note@-2+ {{candidate constructor ignored}} |
| 161 | }; |
| 162 | |
| 163 | A<true, int> a0 = 0.0; // expected-error {{no viable conversion}} |
| 164 | A<true, int> a1( 0.0); |
| 165 | A<true, int> && a2 = 0.0;// expected-error {{could not bind}} |
| 166 | A<true, int> && a3( 0.0);// expected-error {{could not bind}} |
| 167 | A<true, int> a4{ 0.0}; |
| 168 | A<true, int> && a5 = { 0.0};// expected-error {{chosen constructor is explicit}} |
| 169 | A<true, int> && a6{ 0.0}; |
| 170 | A<true, int> a7 = { 0.0}; // expected-error {{chosen constructor is explicit in copy-initialization}} |
| 171 | |
| 172 | A<true, int> b0 = 0; |
| 173 | A<true, int> b1( 0); |
| 174 | A<true, int> && b2 = 0; |
| 175 | A<true, int> && b3( 0); |
| 176 | A<true, int> b4{ 0}; |
| 177 | A<true, int> && b5 = { 0}; |
| 178 | A<true, int> && b6{ 0}; |
| 179 | A<true, int> b7 = { 0}; |
| 180 | |
| 181 | A<true, double> c0 = 0; // expected-error {{no viable conversion}} |
| 182 | A<true, double> c1( 0); |
| 183 | A<true, double> && c2 = 0;// expected-error {{could not bind}} |
| 184 | A<true, double> && c3( 0);// expected-error {{could not bind}} |
| 185 | A<true, double> c4{ 0}; |
| 186 | A<true, double> && c5 = { 0};// expected-error {{chosen constructor is explicit}} |
| 187 | A<true, double> && c6{ 0}; |
| 188 | A<true, double> c7 = { 0}; // expected-error {{chosen constructor is explicit in copy-initialization}} |
| 189 | |
| 190 | } |
| 191 | |
| 192 | namespace constructor_sfinae { |
| 193 | |
| 194 | template<bool a> |
| 195 | struct A { |
| 196 | // expected-note@-1+ {{candidate constructor}} |
| 197 | template<typename T> |
| 198 | explicit(enable_ifv<is_same<int, T>::value, a>::value) |
| 199 | //expected-note@-1 {{explicit(bool) specifier resolved to true}} |
| 200 | A(T) {} |
| 201 | // expected-note@-1+ {{substitution failure}} |
| 202 | // expected-note@-2 {{candidate constructor ignored}} |
| 203 | // expected-note@-3 {{explicit constructor declared here}} |
| 204 | template<typename T, bool c = true> |
| 205 | explicit(enable_ifv<is_same<bool, T>::value, a>::value) |
| 206 | //expected-note@-1 {{explicit(bool) specifier resolved to true}} |
| 207 | A(T) {} |
| 208 | // expected-note@-1+ {{substitution failure}} |
| 209 | // expected-note@-2 {{candidate constructor ignored}} |
| 210 | // expected-note@-3 {{explicit constructor declared here}} |
| 211 | }; |
| 212 | |
| 213 | A<true> a0 = 0.0; // expected-error {{no viable conversion}} |
| 214 | A<true> a1( 0.0); // expected-error {{no matching constructor}} |
| 215 | A<true> a4{ 0.0}; // expected-error {{no matching constructor}} |
| 216 | A<true> a7 = { 0.0}; // expected-error {{no matching constructor}} |
| 217 | |
| 218 | A<true> b0 = 0; // expected-error {{no viable conversion}} |
| 219 | A<true> b1( 0); |
| 220 | A<true> b4{ 0}; |
| 221 | A<true> b7 = { 0}; // expected-error {{chosen constructor is explicit}} |
| 222 | |
| 223 | A<false> c0 = 0; |
| 224 | A<false> c1( 0); |
| 225 | A<false> c4{ 0}; |
| 226 | A<false> c7 = { 0}; |
| 227 | |
| 228 | A<true> d0 = true; // expected-error {{no viable conversion}} |
| 229 | A<true> d1( true); |
| 230 | A<true> d4{ true}; |
| 231 | A<true> d7 = { true}; // expected-error {{chosen constructor is explicit}} |
| 232 | |
| 233 | } |
| 234 | |
| 235 | namespace conversion { |
| 236 | |
| 237 | template<bool a> |
| 238 | struct A { |
| 239 | explicit(a) operator int (); |
| 240 | }; |
| 241 | |
| 242 | template<bool a> |
| 243 | A<a>::operator int() { |
| 244 | return 0; |
| 245 | } |
| 246 | |
| 247 | A<true> A_true; |
| 248 | A<false> A_false; |
| 249 | |
| 250 | int ai0 = A<true>(); // expected-error {{no viable conversion}} |
| 251 | const int& ai1 = A<true>(); // expected-error {{no viable conversion}} |
| 252 | int&& ai3 = A<true>(); // expected-error {{no viable conversion}} |
| 253 | int ai4 = A_true; // expected-error {{no viable conversion}} |
| 254 | const int& ai5 = A_true; // expected-error {{no viable conversion}} |
| 255 | |
| 256 | int ai01 = {A<true>()}; // expected-error {{no viable conversion}} |
| 257 | const int& ai11 = {A<true>()}; // expected-error {{no viable conversion}} |
| 258 | int&& ai31 = {A<true>()}; // expected-error {{no viable conversion}} |
| 259 | int ai41 = {A_true}; // expected-error {{no viable conversion}} |
| 260 | const int& ai51 = {A_true}; // expected-error {{no viable conversion}} |
| 261 | |
| 262 | int ae0(A<true>()); |
| 263 | const int& ae1(A<true>()); |
| 264 | int&& ae3(A<true>()); |
| 265 | int ae4(A_true); |
| 266 | const int& ae5(A_true); |
| 267 | |
| 268 | int bi0 = A<false>(); |
| 269 | const int& bi1 = A<false>(); |
| 270 | int&& bi3 = A<false>(); |
| 271 | int bi4 = A_false; |
| 272 | const int& bi5 = A_false; |
| 273 | |
| 274 | int bi01 = {A<false>()}; |
| 275 | const int& bi11 = {A<false>()}; |
| 276 | int&& bi31 = {A<false>()}; |
| 277 | int bi41 = {A_false}; |
| 278 | const int& bi51 = {A_false}; |
| 279 | |
| 280 | int be0(A<true>()); |
| 281 | const int& be1(A<true>()); |
| 282 | int&& be3(A<true>()); |
| 283 | int be4(A_true); |
| 284 | const int& be5(A_true); |
| 285 | |
| 286 | } |
| 287 | |
| 288 | namespace conversion2 { |
| 289 | |
| 290 | struct B {}; |
| 291 | // expected-note@-1+ {{candidate constructor}} |
| 292 | template<bool a> |
| 293 | struct A { |
| 294 | template<typename T2> |
| 295 | explicit(enable_ifv<is_same<B, T2>::value, a>::value) |
| 296 | // expected-note@-1+ {{explicit(bool) specifier resolved to true}} |
| 297 | operator T2() { return T2(); }; |
| 298 | // expected-note@-1+ {{substitution failure}} |
| 299 | // expected-note@-2+ {{candidate conversion}} |
| 300 | }; |
| 301 | |
| 302 | A<false> A_false; |
| 303 | A<true> A_true; |
| 304 | |
| 305 | int ai0 = A<true>(); // expected-error {{no viable conversion}} |
| 306 | const int& ai1 = A<true>(); // expected-error {{no viable conversion}} |
| 307 | int&& ai3 = A<true>(); // expected-error {{no viable conversion}} |
| 308 | int ai4 = A_false; // expected-error {{no viable conversion}} |
| 309 | const int& ai5 = A_false; // expected-error {{no viable conversion}} |
| 310 | |
| 311 | int ae0{A<true>()}; // expected-error {{no viable conversion}} |
| 312 | const int& ae1{A<true>()}; // expected-error {{no viable conversion}} |
| 313 | int&& ae3{A<true>()}; // expected-error {{no viable conversion}} |
| 314 | int ae4{A_true}; // expected-error {{no viable conversion}} |
| 315 | const int& ae5{A_true}; // expected-error {{no viable conversion}} |
| 316 | |
| 317 | int ap0((A<true>())); // expected-error {{no viable conversion}} |
| 318 | const int& ap1((A<true>())); // expected-error {{no viable conversion}} |
| 319 | int&& ap3((A<true>())); // expected-error {{no viable conversion}} |
| 320 | int ap4(A_true); // expected-error {{no viable conversion}} |
| 321 | const int& ap5(A_true); // expected-error {{no viable conversion}} |
| 322 | |
| 323 | B b0 = A<true>(); // expected-error {{no viable conversion}} |
| 324 | const B & b1 = A<true>(); // expected-error {{no viable conversion}} |
| 325 | B && b3 = A<true>(); // expected-error {{no viable conversion}} |
| 326 | B b4 = A_true; // expected-error {{no viable conversion}} |
| 327 | const B & b5 = A_true; // expected-error {{no viable conversion}} |
| 328 | |
| 329 | B be0(A<true>()); |
| 330 | const B& be1(A<true>()); |
| 331 | B&& be3(A<true>()); |
| 332 | B be4(A_true); |
| 333 | const B& be5(A_true); |
| 334 | |
| 335 | B c0 = A<false>(); |
| 336 | const B & c1 = A<false>(); |
| 337 | B && c3 = A<false>(); |
| 338 | B c4 = A_false; |
| 339 | const B & c5 = A_false; |
| 340 | |
| 341 | } |
| 342 | |
| 343 | namespace parameter_pack { |
| 344 | |
| 345 | template<typename T> |
| 346 | struct A { |
| 347 | // expected-note@-1+ {{candidate constructor}} |
| 348 | // expected-note@-2+ {{candidate function}} |
| 349 | template<typename ... Ts> |
| 350 | explicit((is_same<T, Ts>::value && ...)) |
| 351 | // expected-note@-1 {{explicit(bool) specifier resolved to true}} |
| 352 | A(Ts...); |
| 353 | // expected-note@-1 {{candidate constructor}} |
| 354 | // expected-note@-2 {{explicit constructor}} |
| 355 | }; |
| 356 | |
| 357 | template<typename T> |
| 358 | template<typename ... Ts> |
| 359 | A<T>::A(Ts ...) {} |
| 360 | |
| 361 | void f() { |
| 362 | |
| 363 | A<int> a0 = 0; // expected-error {{no viable conversion}} |
| 364 | A<int> a1( 0, 1); |
| 365 | A<int> a2{ 0, 1}; |
| 366 | A<int> a3 = { 0, 1}; // expected-error {{chosen constructor is explicit}} |
| 367 | |
| 368 | a1 = 0; // expected-error {{no viable overloaded '='}} |
| 369 | a2 = { 0, 1}; // expected-error {{no viable overloaded '='}} |
| 370 | |
| 371 | A<double> b0 = 0; |
| 372 | A<double> b1( 0, 1); |
| 373 | A<double> b2{ 0, 1}; |
| 374 | A<double> b3 = { 0, 1}; |
| 375 | |
| 376 | b1 = 0; |
| 377 | b2 = { 0, 1}; |
| 378 | |
| 379 | } |
| 380 | |
| 381 | } |
| 382 | |
| 383 | namespace deduction_guide { |
| 384 | |
| 385 | template<bool b> |
| 386 | struct B {}; |
| 387 | |
| 388 | B<true> b_true; |
| 389 | B<false> b_false; |
| 390 | |
| 391 | template<typename T> |
| 392 | struct nondeduced |
| 393 | { |
| 394 | using type = T; |
| 395 | }; |
| 396 | |
| 397 | template<typename T1, typename T2, bool b> |
| 398 | struct A { |
| 399 | // expected-note@-1+ {{candidate function}} |
| 400 | explicit(false) |
| 401 | A(typename nondeduced<T1>::type, typename nondeduced<T2>::type, typename nondeduced<B<b>>::type) {} |
| 402 | // expected-note@-1+ {{candidate template ignored}} |
| 403 | }; |
| 404 | |
| 405 | template<typename T1, typename T2, bool b> |
| 406 | explicit(enable_ifv<is_same<T1, T2>::value, b>::value) |
| 407 | A(T1, T2, B<b>) -> A<T1, T2, b>; |
| 408 | // expected-note@-1+ {{explicit deduction guide declared here}} |
| 409 | // expected-note@-2+ {{candidate template ignored}} |
| 410 | void f() { |
| 411 | |
| 412 | A a0( 0.0, 1, b_true); // expected-error {{no viable constructor or deduction guide}} |
| 413 | A a1{ 0.0, 1, b_true}; // expected-error {{no viable constructor or deduction guide}} |
| 414 | A a2 = { 0.0, 1, b_true}; // expected-error {{no viable constructor or deduction guide}} |
| 415 | auto a4 = A( 0.0, 1, b_true); // expected-error {{no viable constructor or deduction guide}} |
| 416 | auto a5 = A{ 0.0, 1, b_true}; // expected-error {{no viable constructor or deduction guide}} |
| 417 | |
| 418 | A b0( 0, 1, b_true); |
| 419 | A b1{ 0, 1, b_true}; |
| 420 | A b2 = { 0, 1, b_true}; // expected-error {{explicit deduction guide for copy-list-initialization}} |
| 421 | auto b4 = A( 0, 1, b_true); |
| 422 | auto b5 = A{ 0, 1, b_true}; |
| 423 | b0 = { 0, 1, b_false}; // expected-error {{no viable overloaded '='}} |
| 424 | |
| 425 | A c0( 0, 1, b_false); |
| 426 | A c1{ 0, 1, b_false}; |
| 427 | A c2 = { 0, 1, b_false}; |
| 428 | auto c4 = A( 0, 1, b_false); |
| 429 | auto c5 = A{ 0, 1, b_false}; |
| 430 | c2 = { 0, 1, b_false}; |
| 431 | |
| 432 | } |
| 433 | |
| 434 | } |
| 435 | |
| 436 | namespace test8 { |
| 437 | |
| 438 | template<bool b> |
| 439 | struct A { |
| 440 | //expected-note@-1+ {{candidate function}} |
| 441 | template<typename T1, typename T2> |
| 442 | explicit(b) |
| 443 | A(T1, T2) {} |
| 444 | //expected-note@-1 {{explicit constructor declared here}} |
| 445 | }; |
| 446 | |
| 447 | template<typename T1, typename T2> |
| 448 | explicit(!is_same<T1, int>::value) |
| 449 | A(T1, T2) -> A<!is_same<int, T2>::value>; |
| 450 | // expected-note@-1+ {{explicit deduction guide declared here}} |
| 451 | |
| 452 | template<bool b> |
| 453 | A<b> v(); |
| 454 | |
| 455 | void f() { |
| 456 | |
| 457 | A a0( 0, 1); |
| 458 | A a1{ 0, 1}; |
| 459 | A a2 = { 0, 1}; |
| 460 | auto a4 = A( 0, 1); |
| 461 | auto a5 = A{ 0, 1}; |
| 462 | auto a6(v<false>()); |
| 463 | a6 = { 0, 1}; |
| 464 | |
| 465 | A b0( 0.0, 1); |
| 466 | A b1{ 0.0, 1}; |
| 467 | A b2 = { 0.0, 1}; // expected-error {{explicit deduction guide for copy-list-initialization}} |
| 468 | auto b4 = A( 0.0, 1); |
| 469 | auto b5 = A{ 0.0, 1}; |
| 470 | |
| 471 | A c0( 0, 1.0); |
| 472 | A c1{ 0, 1.0}; |
| 473 | A c2 = { 0, 1.0}; // expected-error {{chosen constructor is explicit}} |
| 474 | auto c4 = A( 0, 1.0); |
| 475 | auto c5 = A{ 0, 1.0}; |
| 476 | auto c6(v<true>()); |
| 477 | c0 = { 0, 1.0}; // expected-error {{no viable overloaded '='}} |
| 478 | |
| 479 | A d0( 0.0, 1.0); |
| 480 | A d1{ 0.0, 1.0}; |
| 481 | A d2 = { 0.0, 1.0}; // expected-error {{explicit deduction guide for copy-list-initialization}} |
| 482 | auto d4 = A( 0.0, 1.0); |
| 483 | auto d5 = A{ 0.0, 1.0}; |
| 484 | |
| 485 | } |
| 486 | |
| 487 | } |
| 488 | |
| 489 | namespace conversion3 { |
| 490 | |
| 491 | template<bool b> |
| 492 | struct A { |
| 493 | explicit(!b) operator int(); |
| 494 | explicit(b) operator bool(); |
| 495 | }; |
| 496 | |
| 497 | template<bool b> |
| 498 | A<b>::operator bool() { return false; } |
| 499 | |
| 500 | struct B { |
| 501 | void f(int); |
| 502 | void f(bool); |
| 503 | }; |
| 504 | |
| 505 | void f(A<true> a, B b) { |
| 506 | b.f(a); |
| 507 | } |
| 508 | |
| 509 | void f1(A<false> a, B b) { |
| 510 | b.f(a); |
| 511 | } |
| 512 | |
| 513 | // Taken from 12.3.2p2 |
| 514 | class X { X(); }; |
| 515 | class Y { }; // expected-note+ {{candidate constructor (the implicit}} |
| 516 | |
| 517 | template<bool b> |
| 518 | struct Z { |
| 519 | explicit(b) operator X() const; |
| 520 | explicit(b) operator Y() const; |
| 521 | explicit(b) operator int() const; |
| 522 | }; |
| 523 | |
| 524 | void testExplicit() |
| 525 | { |
| 526 | Z<true> z; |
| 527 | // 13.3.1.4p1 & 8.5p16: |
| 528 | Y y2 = z; // expected-error {{no viable conversion}} |
| 529 | Y y2b(z); |
| 530 | Y y3 = (Y)z; |
| 531 | Y y4 = Y(z); |
| 532 | Y y5 = static_cast<Y>(z); |
| 533 | // 13.3.1.5p1 & 8.5p16: |
| 534 | int i1 = (int)z; |
| 535 | int i2 = int(z); |
| 536 | int i3 = static_cast<int>(z); |
| 537 | int i4(z); |
| 538 | // 13.3.1.6p1 & 8.5.3p5: |
| 539 | const Y& y6 = z; // expected-error {{no viable conversion}} |
| 540 | const int& y7 = z; // expected-error {{no viable conversion}} |
| 541 | const Y& y8(z); |
| 542 | const int& y9(z); |
| 543 | |
| 544 | // Y is an aggregate, so aggregate-initialization is performed and the |
| 545 | // conversion function is not considered. |
| 546 | const Y y10{z}; // expected-error {{excess elements}} |
| 547 | const Y& y11{z}; // expected-error {{excess elements}} expected-note {{in initialization of temporary}} |
| 548 | const int& y12{z}; |
| 549 | |
| 550 | // X is not an aggregate, so constructors are considered, |
| 551 | // per 13.3.3.1/4 & DR1467. |
| 552 | const X x1{z}; |
| 553 | const X& x2{z}; |
| 554 | } |
| 555 | |
| 556 | struct tmp {}; |
| 557 | |
| 558 | template<typename T1> |
| 559 | struct C { |
| 560 | template<typename T> |
| 561 | explicit(!is_same<T1, T>::value) |
| 562 | // expected-note@-1+ {{explicit(bool) specifier resolved to true}} |
| 563 | operator T(); |
| 564 | // expected-note@-1+ {{candidate conversion operator ignored}} |
| 565 | }; |
| 566 | |
| 567 | using Bool = C<bool>; |
| 568 | using Integral = C<int>; |
| 569 | using Unrelated = C<tmp>; |
| 570 | |
| 571 | void testBool() { |
| 572 | Bool b; |
| 573 | Integral n; |
| 574 | Unrelated u; |
| 575 | |
| 576 | (void) (1 + b); // expected-error {{invalid operands to binary expression}} |
| 577 | (void) (1 + n); |
| 578 | (void) (1 + u); // expected-error {{invalid operands to binary expression}} |
| 579 | |
| 580 | // 5.3.1p9: |
| 581 | (void) (!b); |
| 582 | (void) (!n); |
| 583 | (void) (!u); |
| 584 | |
| 585 | // 5.14p1: |
| 586 | (void) (b && true); |
| 587 | (void) (n && true); |
| 588 | (void) (u && true); |
| 589 | |
| 590 | // 5.15p1: |
| 591 | (void) (b || true); |
| 592 | (void) (n || true); |
| 593 | (void) (u || true); |
| 594 | |
| 595 | // 5.16p1: |
| 596 | (void) (b ? 0 : 1); |
| 597 | (void) (n ? 0: 1); |
| 598 | (void) (u ? 0: 1); |
| 599 | |
| 600 | // // 5.19p5: |
| 601 | // // TODO: After constexpr has been implemented |
| 602 | |
| 603 | // 6.4p4: |
| 604 | if (b) {} |
| 605 | if (n) {} |
| 606 | if (u) {} |
| 607 | |
| 608 | // 6.4.2p2: |
| 609 | switch (b) {} // expected-error {{statement requires expression of integer type}} |
| 610 | switch (n) {} // expected-error {{statement requires expression of integer type}} |
| 611 | switch (u) {} // expected-error {{statement requires expression of integer type}} |
| 612 | |
| 613 | // 6.5.1: |
| 614 | while (b) {} |
| 615 | while (n) {} |
| 616 | while (u) {} |
| 617 | |
| 618 | // 6.5.2p1: |
| 619 | do {} while (b); |
| 620 | do {} while (n); |
| 621 | do {} while (u); |
| 622 | |
| 623 | // 6.5.3: |
| 624 | for (;b;) {} |
| 625 | for (;n;) {} |
| 626 | for (;u;) {} |
| 627 | |
| 628 | // 13.3.1.5p1: |
| 629 | bool db1(b); |
| 630 | bool db2(n); |
| 631 | bool db3(u); |
| 632 | int di1(b); |
| 633 | int di2(n); |
| 634 | int di3(n); |
| 635 | const bool &direct_cr1(b); |
| 636 | const bool &direct_cr2(n); |
| 637 | const bool &direct_cr3(n); |
| 638 | const int &direct_cr4(b); |
| 639 | const int &direct_cr5(n); |
| 640 | const int &direct_cr6(n); |
| 641 | bool directList1{b}; |
| 642 | bool directList2{n}; |
| 643 | bool directList3{n}; |
| 644 | int directList4{b}; |
| 645 | int directList5{n}; |
| 646 | int directList6{n}; |
| 647 | const bool &directList_cr1{b}; |
| 648 | const bool &directList_cr2{n}; |
| 649 | const bool &directList_cr3{n}; |
| 650 | const int &directList_cr4{b}; |
| 651 | const int &directList_cr5{n}; |
| 652 | const int &directList_cr6{n}; |
| 653 | bool copy1 = b; |
| 654 | bool copy2 = n;// expected-error {{no viable conversion}} |
| 655 | bool copyu2 = u;// expected-error {{no viable conversion}} |
| 656 | int copy3 = b;// expected-error {{no viable conversion}} |
| 657 | int copy4 = n; |
| 658 | int copyu4 = u;// expected-error {{no viable conversion}} |
| 659 | const bool ©5 = b; |
| 660 | const bool ©6 = n;// expected-error {{no viable conversion}} |
| 661 | const bool ©u6 = u;// expected-error {{no viable conversion}} |
| 662 | const int ©7 = b;// expected-error {{no viable conversion}} |
| 663 | const int ©8 = n; |
| 664 | const int ©u8 = u;// expected-error {{no viable conversion}} |
| 665 | bool copyList1 = {b}; |
| 666 | bool copyList2 = {n};// expected-error {{no viable conversion}} |
| 667 | bool copyListu2 = {u};// expected-error {{no viable conversion}} |
| 668 | int copyList3 = {b};// expected-error {{no viable conversion}} |
| 669 | int copyList4 = {n}; |
| 670 | int copyListu4 = {u};// expected-error {{no viable conversion}} |
| 671 | const bool ©List5 = {b}; |
| 672 | const bool ©List6 = {n};// expected-error {{no viable conversion}} |
| 673 | const bool ©Listu6 = {u};// expected-error {{no viable conversion}} |
| 674 | const int ©List7 = {b};// expected-error {{no viable conversion}} |
| 675 | const int ©List8 = {n}; |
| 676 | const int ©Listu8 = {u};// expected-error {{no viable conversion}} |
| 677 | } |
| 678 | |
| 679 | } |
| 680 | |
| 681 | namespace deduction_guide2 { |
| 682 | |
| 683 | template<typename T1 = int, typename T2 = int> |
| 684 | struct A { |
| 685 | // expected-note@-1+ {{candidate template ignored}} |
| 686 | explicit(!is_same<T1, T2>::value) |
| 687 | // expected-note@-1+ {{explicit(bool) specifier resolved to true}} |
| 688 | A(T1 = 0, T2 = 0) {} |
| 689 | // expected-note@-1 {{explicit constructor}} |
| 690 | // expected-note@-2+ {{candidate deductiong guide ignored}} |
| 691 | }; |
| 692 | |
| 693 | A a0 = 0; |
| 694 | A a1(0, 0); |
| 695 | A a2{0, 0}; |
| 696 | A a3 = {0, 0}; |
| 697 | |
| 698 | A b0 = 0.0; // expected-error {{no viable constructor or deduction guide}} |
| 699 | A b1(0.0, 0.0); |
| 700 | A b2{0.0, 0.0}; |
| 701 | A b3 = {0.0, 0.0}; |
| 702 | |
| 703 | A b4 = {0.0, 0}; // expected-error {{explicit constructor}} |
| 704 | |
| 705 | template<typename T1, typename T2> |
| 706 | explicit A(T1, T2) -> A<T1, T2>; |
| 707 | // expected-note@-1+ {{explicit deduction guide}} |
| 708 | |
| 709 | A c0 = 0; |
| 710 | A c1(0, 0); |
| 711 | A c2{0, 0}; |
| 712 | A c3 = {0, 0};// expected-error {{explicit deduction guide}} |
| 713 | |
| 714 | A d0 = 0.0; // expected-error {{no viable constructor or deduction guide}} |
| 715 | A d1(0, 0); |
| 716 | A d2{0, 0}; |
| 717 | A d3 = {0.0, 0.0};// expected-error {{explicit deduction guide}} |
| 718 | |
| 719 | } |