]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - test/SemaTemplate/temp_arg_nontype_cxx1z.cpp
Vendor import of clang trunk r290819:
[FreeBSD/FreeBSD.git] / test / SemaTemplate / temp_arg_nontype_cxx1z.cpp
1 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++1z %s
2
3 template<typename T, T val> struct A {};
4
5 template<typename T, typename U> constexpr bool is_same = false; // expected-note +{{here}}
6 template<typename T> constexpr bool is_same<T, T> = true;
7
8 namespace String {
9   A<const char*, "test"> a; // expected-error {{does not refer to any declaration}}
10   A<const char (&)[5], "test"> b; // expected-error {{does not refer to any declaration}}
11 }
12
13 namespace Array {
14   char arr[3];
15   char x;
16   A<const char*, arr> a;
17   A<const char(&)[3], arr> b;
18   A<const char*, &arr[0]> c;
19   A<const char*, &arr[1]> d; // expected-error {{refers to subobject '&arr[1]'}}
20   A<const char*, (&arr)[0]> e;
21   A<const char*, &x> f;
22   A<const char*, &(&x)[0]> g;
23   A<const char*, &(&x)[1]> h; // expected-error {{refers to subobject '&x + 1'}}
24   A<const char*, 0> i; // expected-error {{not allowed in a converted constant}}
25   A<const char*, nullptr> j;
26 }
27
28 namespace Function {
29   void f();
30   void g() noexcept;
31   void h();
32   void h(int);
33   template<typename...T> void i(T...);
34   typedef A<void (*)(), f> a;
35   typedef A<void (*)(), &f> a;
36   typedef A<void (*)(), g> b;
37   typedef A<void (*)(), &g> b;
38   typedef A<void (*)(), h> c;
39   typedef A<void (*)(), &h> c;
40   typedef A<void (*)(), i> d;
41   typedef A<void (*)(), &i> d;
42   typedef A<void (*)(), i<>> d;
43   typedef A<void (*)(), i<int>> e; // expected-error {{is not implicitly convertible}}
44
45   typedef A<void (*)(), 0> x; // expected-error {{not allowed in a converted constant}}
46   typedef A<void (*)(), nullptr> y;
47 }
48
49 void Func() {
50   A<const char*, __func__> a; // expected-error {{does not refer to any declaration}}
51 }
52
53 namespace LabelAddrDiff {
54   void f() {
55     a: b: A<int, __builtin_constant_p(true) ? (__INTPTR_TYPE__)&&b - (__INTPTR_TYPE__)&&a : 0> s; // expected-error {{label address difference}}
56   };
57 }
58
59 namespace Temp {
60   struct S { int n; };
61   constexpr S &addr(S &&s) { return s; }
62   A<S &, addr({})> a; // expected-error {{constant}} expected-note 2{{temporary}}
63   A<S *, &addr({})> b; // expected-error {{constant}} expected-note 2{{temporary}}
64   A<int &, addr({}).n> c; // expected-error {{constant}} expected-note 2{{temporary}}
65   A<int *, &addr({}).n> d; // expected-error {{constant}} expected-note 2{{temporary}}
66 }
67
68 namespace std { struct type_info; }
69
70 namespace RTTI {
71   A<const std::type_info&, typeid(int)> a; // expected-error {{does not refer to any declaration}}
72   A<const std::type_info*, &typeid(int)> b; // expected-error {{does not refer to any declaration}}
73 }
74
75 namespace PtrMem {
76   struct B { int b; };
77   struct C : B {};
78   struct D : B {};
79   struct E : C, D { int e; };
80
81   constexpr int B::*b = &B::b;
82   constexpr int C::*cb = b;
83   constexpr int D::*db = b;
84   constexpr int E::*ecb = cb; // expected-note +{{here}}
85   constexpr int E::*edb = db; // expected-note +{{here}}
86
87   constexpr int E::*e = &E::e;
88   constexpr int D::*de = (int D::*)e;
89   constexpr int C::*ce = (int C::*)e;
90   constexpr int B::*bde = (int B::*)de; // expected-note +{{here}}
91   constexpr int B::*bce = (int B::*)ce; // expected-note +{{here}}
92
93   // FIXME: This should all be accepted, but we don't yet have a representation
94   // nor mangling for this form of template argument.
95   using Ab = A<int B::*, b>;
96   using Ab = A<int B::*, &B::b>;
97   using Abce = A<int B::*, bce>; // expected-error {{not supported}}
98   using Abde = A<int B::*, bde>; // expected-error {{not supported}}
99   static_assert(!is_same<Ab, Abce>, ""); // expected-error {{undeclared}} expected-error {{must be a type}}
100   static_assert(!is_same<Ab, Abde>, ""); // expected-error {{undeclared}} expected-error {{must be a type}}
101   static_assert(!is_same<Abce, Abde>, ""); // expected-error 2{{undeclared}} expected-error {{must be a type}}
102   static_assert(is_same<Abce, A<int B::*, (int B::*)(int C::*)&E::e>, ""); // expected-error {{undeclared}} expected-error {{not supported}}
103
104   using Ae = A<int E::*, e>;
105   using Ae = A<int E::*, &E::e>;
106   using Aecb = A<int E::*, ecb>; // expected-error {{not supported}}
107   using Aedb = A<int E::*, edb>; // expected-error {{not supported}}
108   static_assert(!is_same<Ae, Aecb>, ""); // expected-error {{undeclared}} expected-error {{must be a type}}
109   static_assert(!is_same<Ae, Aedb>, ""); // expected-error {{undeclared}} expected-error {{must be a type}}
110   static_assert(!is_same<Aecb, Aedb>, ""); // expected-error 2{{undeclared}} expected-error {{must be a type}}
111   static_assert(is_same<Aecb, A<int E::*, (int E::*)(int C::*)&B::b>, ""); // expected-error {{undeclared}} expected-error {{not supported}}
112
113   using An = A<int E::*, nullptr>;
114   using A0 = A<int E::*, (int E::*)0>;
115   static_assert(is_same<An, A0>);
116 }
117
118 namespace DeduceDifferentType {
119   template<int N> struct A {};
120   template<long N> int a(A<N>); // expected-note {{does not have the same type}}
121   int a_imp = a(A<3>()); // expected-error {{no matching function}}
122   int a_exp = a<3>(A<3>());
123
124   template<decltype(nullptr)> struct B {};
125   template<int *P> int b(B<P>); // expected-error {{value of type 'int *' is not implicitly convertible to 'decltype(nullptr)'}}
126   int b_imp = b(B<nullptr>()); // expected-error {{no matching function}}
127   int b_exp = b<nullptr>(B<nullptr>()); // expected-error {{no matching function}}
128
129   struct X { constexpr operator int() { return 0; } } x;
130   template<X &> struct C {};
131   template<int N> int c(C<N>); // expected-error {{value of type 'int' is not implicitly convertible to 'DeduceDifferentType::X &'}}
132   int c_imp = c(C<x>()); // expected-error {{no matching function}}
133   int c_exp = c<x>(C<x>()); // expected-error {{no matching function}}
134
135   struct Z;
136   struct Y { constexpr operator Z&(); } y;
137   struct Z { constexpr operator Y&() { return y; } } z;
138   constexpr Y::operator Z&() { return z; }
139   template<Y &> struct D {};
140   template<Z &z> int d(D<z>); // expected-note {{couldn't infer template argument 'z'}}
141   int d_imp = d(D<y>()); // expected-error {{no matching function}}
142   int d_exp = d<y>(D<y>());
143 }
144
145 namespace DeclMatch {
146   template<typename T, T> int f();
147   template<typename T> class X { friend int f<T, 0>(); static int n; };
148   template<typename T, T> int f() { return X<T>::n; }
149   int k = f<int, 0>(); // ok, friend
150 }
151
152 namespace PR24921 {
153   enum E { e };
154   template<E> void f();
155   template<int> void f(int);
156   template<> void f<e>() {}
157 }
158
159 namespace Auto {
160   namespace Basic {
161     // simple auto
162     template<auto x> constexpr auto constant = x; // expected-note {{declared here}}
163
164     auto v1 = constant<5>;
165     auto v2 = constant<true>;
166     auto v3 = constant<'a'>;
167     auto v4 = constant<2.5>;  // expected-error {{cannot have type 'double'}}
168
169     using T1 = decltype(v1);
170     using T1 = int;
171     using T2 = decltype(v2);
172     using T2 = bool;
173     using T3 = decltype(v3);
174     using T3 = char;
175
176     // pointers
177     template<auto v>    class B { };
178     template<auto* p>   class B<p> { }; // expected-note {{matches}}
179     template<auto** pp> class B<pp> { };
180     template<auto* p0>   int &f(B<p0> b); // expected-note {{candidate}}
181     template<auto** pp0> float &f(B<pp0> b); // expected-note {{candidate}}
182
183     int a, *b = &a;
184     int &r = f(B<&a>());
185     float &s = f(B<&b>());
186
187     // pointers to members
188     template<typename T, auto *T::*p> struct B<p> {};
189     template<typename T, auto **T::*p> struct B<p> {};
190     template<typename T, auto *T::*p0>   char &f(B<p0> b); // expected-note {{candidate}}
191     template<typename T, auto **T::*pp0> short &f(B<pp0> b); // expected-note {{candidate}}
192
193     struct X { int n; int *p; int **pp; typedef int a, b; };
194     auto t = f(B<&X::n>()); // expected-error {{no match}}
195     char &u = f(B<&X::p>());
196     short &v = f(B<&X::pp>());
197
198     // A case where we need to do auto-deduction, and check whether the
199     // resulting dependent types match during partial ordering. These
200     // templates are not ordered due to the mismatching function parameter.
201     template<typename T, auto *(*f)(T, typename T::a)> struct B<f> {}; // expected-note {{matches}}
202     template<typename T, auto **(*f)(T, typename T::b)> struct B<f> {}; // expected-note {{matches}}
203     int **g(X, int);
204     B<&g> bg; // expected-error {{ambiguous}}
205   }
206
207   namespace Chained {
208     // chained template argument deduction
209     template<long n> struct C { };
210     template<class T> struct D;
211     template<class T, T n> struct D<C<n>>
212     {
213         using Q = T;
214     };
215     using DQ = long;
216     using DQ = D<C<short(2)>>::Q;
217
218     // chained template argument deduction from an array bound
219     template<typename T> struct E;
220     template<typename T, T n> struct E<int[n]> {
221         using Q = T;
222     };
223     using EQ = E<int[short(42)]>::Q;
224     using EQ = decltype(sizeof 0);
225
226     template<int N> struct F;
227     template<typename T, T N> int foo(F<N> *) = delete;  // expected-note {{explicitly deleted}}
228     void foo(void *); // expected-note {{candidate function}}
229     void bar(F<0> *p) {
230         foo(p); // expected-error {{deleted function}}
231     }
232   }
233
234   namespace ArrayToPointer {
235     constexpr char s[] = "test";
236     template<const auto* p> struct S { };
237     S<s> p;
238   }
239
240   namespace DecltypeAuto {
241     template<auto v> struct A { };
242     template<decltype(auto) v> struct DA { };
243     template<auto&> struct R { };
244
245     auto n = 0; // expected-note + {{declared here}}
246     A<n> a; // expected-error {{not a constant}} expected-note {{non-const variable 'n'}}
247     DA<n> da1;  // expected-error {{not a constant}} expected-note {{non-const variable 'n'}}
248     DA<(n)> da2;
249     R<n> r;
250   }
251
252   namespace Decomposition {
253     // Types of deduced non-type template arguments must match exactly, so
254     // partial ordering fails in both directions here.
255     template<auto> struct Any;
256     template<int N> struct Any<N> { typedef int Int; }; // expected-note 3{{match}}
257     template<short N> struct Any<N> { typedef int Short; }; // expected-note 3{{match}}
258     Any<0>::Int is_int; // expected-error {{ambiguous}}
259     Any<(short)0>::Short is_short; // expected-error {{ambiguous}}
260     Any<(char)0>::Short is_char; // expected-error {{ambiguous}}
261
262     template<int, auto> struct NestedAny;
263     template<auto N> struct NestedAny<0, N>; // expected-note 3{{match}}
264     template<int N> struct NestedAny<0, N> { typedef int Int; }; // expected-note 3{{match}}
265     template<short N> struct NestedAny<0, N> { typedef int Short; }; // expected-note 3{{match}}
266     NestedAny<0, 0>::Int nested_int; // expected-error {{ambiguous}}
267     NestedAny<0, (short)0>::Short nested_short; // expected-error {{ambiguous}}
268     NestedAny<0, (char)0>::Short nested_char; // expected-error {{ambiguous}}
269
270     double foo(int, bool);
271     template<auto& f> struct fn_result_type;
272
273     template<class R, class... Args, R (& f)(Args...)>
274     struct fn_result_type<f>
275     {
276         using type = R;
277     };
278
279     using R1 = fn_result_type<foo>::type;
280     using R1 = double;
281
282     template<int, auto &f> struct fn_result_type_partial_order;
283     template<auto &f> struct fn_result_type_partial_order<0, f>;
284     template<class R, class... Args, R (& f)(Args...)>
285     struct fn_result_type_partial_order<0, f> {};
286     fn_result_type_partial_order<0, foo> frtpo;
287   }
288
289   namespace Variadic {
290     template<auto... vs> struct value_list { };
291
292     using size_t = decltype(sizeof 0);
293     template<size_t n, class List> struct nth_element;
294     template<size_t n, class List> constexpr auto nth_element_v = nth_element<n, List>::value;
295
296     template<size_t n, auto v0, auto... vs>
297     struct nth_element<n, value_list<v0, vs...>>
298     {
299         static constexpr auto value = nth_element<n - 1, value_list<vs...>>::value;
300     };
301     template<auto v0, auto... vs>
302     struct nth_element<0, value_list<v0, vs...>>
303     {
304         static constexpr auto value = v0;
305     };
306
307     static_assert(nth_element_v<2, value_list<'a', 27U, false>> == false, "value mismatch");
308   }
309 }
310
311 namespace Nested {
312   template<typename T> struct A {
313     template<auto X> struct B;
314     template<auto *P> struct B<P>;
315     template<auto **P> struct B<P> { using pointee = decltype(+**P); };
316     template<auto (*P)(T)> struct B<P> { using param = T; };
317     template<typename U, auto (*P)(T, U)> struct B<P> { using param2 = U; };
318   };
319
320   using Int = int;
321
322   int *n;
323   using Int = A<int>::B<&n>::pointee;
324
325   void f(int);
326   using Int = A<int>::B<&f>::param;
327
328   void g(int, int);
329   using Int = A<int>::B<&g>::param2;
330 }