Revert "[llvm] Improve llvm.objectsize computation by computing GEP, alloca and mallo...
[llvm-project.git] / clang / test / CXX / temp / temp.fct.spec / temp.deduct / temp.deduct.conv / p4.cpp
blob974240c514846c31e7429dfe85068bc0d01b88cd
1 // RUN: %clang_cc1 -fsyntax-only %s -verify
2 // RUN: %clang_cc1 -std=c++11 -fsyntax-only %s -verify
3 // RUN: %clang_cc1 -std=c++17 -fsyntax-only %s -verify
5 struct AnyT {
6 template<typename T>
7 operator T();
8 };
10 void test_cvqual_ref(AnyT any) {
11 const int &cir = any;
14 struct AnyThreeLevelPtr {
15 template<typename T>
16 operator T***() const {
17 T x = 0; // expected-note 2{{declared const here}}
18 x = 0; // expected-error 2{{const-qualified type}}
19 T ***p;
20 return p;
24 struct X { };
26 void test_deduce_with_qual(AnyThreeLevelPtr a3) {
27 int * const * const * const ip1 = a3;
28 // FIXME: This is wrong; we are supposed to deduce 'T = int' here.
29 const int * const * const * const ip2 = a3; // expected-note {{instantiation of}}
30 // This one is correct, though.
31 const double * * * ip3 = a3; // expected-note {{instantiation of}}
34 struct AnyPtrMem {
35 template<typename Class, typename T>
36 operator T Class::*() const
38 // This is correct: we don't need a qualification conversion here, so we
39 // deduce 'T = const float'.
40 T x = 0; // expected-note {{declared const here}}
41 x = 0; // expected-error {{const-qualified type}}
42 return 0;
46 void test_deduce_ptrmem_with_qual(AnyPtrMem apm) {
47 const float X::* pm = apm; // expected-note {{instantiation of}}
50 struct TwoLevelPtrMem {
51 template<typename Class1, typename Class2, typename T>
52 operator T Class1::*Class2::*() const
54 T x = 0; // expected-note 2{{declared const here}}
55 x = 0; // expected-error 2{{const-qualified type}}
56 return 0;
60 void test_deduce_two_level_ptrmem_with_qual(TwoLevelPtrMem apm) {
61 // FIXME: This is wrong: we should deduce T = 'float'
62 const float X::* const X::* pm2 = apm; // expected-note {{instantiation of}}
63 // This is correct: we don't need a qualification conversion, so we directly
64 // deduce T = 'const double'
65 const double X::* X::* pm1 = apm; // expected-note {{instantiation of}}
68 namespace non_ptr_ref_cv_qual {
69 template<typename Expected>
70 struct ConvToT {
71 template<typename T> operator T() {
72 using Check = T;
73 using Check = Expected;
76 const int test_conv_to_t_1 = ConvToT<int>();
77 // We intentionally deviate from [temp.deduct.conv]p4 here, and also remove
78 // the top-level cv-quaifiers from A *after* removing the reference type, if
79 // P is not also a reference type. This matches what other compilers are
80 // doing, and is necessary to support real-world code.
81 const int &test_conv_to_t_2 = ConvToT<int>();
83 // Example code that would be broken by the standard's rule.
84 struct Dest {};
85 Dest d1a((ConvToT<Dest>()));
86 Dest d1b = ConvToT<Dest>();
87 Dest &d2 = (d1a = ConvToT<Dest>());
89 template<typename Expected>
90 struct ConvToTRef {
91 template<typename T> operator T&() {
92 using Check = T;
93 using Check = Expected;
96 const int test_conv_to_t_ref_1 = ConvToTRef<int>();
97 const int &test_conv_to_t_ref_2 = ConvToTRef<const int>();
99 Dest d3a((ConvToTRef<const Dest>())); // initialize the copy ctor parameter with 'const Dest&'
100 Dest d3b = ConvToTRef<Dest>(); // convert to non-const T via [over.match.copy]/1.2
101 Dest &d4 = (d3a = ConvToTRef<const Dest>());
103 template<typename Expected>
104 struct ConvToConstT {
105 template<typename T> operator const T() {
106 using Check = T;
107 using Check = Expected;
110 const int test_conv_to_const_t_1 = ConvToConstT<int>();
111 const int &test_conv_to_const_t_2 = ConvToConstT<int>();
113 template<typename Expected>
114 struct ConvToConstTRef {
115 template<typename T> operator const T&() {
116 using Check = T;
117 using Check = Expected;
120 const int test_conv_to_const_t_ref_1 = ConvToConstTRef<int>();
121 const int &test_conv_to_const_t_ref_2 = ConvToConstTRef<int>();
123 template <typename T, int N> using Arr = T[N];
124 struct ConvToArr {
125 template <int N>
126 operator Arr<int, N> &() {
127 static_assert(N == 3, "");
130 int (&test_conv_to_arr_1)[3] = ConvToArr(); // ok
131 const int (&test_conv_to_arr_2)[3] = ConvToArr(); // ok, with qualification conversion
133 struct ConvToConstArr {
134 template <int N>
135 operator const Arr<int, N> &() { // expected-note {{candidate}}
136 static_assert(N == 3, "");
139 Arr<int, 3> &test_conv_to_const_arr_1 = ConvToConstArr(); // expected-error {{no viable}}
140 const Arr<int, 3> &test_conv_to_const_arr_2 = ConvToConstArr(); // ok
142 #if __cplusplus >= 201702L
143 template<bool Noexcept, typename T, typename ...U> using Function = T(U...) noexcept(Noexcept);
144 template<bool Noexcept> struct ConvToFunction {
145 template <typename T, typename ...U> operator Function<Noexcept, T, U...>&(); // expected-note {{candidate}}
147 void (&fn1)(int) noexcept(false) = ConvToFunction<false>();
148 void (&fn2)(int) noexcept(true) = ConvToFunction<false>(); // expected-error {{no viable}}
149 void (&fn3)(int) noexcept(false) = ConvToFunction<true>();
150 void (&fn4)(int) noexcept(true) = ConvToFunction<true>();
152 struct ConvToFunctionDeducingNoexcept {
153 template <bool Noexcept, typename T, typename ...U> operator Function<Noexcept, T, U...>&();
155 void (&fn5)(int) noexcept(false) = ConvToFunctionDeducingNoexcept();
156 void (&fn6)(int) noexcept(true) = ConvToFunctionDeducingNoexcept();
157 #endif