1 // RUN: %clang_cc1 -std=c++17 -fsyntax-only %s -verify=expected,pre20 -Wno-c++2a-extensions
2 // RUN: %clang_cc1 -std=c++2a -fsyntax-only %s -verify=expected,post20
4 template <bool b
, auto val
> struct enable_ifv
{};
6 template <auto val
> struct enable_ifv
<true, val
> {
7 static constexpr auto value
= val
;
10 template <typename T1
, typename T2
> struct is_same
{
11 static constexpr bool value
= false;
14 template <typename T
> struct is_same
<T
, T
> {
15 static constexpr bool value
= true;
18 namespace special_cases
23 // pre20-note@-1+ {{candidate constructor}}
25 // expected-note@-1 {{negative shift count -1}}
26 // expected-error@-2 {{explicit specifier argument is not a constant expression}}
31 // pre20-error@-1 {{no matching constructor}}
32 // post20-error@-2 {{excess elements in struct initializer}}
33 // expected-note@-3 {{in instantiation of template class}}
38 // expected-error@-1 {{use of undeclared identifier}}
45 // expected-error@-1 {{expected expression}}
50 explicit(false) explicit
52 // expected-error@-2 {{duplicate 'explicit' declaration specifier}}
57 // expected-note@-1 {{candidate constructor}} expected-note@-1 {{candidate constructor}}
58 // expected-note@-2 {{candidate constructor}} expected-note@-2 {{candidate constructor}}
60 C(int), // expected-note 2{{not a candidate}}
61 C(double); // expected-note 2{{not a candidate}}
64 C
<0> c0
= 0.0; // expected-error {{no viable conversion}}
65 C
<0> c1
= 0; // expected-error {{no viable conversion}}
69 explicit(false) void f(int);// expected-error {{'explicit' can only be specified inside the class definition}}
72 explicit(false) void f(int);// expected-error {{'explicit' can only be applied to a constructor or conversion function}}
75 template <typename T
> struct E
{
76 // expected-note@-1+ {{candidate constructor}}
77 explicit((T
{}, false))
78 // expected-error@-1 {{illegal initializer type 'void'}}
83 // expected-error@-1 {{no viable conversion}}
84 // expected-note@-2 {{in instantiation of}}
88 namespace trailing_object
{
97 explicit(b
) A(int) : B
<b
>(0) {}
104 namespace constructor1
{
108 // expected-note@-1+ {{candidate constructor}}
109 // expected-note@-2+ {{candidate function}}
110 explicit(b
) A(int, int = 0); // expected-note {{not a candidate}}
111 // expected-note@-1+ {{explicit constructor declared here}}
119 A
<true> a0
= 0; // expected-error {{no viable conversion}}
121 A
<true> && a2
= 0;// expected-error {{could not bind}}
122 A
<true> && a3( 0);// expected-error {{could not bind}}
124 A
<true> && a5
= { 0};// expected-error {{chosen constructor is explicit}}
126 A
<true> a7
= { 0}; // expected-error {{chosen constructor is explicit in copy-initialization}}
128 a0
= 0; // expected-error {{no viable overloaded '='}}
129 a1
= { 0}; // expected-error {{no viable overloaded '='}}
133 A
<false> c0
= ((short)0);
134 A
<false> c1( ((short)0));
135 A
<false> && c2
= ((short)0);
136 A
<false> && c3( ((short)0));
137 A
<false> c4
{ ((short)0)};
138 A
<false> && c5
= { ((short)0)};
139 A
<false> && c6
{ ((short)0)};
143 A
<true> d3
= { 0, 0}; // expected-error {{chosen constructor is explicit in copy-initialization}}
145 d1
= { 0, 0}; // expected-error {{no viable overloaded '='}}
151 namespace constructor2
{
153 template<bool a
, typename T1
>
155 // expected-note@-1 {{candidate constructor}} expected-note@-1 {{candidate constructor}}
156 // expected-note@-2 {{candidate constructor}} expected-note@-2 {{candidate constructor}}
157 template<typename T2
>
158 explicit(a
^ is_same
<T1
, T2
>::value
)
160 // expected-note@-1+ {{explicit constructor declared here}}
161 // expected-note@-2+ {{not a candidate}}
164 A
<true, int> a0
= 0.0; // expected-error {{no viable conversion}}
165 A
<true, int> a1( 0.0);
166 A
<true, int> && a2
= 0.0;// expected-error {{could not bind}}
167 A
<true, int> && a3( 0.0);// expected-error {{could not bind}}
168 A
<true, int> a4
{ 0.0};
169 A
<true, int> && a5
= { 0.0};// expected-error {{chosen constructor is explicit}}
170 A
<true, int> && a6
{ 0.0};
171 A
<true, int> a7
= { 0.0}; // expected-error {{chosen constructor is explicit in copy-initialization}}
175 A
<true, int> && b2
= 0;
176 A
<true, int> && b3( 0);
178 A
<true, int> && b5
= { 0};
179 A
<true, int> && b6
{ 0};
180 A
<true, int> b7
= { 0};
182 A
<true, double> c0
= 0; // expected-error {{no viable conversion}}
183 A
<true, double> c1( 0);
184 A
<true, double> && c2
= 0;// expected-error {{could not bind}}
185 A
<true, double> && c3( 0);// expected-error {{could not bind}}
186 A
<true, double> c4
{ 0};
187 A
<true, double> && c5
= { 0};// expected-error {{chosen constructor is explicit}}
188 A
<true, double> && c6
{ 0};
189 A
<true, double> c7
= { 0}; // expected-error {{chosen constructor is explicit in copy-initialization}}
193 namespace constructor_sfinae
{
197 // expected-note@-1+ {{candidate constructor}}
199 explicit(enable_ifv
<is_same
<int, T
>::value
, a
>::value
)
201 // expected-note@-1+ {{substitution failure}}
202 // expected-note@-2 {{not a candidate}}
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
)
207 // expected-note@-1+ {{substitution failure}}
208 // expected-note@-2 {{not a candidate}}
209 // expected-note@-3 {{explicit constructor declared here}}
212 A
<true> a0
= 0.0; // expected-error {{no viable conversion}}
213 A
<true> a1( 0.0); // expected-error {{no matching constructor}}
214 A
<true> a4
{ 0.0}; // expected-error {{no matching constructor}}
215 A
<true> a7
= { 0.0}; // expected-error {{no matching constructor}}
217 A
<true> b0
= 0; // expected-error {{no viable conversion}}
220 A
<true> b7
= { 0}; // expected-error {{chosen constructor is explicit}}
227 A
<true> d0
= true; // expected-error {{no viable conversion}}
230 A
<true> d7
= { true}; // expected-error {{chosen constructor is explicit}}
234 namespace conversion
{
238 explicit(a
) operator int (); // expected-note+ {{not a candidate}}
242 A
<a
>::operator int() {
249 int ai0
= A
<true>(); // expected-error {{no viable conversion}}
250 const int& ai1
= A
<true>(); // expected-error {{no viable conversion}}
251 int&& ai3
= A
<true>(); // expected-error {{no viable conversion}}
252 int ai4
= A_true
; // expected-error {{no viable conversion}}
253 const int& ai5
= A_true
; // expected-error {{no viable conversion}}
255 int ai01
= {A
<true>()}; // expected-error {{no viable conversion}}
256 const int& ai11
= {A
<true>()}; // expected-error {{no viable conversion}}
257 int&& ai31
= {A
<true>()}; // expected-error {{no viable conversion}}
258 int ai41
= {A_true
}; // expected-error {{no viable conversion}}
259 const int& ai51
= {A_true
}; // expected-error {{no viable conversion}}
262 const int& ae1(A
<true>());
263 int&& ae3(A
<true>());
265 const int& ae5(A_true
);
267 int bi0
= A
<false>();
268 const int& bi1
= A
<false>();
269 int&& bi3
= A
<false>();
271 const int& bi5
= A_false
;
273 int bi01
= {A
<false>()};
274 const int& bi11
= {A
<false>()};
275 int&& bi31
= {A
<false>()};
276 int bi41
= {A_false
};
277 const int& bi51
= {A_false
};
280 const int& be1(A
<true>());
281 int&& be3(A
<true>());
283 const int& be5(A_true
);
287 namespace conversion2
{
290 // expected-note@-1+ {{candidate constructor}}
293 template<typename T2
>
294 explicit(enable_ifv
<is_same
<B
, T2
>::value
, a
>::value
)
295 operator T2() { return T2(); };
296 // expected-note@-1+ {{substitution failure}}
297 // expected-note@-2+ {{not a candidate}}
303 int ai0
= A
<true>(); // expected-error {{no viable conversion}}
304 const int& ai1
= A
<true>(); // expected-error {{no viable conversion}}
305 int&& ai3
= A
<true>(); // expected-error {{no viable conversion}}
306 int ai4
= A_false
; // expected-error {{no viable conversion}}
307 const int& ai5
= A_false
; // expected-error {{no viable conversion}}
309 int ae0
{A
<true>()}; // expected-error {{no viable conversion}}
310 const int& ae1
{A
<true>()}; // expected-error {{no viable conversion}}
311 int&& ae3
{A
<true>()}; // expected-error {{no viable conversion}}
312 int ae4
{A_true
}; // expected-error {{no viable conversion}}
313 const int& ae5
{A_true
}; // expected-error {{no viable conversion}}
315 int ap0((A
<true>())); // expected-error {{no viable conversion}}
316 const int& ap1((A
<true>())); // expected-error {{no viable conversion}}
317 int&& ap3((A
<true>())); // expected-error {{no viable conversion}}
318 int ap4(A_true
); // expected-error {{no viable conversion}}
319 const int& ap5(A_true
); // expected-error {{no viable conversion}}
321 B b0
= A
<true>(); // expected-error {{no viable conversion}}
322 const B
& b1
= A
<true>(); // expected-error {{no viable conversion}}
323 B
&& b3
= A
<true>(); // expected-error {{no viable conversion}}
324 B b4
= A_true
; // expected-error {{no viable conversion}}
325 const B
& b5
= A_true
; // expected-error {{no viable conversion}}
328 const B
& be1(A
<true>());
331 const B
& be5(A_true
);
334 const B
& c1
= A
<false>();
335 B
&& c3
= A
<false>();
337 const B
& c5
= A_false
;
341 namespace parameter_pack
{
345 // expected-note@-1+ {{candidate constructor}}
346 // expected-note@-2+ {{candidate function}}
347 template<typename
... Ts
>
348 explicit((is_same
<T
, Ts
>::value
&& ...))
350 // expected-note@-1 {{not a candidate}}
351 // expected-note@-2 {{explicit constructor}}
355 template<typename
... Ts
>
360 A
<int> a0
= 0; // expected-error {{no viable conversion}}
363 A
<int> a3
= { 0, 1}; // expected-error {{chosen constructor is explicit}}
365 a1
= 0; // expected-error {{no viable overloaded '='}}
366 a2
= { 0, 1}; // expected-error {{no viable overloaded '='}}
371 A
<double> b3
= { 0, 1};
380 namespace deduction_guide
{
394 template<typename T1
, typename T2
, bool b
>
396 // expected-note@-1+ {{candidate function}}
398 A(typename nondeduced
<T1
>::type
, typename nondeduced
<T2
>::type
, typename nondeduced
<B
<b
>>::type
) {}
399 // expected-note@-1+ {{candidate template ignored}}
402 template<typename T1
, typename T2
, bool b
>
403 explicit(enable_ifv
<is_same
<T1
, T2
>::value
, b
>::value
)
404 A(T1
, T2
, B
<b
>) -> A
<T1
, T2
, b
>;
405 // expected-note@-1+ {{explicit deduction guide declared here}}
406 // expected-note@-2+ {{candidate template ignored}}
409 A
a0( 0.0, 1, b_true
); // expected-error {{no viable constructor or deduction guide}}
410 A a1
{ 0.0, 1, b_true
}; // expected-error {{no viable constructor or deduction guide}}
411 A a2
= { 0.0, 1, b_true
}; // expected-error {{no viable constructor or deduction guide}}
412 auto a4
= A( 0.0, 1, b_true
); // expected-error {{no viable constructor or deduction guide}}
413 auto a5
= A
{ 0.0, 1, b_true
}; // expected-error {{no viable constructor or deduction guide}}
417 A b2
= { 0, 1, b_true
}; // expected-error {{explicit deduction guide for copy-list-initialization}}
418 auto b4
= A( 0, 1, b_true
);
419 auto b5
= A
{ 0, 1, b_true
};
420 b0
= { 0, 1, b_false
}; // expected-error {{no viable overloaded '='}}
422 A
c0( 0, 1, b_false
);
423 A c1
{ 0, 1, b_false
};
424 A c2
= { 0, 1, b_false
};
425 auto c4
= A( 0, 1, b_false
);
426 auto c5
= A
{ 0, 1, b_false
};
427 c2
= { 0, 1, b_false
};
437 //expected-note@-1+ {{candidate function}}
438 template<typename T1
, typename T2
>
441 //expected-note@-1 {{explicit constructor declared here}}
444 template<typename T1
, typename T2
>
445 explicit(!is_same
<T1
, int>::value
)
446 A(T1
, T2
) -> A
<!is_same
<int, T2
>::value
>;
447 // expected-note@-1+ {{explicit deduction guide declared here}}
464 A b2
= { 0.0, 1}; // expected-error {{explicit deduction guide for copy-list-initialization}}
465 auto b4
= A( 0.0, 1);
466 auto b5
= A
{ 0.0, 1};
470 A c2
= { 0, 1.0}; // expected-error {{chosen constructor is explicit}}
471 auto c4
= A( 0, 1.0);
472 auto c5
= A
{ 0, 1.0};
474 c0
= { 0, 1.0}; // expected-error {{no viable overloaded '='}}
478 A d2
= { 0.0, 1.0}; // expected-error {{explicit deduction guide for copy-list-initialization}}
479 auto d4
= A( 0.0, 1.0);
480 auto d5
= A
{ 0.0, 1.0};
486 namespace conversion3
{
490 explicit(!b
) operator int();
491 explicit(b
) operator bool();
495 A
<b
>::operator bool() { return false; }
502 void f(A
<true> a
, B b
) {
506 void f1(A
<false> a
, B b
) {
510 // Taken from 12.3.2p2
512 class Y
{ }; // expected-note+ {{candidate constructor (the implicit}}
516 explicit(b
) operator X() const;
517 explicit(b
) operator Y() const; // expected-note 2{{not a candidate}}
518 explicit(b
) operator int() const; // expected-note {{not a candidate}}
524 // 13.3.1.4p1 & 8.5p16:
525 Y y2
= z
; // expected-error {{no viable conversion}}
529 Y y5
= static_cast<Y
>(z
);
530 // 13.3.1.5p1 & 8.5p16:
533 int i3
= static_cast<int>(z
);
535 // 13.3.1.6p1 & 8.5.3p5:
536 const Y
& y6
= z
; // expected-error {{no viable conversion}}
537 const int& y7
= z
; // expected-error {{no viable conversion}}
541 // Y is an aggregate, so aggregate-initialization is performed and the
542 // conversion function is not considered.
543 const Y y10
{z
}; // expected-error {{excess elements}}
544 const Y
& y11
{z
}; // expected-error {{excess elements}} expected-note {{in initialization of temporary}}
547 // X is not an aggregate, so constructors are considered,
548 // per 13.3.3.1/4 & DR1467.
555 template<typename T1
>
558 explicit(!is_same
<T1
, T
>::value
)
559 operator T(); // expected-note+ {{explicit conversion function is not a candidate}}
562 using Bool
= C
<bool>;
563 using Integral
= C
<int>;
564 using Unrelated
= C
<tmp
>;
571 (void) (1 + b
); // expected-error {{invalid operands to binary expression}}
573 (void) (1 + u
); // expected-error {{invalid operands to binary expression}}
596 // // TODO: After constexpr has been implemented
604 switch (b
) {} // expected-error {{statement requires expression of integer type}}
605 switch (n
) {} // expected-error {{statement requires expression of integer type}}
606 switch (u
) {} // expected-error {{statement requires expression of integer type}}
630 const bool &direct_cr1(b
);
631 const bool &direct_cr2(n
);
632 const bool &direct_cr3(n
);
633 const int &direct_cr4(b
);
634 const int &direct_cr5(n
);
635 const int &direct_cr6(n
);
642 const bool &directList_cr1
{b
};
643 const bool &directList_cr2
{n
};
644 const bool &directList_cr3
{n
};
645 const int &directList_cr4
{b
};
646 const int &directList_cr5
{n
};
647 const int &directList_cr6
{n
};
649 bool copy2
= n
;// expected-error {{no viable conversion}}
650 bool copyu2
= u
;// expected-error {{no viable conversion}}
651 int copy3
= b
;// expected-error {{no viable conversion}}
653 int copyu4
= u
;// expected-error {{no viable conversion}}
654 const bool ©5
= b
;
655 const bool ©6
= n
;// expected-error {{no viable conversion}}
656 const bool ©u6
= u
;// expected-error {{no viable conversion}}
657 const int ©7
= b
;// expected-error {{no viable conversion}}
658 const int ©8
= n
;
659 const int ©u8
= u
;// expected-error {{no viable conversion}}
660 bool copyList1
= {b
};
661 bool copyList2
= {n
};// expected-error {{no viable conversion}}
662 bool copyListu2
= {u
};// expected-error {{no viable conversion}}
663 int copyList3
= {b
};// expected-error {{no viable conversion}}
665 int copyListu4
= {u
};// expected-error {{no viable conversion}}
666 const bool ©List5
= {b
};
667 const bool ©List6
= {n
};// expected-error {{no viable conversion}}
668 const bool ©Listu6
= {u
};// expected-error {{no viable conversion}}
669 const int ©List7
= {b
};// expected-error {{no viable conversion}}
670 const int ©List8
= {n
};
671 const int ©Listu8
= {u
};// expected-error {{no viable conversion}}
676 namespace deduction_guide2
{
678 template<typename T1
= int, typename T2
= int>
680 // expected-note@-1+ {{candidate template ignored}}
681 explicit(!is_same
<T1
, T2
>::value
)
683 // expected-note@-1 {{explicit constructor declared here}}
684 // expected-note@-2 2{{explicit constructor is not a candidate}}
692 A b0
= 0.0; // expected-error {{no viable constructor or deduction guide}}
697 A b4
= {0.0, 0}; // expected-error {{explicit constructor}}
699 template<typename T1
, typename T2
>
700 explicit A(T1
, T2
) -> A
<T1
, T2
>;
701 // expected-note@-1+ {{explicit deduction guide}}
706 A c3
= {0, 0};// expected-error {{explicit deduction guide}}
708 A d0
= 0.0; // expected-error {{no viable constructor or deduction guide}}
711 A d3
= {0.0, 0.0};// expected-error {{explicit deduction guide}}
716 using size_t = decltype(sizeof(0));
718 struct Str
{// expected-note+ {{candidate constructor}}
721 Str(char const (&str
)[N
]); // expected-note {{explicit constructor is not a candidate}}
725 Str::Str(char const(&str
)[N
]) { }
728 Str b
= "not so short";// expected-error {{no viable conversion}}
737 explicit(sizeof(char[2])) S(char); // expected-error {{explicit specifier argument evaluates to 2, which cannot be narrowed to type 'bool'}}
738 explicit(ptr
) S(long); // expected-error {{conversion from 'const int *' to 'bool' is not allowed in a converted constant expression}}
739 explicit(nullptr) S(int); // expected-error {{conversion from 'std::nullptr_t' to 'bool' is not allowed in a converted constant expression}}
740 explicit(42L) S(int, int); // expected-error {{explicit specifier argument evaluates to 42, which cannot be narrowed to type 'bool'}}
741 explicit(sizeof(char)) S();
742 explicit(0) S(char, char);
743 explicit(1L) S(char, char, char);