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