150
|
1 // RUN: %clang_cc1 -std=c++2a -emit-pch %s -o %t-cxx2a
|
|
2 // RUN: %clang_cc1 -std=c++2a -DUSE_PCH -include-pch %t-cxx2a %s -ast-print -verify | FileCheck %s
|
|
3
|
|
4 #ifndef USE_PCH
|
|
5 namespace inheriting_constructor {
|
|
6 struct S {};
|
|
7
|
|
8 template<typename X, typename Y> struct T {
|
|
9 template<typename A>
|
|
10 explicit((Y{}, true)) T(A &&a) {}
|
|
11 };
|
|
12
|
|
13 template<typename X, typename Y> struct U : T<X, Y> {
|
|
14 using T<X, Y>::T;
|
|
15 };
|
|
16
|
|
17 U<S, char> foo(char ch) {
|
|
18 return U<S, char>(ch);
|
|
19 }
|
|
20 }
|
|
21 #else
|
|
22 namespace inheriting_constructor {
|
|
23 U<S, char> a = foo('0');
|
|
24 }
|
|
25
|
|
26 //CHECK: explicit((char{} , true))
|
|
27
|
|
28 #endif
|
|
29
|
|
30 namespace basic {
|
|
31 #ifndef USE_PCH
|
|
32
|
|
33 struct B {};
|
|
34
|
|
35 struct A {
|
|
36 explicit A(int);
|
|
37 explicit(false) operator bool();
|
|
38 explicit(true) operator B();
|
|
39 };
|
|
40 #else
|
|
41 //expected-note@-6+ {{candidate constructor}}
|
|
42 //expected-note@-9+ {{candidate constructor}}
|
|
43 //expected-note-re@-7+ {{explicit constructor is not a candidate{{$}}}}
|
|
44 //expected-note@-7+ {{candidate function}}
|
|
45 //expected-note@-7+ {{explicit conversion function is not a candidate (explicit specifier evaluates to true)}}
|
|
46
|
|
47 //CHECK: explicit{{ +}}A(
|
|
48 //CHECK-NEXT: explicit(false){{ +}}operator
|
|
49 //CHECK-NEXT: explicit(true){{ +}}operator
|
|
50 A a = 0; //expected-error {{no viable conversion}}
|
|
51 A a1(0);
|
|
52
|
|
53 bool b = a1;
|
|
54 B b1 = a1; //expected-error {{no viable conversion}}
|
|
55
|
|
56 #endif
|
|
57 }
|
|
58
|
|
59
|
|
60 namespace templ {
|
|
61 #ifndef USE_PCH
|
|
62
|
|
63 template<bool b>
|
|
64 struct B {
|
|
65 static constexpr bool value = b;
|
|
66 };
|
|
67
|
|
68 template<bool b>
|
|
69 struct A {
|
|
70 explicit(b) A(B<b>) {}
|
|
71 template<typename T>
|
|
72 explicit(b ^ T::value) operator T();
|
|
73 };
|
|
74 B<true> b_true;
|
|
75 B<false> b_false;
|
|
76 #else
|
|
77 //expected-note@-8 {{candidate template ignored}}
|
|
78 //expected-note@-8 {{explicit constructor declared here}}
|
|
79 //expected-note@-15+ {{candidate constructor}}
|
|
80 //expected-note@-8+ {{explicit conversion function is not a candidate (explicit specifier}}
|
|
81 //expected-note@-11 {{explicit constructor is not a candidate (explicit specifier}}
|
|
82
|
|
83 //CHECK: explicit(b){{ +}}A
|
|
84 //CHECK: explicit(b{{ +}}^{{ +}}T::value){{ +}}operator
|
|
85
|
|
86 A a = { b_true }; //expected-error {{class template argument deduction}}
|
|
87 A a0 = b_true; //expected-error {{no viable constructor or deduction guide}}
|
|
88 A a_true(b_true);
|
|
89 A a_false = b_false;
|
|
90
|
|
91 B<true> b = a_true;
|
|
92 B<true> b1 = a_false; //expected-error {{no viable conversion}}
|
|
93 B<false> b2(a_true);
|
|
94
|
|
95 #endif
|
|
96
|
|
97 }
|
|
98
|
|
99 namespace guide {
|
|
100
|
|
101 #ifndef USE_PCH
|
|
102
|
|
103 template<typename T>
|
|
104 struct A {
|
|
105 A(T);
|
|
106 };
|
|
107
|
|
108 template<typename T>
|
|
109 explicit(true) A(T) -> A<T>;
|
|
110
|
|
111 explicit(false) A(int) -> A<int>;
|
|
112
|
|
113 #else
|
|
114 //expected-note@-5 {{explicit deduction guide}}
|
|
115
|
|
116 //CHECK: explicit(true){{ +}}A(
|
|
117 //CHECK: explicit(false){{ +}}A(
|
|
118
|
|
119 A a = { 0.0 }; //expected-error {{explicit deduction guide}}
|
|
120 A a1 = { 0 };
|
|
121
|
|
122 #endif
|
|
123
|
|
124 }
|