// RUN: %clang_cc1 -fsyntax-only %s -verify // RUN: %clang_cc1 -std=c++11 -fsyntax-only %s -verify // RUN: %clang_cc1 -std=c++17 -fsyntax-only %s -verify struct AnyT { template operator T(); }; void test_cvqual_ref(AnyT any) { const int &cir = any; } struct AnyThreeLevelPtr { template operator T***() const { T x = 0; // expected-note 2{{declared const here}} x = 0; // expected-error 2{{const-qualified type}} T ***p; return p; } }; struct X { }; void test_deduce_with_qual(AnyThreeLevelPtr a3) { int * const * const * const ip1 = a3; // FIXME: This is wrong; we are supposed to deduce 'T = int' here. const int * const * const * const ip2 = a3; // expected-note {{instantiation of}} // This one is correct, though. const double * * * ip3 = a3; // expected-note {{instantiation of}} } struct AnyPtrMem { template operator T Class::*() const { // This is correct: we don't need a qualification conversion here, so we // deduce 'T = const float'. T x = 0; // expected-note {{declared const here}} x = 0; // expected-error {{const-qualified type}} return 0; } }; void test_deduce_ptrmem_with_qual(AnyPtrMem apm) { const float X::* pm = apm; // expected-note {{instantiation of}} } struct TwoLevelPtrMem { template operator T Class1::*Class2::*() const { T x = 0; // expected-note 2{{declared const here}} x = 0; // expected-error 2{{const-qualified type}} return 0; } }; void test_deduce_two_level_ptrmem_with_qual(TwoLevelPtrMem apm) { // FIXME: This is wrong: we should deduce T = 'float' const float X::* const X::* pm2 = apm; // expected-note {{instantiation of}} // This is correct: we don't need a qualification conversion, so we directly // deduce T = 'const double' const double X::* X::* pm1 = apm; // expected-note {{instantiation of}} } namespace non_ptr_ref_cv_qual { template struct ConvToT { template operator T() { using Check = T; using Check = Expected; } }; const int test_conv_to_t_1 = ConvToT(); // We intentionally deviate from [temp.deduct.conv]p4 here, and also remove // the top-level cv-quaifiers from A *after* removing the reference type, if // P is not also a reference type. This matches what other compilers are // doing, and is necessary to support real-world code. const int &test_conv_to_t_2 = ConvToT(); // Example code that would be broken by the standard's rule. struct Dest {}; Dest d1a((ConvToT())); Dest d1b = ConvToT(); Dest &d2 = (d1a = ConvToT()); template struct ConvToTRef { template operator T&() { using Check = T; using Check = Expected; } }; const int test_conv_to_t_ref_1 = ConvToTRef(); const int &test_conv_to_t_ref_2 = ConvToTRef(); Dest d3a((ConvToTRef())); // initialize the copy ctor parameter with 'const Dest&' Dest d3b = ConvToTRef(); // convert to non-const T via [over.match.copy]/1.2 Dest &d4 = (d3a = ConvToTRef()); template struct ConvToConstT { template operator const T() { using Check = T; using Check = Expected; } }; const int test_conv_to_const_t_1 = ConvToConstT(); const int &test_conv_to_const_t_2 = ConvToConstT(); template struct ConvToConstTRef { template operator const T&() { using Check = T; using Check = Expected; } }; const int test_conv_to_const_t_ref_1 = ConvToConstTRef(); const int &test_conv_to_const_t_ref_2 = ConvToConstTRef(); template using Arr = T[N]; struct ConvToArr { template operator Arr &() { static_assert(N == 3, ""); } }; int (&test_conv_to_arr_1)[3] = ConvToArr(); // ok const int (&test_conv_to_arr_2)[3] = ConvToArr(); // ok, with qualification conversion #if __cplusplus >= 201702L template using Function = T(U...) noexcept(Noexcept); template struct ConvToFunction { template operator Function&(); // expected-note {{candidate}} }; void (&fn1)(int) noexcept(false) = ConvToFunction(); void (&fn2)(int) noexcept(true) = ConvToFunction(); // expected-error {{no viable}} void (&fn3)(int) noexcept(false) = ConvToFunction(); void (&fn4)(int) noexcept(true) = ConvToFunction(); struct ConvToFunctionDeducingNoexcept { template operator Function&(); }; void (&fn5)(int) noexcept(false) = ConvToFunctionDeducingNoexcept(); void (&fn6)(int) noexcept(true) = ConvToFunctionDeducingNoexcept(); #endif }