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