forked from OSchip/llvm-project
125 lines
2.5 KiB
C++
125 lines
2.5 KiB
C++
|
// RUN: %clang_cc1 -std=c++2a -emit-pch %s -o %t-cxx2a
|
||
|
// RUN: %clang_cc1 -std=c++2a -DUSE_PCH -include-pch %t-cxx2a %s -ast-print -verify | FileCheck %s
|
||
|
|
||
|
#ifndef USE_PCH
|
||
|
namespace inheriting_constructor {
|
||
|
struct S {};
|
||
|
|
||
|
template<typename X, typename Y> struct T {
|
||
|
template<typename A>
|
||
|
explicit((Y{}, true)) T(A &&a) {}
|
||
|
};
|
||
|
|
||
|
template<typename X, typename Y> struct U : T<X, Y> {
|
||
|
using T<X, Y>::T;
|
||
|
};
|
||
|
|
||
|
U<S, char> foo(char ch) {
|
||
|
return U<S, char>(ch);
|
||
|
}
|
||
|
}
|
||
|
#else
|
||
|
namespace inheriting_constructor {
|
||
|
U<S, char> a = foo('0');
|
||
|
}
|
||
|
|
||
|
//CHECK: explicit((char{} , true))
|
||
|
|
||
|
#endif
|
||
|
|
||
|
namespace basic {
|
||
|
#ifndef USE_PCH
|
||
|
|
||
|
struct B {};
|
||
|
|
||
|
struct A {
|
||
|
explicit A(int);
|
||
|
explicit(false) operator bool();
|
||
|
explicit(true) operator B();
|
||
|
};
|
||
|
#else
|
||
|
//expected-note@-6+ {{candidate constructor}}
|
||
|
//expected-note@-9+ {{candidate constructor}}
|
||
|
//expected-note@-6+ {{candidate function}}
|
||
|
|
||
|
//CHECK: explicit{{ +}}A(
|
||
|
//CHECK-NEXT: explicit(false){{ +}}operator
|
||
|
//CHECK-NEXT: explicit(true){{ +}}operator
|
||
|
A a = 0; //expected-error {{no viable conversion}}
|
||
|
A a1(0);
|
||
|
|
||
|
bool b = a1;
|
||
|
B b1 = a1; //expected-error {{no viable conversion}}
|
||
|
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
|
||
|
namespace templ {
|
||
|
#ifndef USE_PCH
|
||
|
|
||
|
template<bool b>
|
||
|
struct B {
|
||
|
static constexpr bool value = b;
|
||
|
};
|
||
|
|
||
|
template<bool b>
|
||
|
struct A {
|
||
|
explicit(b) A(B<b>) {}
|
||
|
template<typename T>
|
||
|
explicit(b ^ T::value) operator T();
|
||
|
};
|
||
|
B<true> b_true;
|
||
|
B<false> b_false;
|
||
|
#else
|
||
|
//expected-note@-8 {{candidate template ignored}}
|
||
|
//expected-note@-8+ {{explicit constructor}}
|
||
|
//expected-note@-15+ {{candidate constructor}}
|
||
|
//expected-note@-8+ {{candidate conversion operator ignored}}
|
||
|
//expected-note@-9+ {{explicit(bool) specifier resolved to true}}
|
||
|
//expected-note@-12 {{explicit(bool) specifier resolved to true}}
|
||
|
//expected-note@-13+ {{candidate deductiong guide ignored}}
|
||
|
|
||
|
//CHECK: explicit(b){{ +}}A
|
||
|
//CHECK: explicit(b{{ +}}^{{ +}}T::value){{ +}}operator
|
||
|
|
||
|
A a = { b_true }; //expected-error {{class template argument deduction}}
|
||
|
A a0 = b_true; //expected-error {{no viable constructor or deduction guide}}
|
||
|
A a_true(b_true);
|
||
|
A a_false = b_false;
|
||
|
|
||
|
B<true> b = a_true;
|
||
|
B<true> b1 = a_false; //expected-error {{no viable conversion}}
|
||
|
B<false> b2(a_true);
|
||
|
|
||
|
#endif
|
||
|
|
||
|
}
|
||
|
|
||
|
namespace guide {
|
||
|
|
||
|
#ifndef USE_PCH
|
||
|
|
||
|
template<typename T>
|
||
|
struct A {
|
||
|
A(T);
|
||
|
};
|
||
|
|
||
|
template<typename T>
|
||
|
explicit(true) A(T) -> A<T>;
|
||
|
|
||
|
explicit(false) A(int) -> A<int>;
|
||
|
|
||
|
#else
|
||
|
//expected-note@-5 {{explicit deduction guide}}
|
||
|
|
||
|
//CHECK: explicit(true){{ +}}A(
|
||
|
//CHECK: explicit(false){{ +}}A(
|
||
|
|
||
|
A a = { 0.0 }; //expected-error {{explicit deduction guide}}
|
||
|
A a1 = { 0 };
|
||
|
|
||
|
#endif
|
||
|
|
||
|
}
|