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