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 } 125