• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 {{pointer to subobject of string literal}}
10   A<const char (&)[5], "test"> b; // expected-error {{reference to string literal}}
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   extern char aub[];
28   A<char[], aub> k;
29 }
30 
31 namespace Function {
32   void f();
33   void g() noexcept;
34   void h();
35   void h(int);
36   template<typename...T> void i(T...);
37   typedef A<void (*)(), f> a;
38   typedef A<void (*)(), &f> a;
39   typedef A<void (*)(), g> b;
40   typedef A<void (*)(), &g> b;
41   typedef A<void (*)(), h> c;
42   typedef A<void (*)(), &h> c;
43   typedef A<void (*)(), i> d;
44   typedef A<void (*)(), &i> d;
45   typedef A<void (*)(), i<>> d;
46   typedef A<void (*)(), i<int>> e; // expected-error {{is not implicitly convertible}}
47 
48   typedef A<void (*)(), 0> x; // expected-error {{not allowed in a converted constant}}
49   typedef A<void (*)(), nullptr> y;
50 }
51 
Func()52 void Func() {
53   A<const char*, __func__> a; // expected-error {{pointer to subobject of predefined '__func__' variable}}
54 }
55 
56 namespace LabelAddrDiff {
f()57   void f() {
58     a: b: A<int, __builtin_constant_p(true) ? (__INTPTR_TYPE__)&&b - (__INTPTR_TYPE__)&&a : 0> s; // expected-error {{label address difference}}
59   };
60 }
61 
62 namespace Temp {
63   struct S { int n; };
addr(S && s)64   constexpr S &addr(S &&s) { return s; }
65   A<S &, addr({})> a; // expected-error {{reference to temporary object}}
66   A<S *, &addr({})> b; // expected-error {{pointer to temporary object}}
67   A<int &, addr({}).n> c; // expected-error {{reference to subobject of temporary object}}
68   A<int *, &addr({}).n> d; // expected-error {{pointer to subobject of temporary object}}
69 }
70 
71 namespace std { struct type_info; }
72 
73 namespace RTTI {
74   A<const std::type_info&, typeid(int)> a; // expected-error {{reference to type_info object}}
75   A<const std::type_info*, &typeid(int)> b; // expected-error {{pointer to type_info object}}
76 }
77 
78 namespace PtrMem {
79   struct B { int b; };
80   struct C : B {};
81   struct D : B {};
82   struct E : C, D { int e; };
83 
84   constexpr int B::*b = &B::b;
85   constexpr int C::*cb = b;
86   constexpr int D::*db = b;
87   constexpr int E::*ecb = cb; // expected-note +{{here}}
88   constexpr int E::*edb = db; // expected-note +{{here}}
89 
90   constexpr int E::*e = &E::e;
91   constexpr int D::*de = (int D::*)e;
92   constexpr int C::*ce = (int C::*)e;
93   constexpr int B::*bde = (int B::*)de; // expected-note +{{here}}
94   constexpr int B::*bce = (int B::*)ce; // expected-note +{{here}}
95 
96   // FIXME: This should all be accepted, but we don't yet have a representation
97   // nor mangling for this form of template argument.
98   using Ab = A<int B::*, b>;
99   using Ab = A<int B::*, &B::b>;
100   using Abce = A<int B::*, bce>; // expected-error {{not supported}}
101   using Abde = A<int B::*, bde>; // expected-error {{not supported}}
102   static_assert(!is_same<Ab, Abce>, ""); // expected-error {{undeclared}} expected-error {{must be a type}}
103   static_assert(!is_same<Ab, Abde>, ""); // expected-error {{undeclared}} expected-error {{must be a type}}
104   static_assert(!is_same<Abce, Abde>, ""); // expected-error 2{{undeclared}} expected-error {{must be a type}}
105   static_assert(is_same<Abce, A<int B::*, (int B::*)(int C::*)&E::e>>, ""); // expected-error {{undeclared}} expected-error {{not supported}}
106 
107   using Ae = A<int E::*, e>;
108   using Ae = A<int E::*, &E::e>;
109   using Aecb = A<int E::*, ecb>; // expected-error {{not supported}}
110   using Aedb = A<int E::*, edb>; // expected-error {{not supported}}
111   static_assert(!is_same<Ae, Aecb>, ""); // expected-error {{undeclared}} expected-error {{must be a type}}
112   static_assert(!is_same<Ae, Aedb>, ""); // expected-error {{undeclared}} expected-error {{must be a type}}
113   static_assert(!is_same<Aecb, Aedb>, ""); // expected-error 2{{undeclared}} expected-error {{must be a type}}
114   static_assert(is_same<Aecb, A<int E::*, (int E::*)(int C::*)&B::b>>, ""); // expected-error {{undeclared}} expected-error {{not supported}}
115 
116   using An = A<int E::*, nullptr>;
117   using A0 = A<int E::*, (int E::*)0>;
118   static_assert(is_same<An, A0>);
119 }
120 
121 namespace DeduceDifferentType {
122   template<int N> struct A {};
123   template<long N> int a(A<N>); // expected-note {{does not have the same type}}
124   int a_imp = a(A<3>()); // expected-error {{no matching function}}
125   int a_exp = a<3>(A<3>());
126 
127   template<decltype(nullptr)> struct B {};
128   template<int *P> int b(B<P>); // expected-error {{value of type 'int *' is not implicitly convertible to 'decltype(nullptr)'}}
129   int b_imp = b(B<nullptr>()); // expected-error {{no matching function}}
130   int b_exp = b<nullptr>(B<nullptr>()); // expected-error {{no matching function}}
131 
operator intDeduceDifferentType::X132   struct X { constexpr operator int() { return 0; } } x;
133   template<X &> struct C {};
134   template<int N> int c(C<N>); // expected-error {{value of type 'int' is not implicitly convertible to 'DeduceDifferentType::X &'}}
135   int c_imp = c(C<x>()); // expected-error {{no matching function}}
136   int c_exp = c<x>(C<x>()); // expected-error {{no matching function}}
137 
138   struct Z;
139   struct Y { constexpr operator Z&(); } y;
operator Y&DeduceDifferentType::Z140   struct Z { constexpr operator Y&() { return y; } } z;
operator Z&()141   constexpr Y::operator Z&() { return z; }
142   template<Y &> struct D {};
143   template<Z &z> int d(D<z>); // expected-note {{couldn't infer template argument 'z'}}
144   int d_imp = d(D<y>()); // expected-error {{no matching function}}
145   int d_exp = d<y>(D<y>());
146 }
147 
148 namespace DeclMatch {
149   template<typename T, T> int f();
150   template<typename T> class X { friend int f<T, 0>(); static int n; };
f()151   template<typename T, T> int f() { return X<T>::n; }
152   int k = f<int, 0>(); // ok, friend
153 }
154 
155 namespace PR24921 {
156   enum E { e };
157   template<E> void f();
158   template<int> void f(int);
f()159   template<> void f<e>() {}
160 }
161 
162 namespace Auto {
163   namespace Basic {
164     // simple auto
165     template<auto x> constexpr auto constant = x; // expected-note {{declared here}}
166 
167     auto v1 = constant<5>;
168     auto v2 = constant<true>;
169     auto v3 = constant<'a'>;
170     auto v4 = constant<2.5>;  // expected-error {{cannot have type 'double'}}
171 
172     using T1 = decltype(v1);
173     using T1 = int;
174     using T2 = decltype(v2);
175     using T2 = bool;
176     using T3 = decltype(v3);
177     using T3 = char;
178 
179     // pointers
180     template<auto v>    class B { };
181     template<auto* p>   class B<p> { }; // expected-note {{matches}}
182     template<auto** pp> class B<pp> { };
183     template<auto* p0>   int &f(B<p0> b); // expected-note {{candidate}}
184     template<auto** pp0> float &f(B<pp0> b); // expected-note {{candidate}}
185 
186     int a, *b = &a;
187     int &r = f(B<&a>());
188     float &s = f(B<&b>());
189 
190     // pointers to members
191     template<typename T, auto *T::*p> struct B<p> {};
192     template<typename T, auto **T::*p> struct B<p> {};
193     template<typename T, auto *T::*p0>   char &f(B<p0> b); // expected-note {{candidate}}
194     template<typename T, auto **T::*pp0> short &f(B<pp0> b); // expected-note {{candidate}}
195 
196     struct X { int n; int *p; int **pp; typedef int a, b; };
197     auto t = f(B<&X::n>()); // expected-error {{no match}}
198     char &u = f(B<&X::p>());
199     short &v = f(B<&X::pp>());
200 
201     // A case where we need to do auto-deduction, and check whether the
202     // resulting dependent types match during partial ordering. These
203     // templates are not ordered due to the mismatching function parameter.
204     template<typename T, auto *(*f)(T, typename T::a)> struct B<f> {}; // expected-note {{matches}}
205     template<typename T, auto **(*f)(T, typename T::b)> struct B<f> {}; // expected-note {{matches}}
206     int **g(X, int);
207     B<&g> bg; // expected-error {{ambiguous}}
208   }
209 
210   namespace Chained {
211     // chained template argument deduction
212     template<long n> struct C { };
213     template<class T> struct D;
214     template<class T, T n> struct D<C<n>>
215     {
216         using Q = T;
217     };
218     using DQ = long;
219     using DQ = D<C<short(2)>>::Q;
220 
221     // chained template argument deduction from an array bound
222     template<typename T> struct E;
223     template<typename T, T n> struct E<int[n]> {
224         using Q = T;
225     };
226     using EQ = E<int[short(42)]>::Q;
227     using EQ = decltype(sizeof 0);
228 
229     template<int N> struct F;
230     template<typename T, T N> int foo(F<N> *) = delete;  // expected-note {{explicitly deleted}}
231     void foo(void *); // expected-note {{candidate function}}
bar(F<0> * p)232     void bar(F<0> *p) {
233         foo(p); // expected-error {{deleted function}}
234     }
235   }
236 
237   namespace ArrayToPointer {
238     constexpr char s[] = "test";
239     template<const auto* p> struct S { };
240     S<s> p;
241 
242     template<typename R, typename P, R F(P)> struct A {};
243     template<typename R, typename P, R F(P)> void x(A<R, P, F> a);
g(int)244     void g(int) { x(A<void, int, &g>()); }
245   }
246 
247   namespace DecltypeAuto {
248     template<auto v> struct A { };
249     template<decltype(auto) v> struct DA { };
250     template<auto&> struct R { };
251 
252     auto n = 0; // expected-note + {{declared here}}
253     A<n> a; // expected-error {{not a constant}} expected-note {{non-const variable 'n'}}
254     DA<n> da1;  // expected-error {{not a constant}} expected-note {{non-const variable 'n'}}
255     DA<(n)> da2;
256     R<n> r;
257   }
258 
259   namespace Decomposition {
260     // Types of deduced non-type template arguments must match exactly, so
261     // partial ordering fails in both directions here.
262     template<auto> struct Any;
263     template<int N> struct Any<N> { typedef int Int; }; // expected-note 3{{match}}
264     template<short N> struct Any<N> { typedef int Short; }; // expected-note 3{{match}}
265     Any<0>::Int is_int; // expected-error {{ambiguous}}
266     Any<(short)0>::Short is_short; // expected-error {{ambiguous}}
267     Any<(char)0>::Short is_char; // expected-error {{ambiguous}}
268 
269     template<int, auto> struct NestedAny;
270     template<auto N> struct NestedAny<0, N>; // expected-note 3{{match}}
271     template<int N> struct NestedAny<0, N> { typedef int Int; }; // expected-note 3{{match}}
272     template<short N> struct NestedAny<0, N> { typedef int Short; }; // expected-note 3{{match}}
273     NestedAny<0, 0>::Int nested_int; // expected-error {{ambiguous}}
274     NestedAny<0, (short)0>::Short nested_short; // expected-error {{ambiguous}}
275     NestedAny<0, (char)0>::Short nested_char; // expected-error {{ambiguous}}
276 
277     double foo(int, bool);
278     template<auto& f> struct fn_result_type;
279 
280     template<class R, class... Args, R (& f)(Args...)>
281     struct fn_result_type<f>
282     {
283         using type = R;
284     };
285 
286     using R1 = fn_result_type<foo>::type;
287     using R1 = double;
288 
289     template<int, auto &f> struct fn_result_type_partial_order;
290     template<auto &f> struct fn_result_type_partial_order<0, f>;
291     template<class R, class... Args, R (& f)(Args...)>
292     struct fn_result_type_partial_order<0, f> {};
293     fn_result_type_partial_order<0, foo> frtpo;
294   }
295 
296   namespace Variadic {
297     template<auto... vs> struct value_list { };
298 
299     using size_t = decltype(sizeof 0);
300     template<size_t n, class List> struct nth_element;
301     template<size_t n, class List> constexpr auto nth_element_v = nth_element<n, List>::value;
302 
303     template<size_t n, auto v0, auto... vs>
304     struct nth_element<n, value_list<v0, vs...>>
305     {
306         static constexpr auto value = nth_element<n - 1, value_list<vs...>>::value;
307     };
308     template<auto v0, auto... vs>
309     struct nth_element<0, value_list<v0, vs...>>
310     {
311         static constexpr auto value = v0;
312     };
313 
314     static_assert(nth_element_v<2, value_list<'a', 27U, false>> == false, "value mismatch");
315   }
316 }
317 
318 namespace Nested {
319   template<typename T> struct A {
320     template<auto X> struct B;
321     template<auto *P> struct B<P>;
322     template<auto **P> struct B<P> { using pointee = decltype(+**P); };
323     template<auto (*P)(T)> struct B<P> { using param = T; };
324     template<typename U, auto (*P)(T, U)> struct B<P> { using param2 = U; };
325   };
326 
327   using Int = int;
328 
329   int *n;
330   using Int = A<int>::B<&n>::pointee;
331 
332   void f(int);
333   using Int = A<int>::B<&f>::param;
334 
335   void g(int, int);
336   using Int = A<int>::B<&g>::param2;
337 }
338 
339 namespace rdar41852459 {
340 template <auto V> struct G {};
341 
342 template <class T> struct S {
frdar41852459::S343   template <auto V> void f() {
344     G<V> x;
345   }
f2rdar41852459::S346   template <auto *PV> void f2() {
347     G<PV> x;
348   }
f3rdar41852459::S349   template <decltype(auto) V> void f3() {
350     G<V> x;
351   }
352 };
353 
354 template <auto *PV> struct I {};
355 
356 template <class T> struct K {
frdar41852459::K357   template <auto *PV> void f() {
358     I<PV> x;
359   }
f2rdar41852459::K360   template <auto V> void f2() {
361     I<V> x;
362   }
f3rdar41852459::K363   template <decltype(auto) V> void f3() {
364     I<V> x;
365   }
366 };
367 
368 template <decltype(auto)> struct L {};
369 template <class T> struct M {
frdar41852459::M370   template <auto *PV> void f() {
371     L<PV> x;
372   }
frdar41852459::M373   template <auto V> void f() {
374     L<V> x;
375   }
frdar41852459::M376   template <decltype(auto) V> void f() {
377     L<V> x;
378   }
379 };
380 }
381 
382 namespace PR42362 {
383   template<auto ...A> struct X { struct Y; void f(int...[A]); };
384   template<auto ...A> struct X<A...>::Y {};
f(int...[A])385   template<auto ...A> void X<A...>::f(int...[A]) {}
f()386   void f() { X<1, 2>::Y y; X<1, 2>().f(0, 0); }
387 
388   template<typename, auto...> struct Y;
389   template<auto ...A> struct Y<int, A...> {};
390   Y<int, 1, 2, 3> y;
391 
392   template<auto (&...F)()> struct Z { struct Q; };
393   template<auto (&...F)()> struct Z<F...>::Q {};
394   Z<f, f, f>::Q q;
395 }
396 
397 namespace QualConv {
398   int *X;
f()399   template<const int *const *P> void f() {
400     using T = decltype(P);
401     using T = const int* const*;
402   }
403   template void f<&X>();
404 
g()405   template<const int *const &R> void g() {
406     using T = decltype(R);
407     using T = const int *const &;
408   }
409   template void g<(const int *const&)X>();
410 }
411 
412 namespace FunctionConversion {
413   struct a { void c(char *) noexcept; };
g()414   template<void (a::*f)(char*)> void g() {
415     using T = decltype(f);
416     using T = void (a::*)(char*); // (not 'noexcept')
417   }
418   template void g<&a::c>();
419 
420   void c() noexcept;
h()421   template<void (*p)()> void h() {
422     using T = decltype(p);
423     using T = void (*)(); // (not 'noexcept')
424   }
425   template void h<&c>();
426 }
427 
428 namespace VoidPtr {
429   // Note, this is an extension in C++17 but valid in C++20.
f()430   template<void *P> void f() {
431     using T = decltype(P);
432     using T = void*;
433   }
434   int n;
435   template void f<(void*)&n>();
436 }
437 
438 namespace PR42108 {
439   struct R {};
SPR42108::S440   struct S { constexpr S() {} constexpr S(R) {} };
operator SPR42108::T441   struct T { constexpr operator S() { return {}; } };
442   template <const S &> struct A {};
f()443   void f() {
444     A<R{}>(); // expected-error {{would bind reference to a temporary}}
445     A<S{}>(); // expected-error {{reference to temporary object}}
446     A<T{}>(); // expected-error {{reference to temporary object}}
447   }
448 }
449 
450 namespace PR46637 {
451   template<auto (*f)() -> auto> struct X { // expected-note {{here}}
callPR46637::X452     auto call() { return f(); }
453   };
454   X<nullptr> x; // expected-error {{incompatible initializer}}
455 
456   void *f();
457   X<f> y;
458   int n = y.call(); // expected-error {{cannot initialize a variable of type 'int' with an rvalue of type 'void *'}}
459 }
460