xref: /llvm-project/clang/test/SemaTemplate/temp_arg_nontype.cpp (revision 28ad8978ee2054298d4198bf10c8cb68730af037)
1 // RUN: %clang_cc1 -fsyntax-only -std=c++98 -Wconversion -verify %s
2 template<int N> struct A; // expected-note 5{{template parameter is declared here}}
3 
4 A<0> *a0;
5 
6 A<int()> *a1; // expected-error{{template argument for non-type template parameter is treated as function type 'int ()'}}
7 
8 A<int> *a2; // expected-error{{template argument for non-type template parameter must be an expression}}
9 
10 A<1 >> 2> *a3; // expected-warning{{use of right-shift operator ('>>') in template argument will require parentheses in C++11}}
11 
12 // C++ [temp.arg.nontype]p5:
13 A<A> *a4; // expected-error{{must be an expression}}
14 
15 enum E { Enumerator = 17 };
16 A<E> *a5; // expected-error{{template argument for non-type template parameter must be an expression}}
17 template<E Value> struct A1; // expected-note{{template parameter is declared here}}
18 A1<Enumerator> *a6; // okay
19 A1<17> *a7; // expected-error{{non-type template argument of type 'int' cannot be converted to a value of type 'E'}}
20 
21 const long LongValue = 12345678;
22 A<LongValue> *a8;
23 const short ShortValue = 17;
24 A<ShortValue> *a9;
25 
26 int f(int);
27 A<f(17)> *a10; // expected-error{{non-type template argument of type 'int' is not an integral constant expression}}
28 
29 class X {
30 public:
31   X();
32   X(int, int);
33   operator int() const;
34 };
35 A<X(17, 42)> *a11; // expected-error{{non-type template argument of type 'X' must have an integral or enumeration type}}
36 
37 float f(float);
38 
39 float g(float); // expected-note 2{{candidate function}}
40 double g(double); // expected-note 2{{candidate function}}
41 
42 int h(int);
43 float h2(float);
44 
45 template<int fp(int)> struct A3; // expected-note 1{{template parameter is declared here}}
46 A3<h> *a14_1;
47 A3<&h> *a14_2;
48 A3<f> *a14_3;
49 A3<&f> *a14_4;
50 A3<h2> *a14_6;  // expected-error{{non-type template argument of type 'float (float)' cannot be converted to a value of type 'int (*)(int)'}}
51 A3<g> *a14_7; // expected-error{{address of overloaded function 'g' does not match required type 'int (int)'}}
52 
53 
54 struct Y { } y;
55 
56 volatile X * X_volatile_ptr;
57 template<X const &AnX> struct A4; // expected-note 2{{template parameter is declared here}}
58 X an_X;
59 A4<an_X> *a15_1; // okay
60 A4<*X_volatile_ptr> *a15_2; // expected-error{{non-type template argument does not refer to any declaration}}
61 A4<y> *15_3; //  expected-error{{non-type template parameter of reference type 'const X &' cannot bind to template argument of type 'struct Y'}} \
62             // FIXME: expected-error{{expected unqualified-id}}
63 
64 template<int (&fr)(int)> struct A5; // expected-note{{template parameter is declared here}}
65 A5<h> *a16_1;
66 A5<f> *a16_3;
67 A5<h2> *a16_6;  // expected-error{{non-type template parameter of reference type 'int (&)(int)' cannot bind to template argument of type 'float (float)'}}
68 A5<g> *a14_7; // expected-error{{address of overloaded function 'g' does not match required type 'int (int)'}}
69 
70 struct Z {
71   int foo(int);
72   float bar(float);
73   int bar(int);
74   double baz(double);
75 
76   int int_member;
77   float float_member;
78   union {
79     int union_member;
80   };
81 };
82 template<int (Z::*pmf)(int)> struct A6; // expected-note{{template parameter is declared here}}
83 A6<&Z::foo> *a17_1;
84 A6<&Z::bar> *a17_2;
85 A6<&Z::baz> *a17_3; // expected-error-re{{non-type template argument of type 'double (Z::*)(double){{( __attribute__\(\(thiscall\)\))?}}' cannot be converted to a value of type 'int (Z::*)(int){{( __attribute__\(\(thiscall\)\))?}}'}}
86 
87 
88 template<int Z::*pm> struct A7;  // expected-note{{template parameter is declared here}}
89 template<int Z::*pm> struct A7c;
90 A7<&Z::int_member> *a18_1;
91 A7c<&Z::int_member> *a18_2;
92 A7<&Z::float_member> *a18_3; // expected-error{{non-type template argument of type 'float Z::*' cannot be converted to a value of type 'int Z::*'}}
93 A7c<(&Z::int_member)> *a18_4; // expected-warning{{address non-type template argument cannot be surrounded by parentheses}}
94 A7c<&Z::union_member> *a18_5;
95 
96 template<unsigned char C> struct Overflow; // expected-note{{template parameter is declared here}}
97 
98 Overflow<5> *overflow1; // okay
99 Overflow<255> *overflow2; // okay
100 Overflow<256> *overflow3; // expected-warning{{non-type template argument value '256' truncated to '0' for template parameter of type 'unsigned char'}}
101 
102 
103 template<unsigned> struct Signedness; // expected-note{{template parameter is declared here}}
104 Signedness<10> *signedness1; // okay
105 Signedness<-10> *signedness2; // expected-warning{{non-type template argument with value '-10' converted to '4294967286' for unsigned template parameter of type 'unsigned int'}}
106 
107 template<signed char C> struct SignedOverflow; // expected-note 3 {{template parameter is declared here}}
108 SignedOverflow<1> *signedoverflow1;
109 SignedOverflow<-1> *signedoverflow2;
110 SignedOverflow<-128> *signedoverflow3;
111 SignedOverflow<-129> *signedoverflow4; // expected-warning{{non-type template argument value '-129' truncated to '127' for template parameter of type 'signed char'}}
112 SignedOverflow<127> *signedoverflow5;
113 SignedOverflow<128> *signedoverflow6; // expected-warning{{non-type template argument value '128' truncated to '-128' for template parameter of type 'signed char'}}
114 SignedOverflow<(unsigned char)128> *signedoverflow7; // expected-warning{{non-type template argument value '128' truncated to '-128' for template parameter of type 'signed char'}}
115 
116 // Check canonicalization of template arguments.
117 template<int (*)(int, int)> struct FuncPtr0;
118 int func0(int, int);
119 extern FuncPtr0<&func0> *fp0;
120 template<int (*)(int, int)> struct FuncPtr0;
121 extern FuncPtr0<&func0> *fp0;
122 int func0(int, int);
123 extern FuncPtr0<&func0> *fp0;
124 
125 // PR5350
126 namespace ns {
127   template <typename T>
128   struct Foo {
129     static const bool value = true;
130   };
131 
132   template <bool b>
133   struct Bar {};
134 
135   const bool value = false;
136 
137   Bar<bool(ns::Foo<int>::value)> x;
138 }
139 
140 // PR5349
141 namespace ns {
142   enum E { k };
143 
144   template <E e>
145   struct Baz  {};
146 
147   Baz<k> f1;  // This works.
148   Baz<E(0)> f2;  // This too.
149   Baz<static_cast<E>(0)> f3;  // And this.
150 
151   Baz<ns::E(0)> b1;  // This doesn't work.
152   Baz<static_cast<ns::E>(0)> b2;  // This neither.
153 }
154 
155 // PR5597
156 template<int (*)(float)> struct X0 { };
157 
158 struct X1 {
159     static int pfunc(float);
160 };
161 void test_X0_X1() {
162   X0<X1::pfunc> x01;
163 }
164 
165 // PR6249
166 namespace pr6249 {
167   template<typename T, T (*func)()> T f() {
168     return func();
169   }
170 
171   int h();
172   template int f<int, h>();
173 }
174 
175 namespace PR6723 {
176   template<unsigned char C> void f(int (&a)[C]); // expected-note 3{{candidate template ignored: substitution failure [with C = '\x00']}}
177   // expected-note@-1 {{not viable: no known conversion from 'int[512]' to 'int (&)[0]'}}
178   void g() {
179     int arr512[512];
180     f(arr512); // expected-error{{no matching function for call}}
181     f<512>(arr512); // expected-error{{no matching function for call}}
182 
183     int arr0[0];
184     f(arr0); // expected-error{{no matching function for call}}
185     f<0>(arr0); // expected-error{{no matching function for call}}
186   }
187 }
188 
189 // Check that we instantiate declarations whose addresses are taken
190 // for non-type template arguments.
191 namespace EntityReferenced {
192   template<typename T, void (*)(T)> struct X { };
193 
194   template<typename T>
195   struct Y {
196     static void f(T x) {
197       x = 1; // expected-error{{incompatible integer to pointer conversion assigning to 'int *' from 'int'}}
198     }
199   };
200 
201   void g() {
202     typedef X<int*, Y<int*>::f> x; // expected-note{{in instantiation of}}
203   }
204 }
205 
206 namespace PR6964 {
207   template <typename ,int, int = 9223372036854775807L > // expected-warning {{non-type template argument value '9223372036854775807' truncated to '-1' for template parameter of type 'int'}} \
208   // expected-note {{template parameter is declared here}}
209   struct as_nview { };
210 
211   template <typename Sequence, int I0>
212   struct as_nview<Sequence, I0>  // expected-note{{while checking a default template argument used here}}
213   { };
214 }
215 
216 namespace test8 {
217   template <int* ip> struct A {
218     int* p;
219     A() : p(ip) {}
220   };
221 
222   void test0() {
223     extern int i00;
224     A<&i00> a00;
225   }
226 
227   extern int i01;
228   void test1() {
229     A<&i01> a01;
230   }
231 
232 
233   struct C {
234     int x;
235     char y;
236     double z;
237   };
238 
239   template <C* cp> struct B {
240     C* p;
241     B() : p(cp) {}
242   };
243 
244   void test2() {
245     extern C c02;
246     B<&c02> b02;
247   }
248 
249   extern C c03;
250   void test3() {
251     B<&c03> b03;
252   }
253 }
254 
255 namespace PR8372 {
256   template <int I> void foo() { } // expected-note{{template parameter is declared here}}
257   void bar() { foo <0x80000000> (); } // expected-warning{{non-type template argument value '2147483648' truncated to '-2147483648' for template parameter of type 'int'}}
258 }
259 
260 namespace PR9227 {
261   template <bool B> struct enable_if_bool { };
262   template <> struct enable_if_bool<true> { typedef int type; }; // expected-note{{'enable_if_bool<true>::type' declared here}}
263   void test_bool() { enable_if_bool<false>::type i; } // expected-error{{enable_if_bool<false>'; did you mean 'enable_if_bool<true>::type'?}}
264 
265   template <char C> struct enable_if_char { };
266   template <> struct enable_if_char<'a'> { typedef int type; }; // expected-note 5{{'enable_if_char<'a'>::type' declared here}}
267   void test_char_0() { enable_if_char<0>::type i; } // expected-error{{enable_if_char<'\x00'>'; did you mean 'enable_if_char<'a'>::type'?}}
268   void test_char_b() { enable_if_char<'b'>::type i; } // expected-error{{enable_if_char<'b'>'; did you mean 'enable_if_char<'a'>::type'?}}
269   void test_char_possibly_negative() { enable_if_char<'\x02'>::type i; } // expected-error{{enable_if_char<'\x02'>'; did you mean 'enable_if_char<'a'>::type'?}}
270   void test_char_single_quote() { enable_if_char<'\''>::type i; } // expected-error{{enable_if_char<'\''>'; did you mean 'enable_if_char<'a'>::type'?}}
271   void test_char_backslash() { enable_if_char<'\\'>::type i; } // expected-error{{enable_if_char<'\\'>'; did you mean 'enable_if_char<'a'>::type'?}}
272 
273   template <int N> struct enable_if_int {};
274   template <> struct enable_if_int<1> { typedef int type; }; // expected-note{{'enable_if_int<1>::type' declared here}}
275   void test_int() { enable_if_int<2>::type i; } // expected-error{{enable_if_int<2>'; did you mean 'enable_if_int<1>::type'?}}
276 
277   template <unsigned int N> struct enable_if_unsigned_int {};
278   template <> struct enable_if_unsigned_int<1> { typedef int type; }; // expected-note{{'enable_if_unsigned_int<1>::type' declared here}}
279   void test_unsigned_int() { enable_if_unsigned_int<2>::type i; } // expected-error{{enable_if_unsigned_int<2>'; did you mean 'enable_if_unsigned_int<1>::type'?}}
280 
281   template <unsigned long long N> struct enable_if_unsigned_long_long {};
282   template <> struct enable_if_unsigned_long_long<1> { typedef int type; }; // expected-note{{'enable_if_unsigned_long_long<1>::type' declared here}}
283   void test_unsigned_long_long() { enable_if_unsigned_long_long<2>::type i; } // expected-error{{enable_if_unsigned_long_long<2>'; did you mean 'enable_if_unsigned_long_long<1>::type'?}}
284 
285   template <long long N> struct enable_if_long_long {};
286   template <> struct enable_if_long_long<1> { typedef int type; }; // expected-note{{'enable_if_long_long<1>::type' declared here}}
287   void test_long_long() { enable_if_long_long<2>::type i; } // expected-error{{enable_if_long_long<2>'; did you mean 'enable_if_long_long<1>::type'?}}
288 
289 }
290 
291 namespace PR10579 {
292   namespace fcppt
293   {
294     namespace container
295     {
296       namespace bitfield
297       {
298 
299         template<
300           typename Enum,
301           Enum Size
302           >
303         class basic;
304 
305         template<
306           typename Enum,
307           Enum Size
308           >
309         class basic
310         {
311         public:
312           basic()
313           {
314           }
315         };
316 
317       }
318     }
319   }
320 
321   namespace
322   {
323 
324     namespace testenum
325     {
326       enum type
327         {
328           foo,
329           bar,
330           size
331         };
332     }
333 
334   }
335 
336   int main()
337   {
338     typedef fcppt::container::bitfield::basic<
339     testenum::type,
340       testenum::size
341       > bitfield_foo;
342 
343     bitfield_foo obj;
344   }
345 
346 }
347 
348 template <int& I> struct PR10766 { static int *ip; };
349 template <int& I> int* PR10766<I>::ip = &I;
350 
351 namespace rdar13000548 {
352   template<typename R, typename U, R F>
353   U f() { return &F; } // expected-error{{cannot take the address of an rvalue of type 'int (*)(int)'}} expected-error{{cannot take the address of an rvalue of type 'int *'}}
354 
355   int g(int);
356   int y[3];
357   void test()
358   {
359     f<int(int), int (*)(int), g>(); // expected-note{{in instantiation of}}
360     f<int[3], int*, y>(); // expected-note{{in instantiation of}}
361   }
362 
363 }
364 
365 namespace rdar13806270 {
366   template <unsigned N> class X { };
367   const unsigned value = 32;
368   struct Y {
369     X<value + 1> x;
370   };
371   void foo() {}
372 }
373 
374 namespace PR17696 {
375   struct a {
376     union {
377       int i;
378     };
379   };
380 
381   template <int (a::*p)> struct b : a {
382     b() { this->*p = 0; }
383   };
384 
385   b<&a::i> c; // okay
386 }
387 
388 namespace partial_order_different_types {
389   template<int, int, typename T, typename, T> struct A;
390   // expected-note@-1 {{template is declared here}}
391   template<int N, typename T, typename U, T V> struct A<0, N, T, U, V> {};
392   template<int N, typename T, typename U, U V> struct A<0, N, T, U, V>;
393   // expected-error@-1 {{class template partial specialization is not more specialized than the primary template}}
394   A<0, 0, int, int, 0> a;
395 }
396 
397 namespace partial_order_references {
398   // FIXME: The standard does not appear to consider the second specialization
399   // to be more specialized than the first! The problem is that deducing
400   // an 'int&' parameter from an argument 'R' results in a type mismatch,
401   // because the parameter has a reference type and the argument is an
402   // expression and thus does not have reference type. We resolve this by
403   // matching the type of an expression corresponding to the parameter rather
404   // than matching the parameter itself.
405   template <int, int, int &> struct A {};
406   template <int N, int &R> struct A<N, 0, R> {};
407   template <int &R> struct A<0, 0, R> {};
408   int N;
409   A<0, 0, N> a;
410 
411   template<int, int &R> struct B; // expected-note 2{{template}}
412   template<const int &R> struct B<0, R> {};
413   // expected-error@-1 {{not more specialized than the primary}}
414   // expected-note@-2 {{'const int' vs 'int &'}}
415   B<0, N> b; // expected-error {{undefined}}
416 
417   template<int, const int &R> struct C; // expected-note 2{{template}}
418   template<int &R> struct C<0, R> {};
419   // expected-error@-1 {{not more specialized than the primary}}
420   // expected-note@-2 {{'int' vs 'const int &'}}
421   C<0, N> c; // expected-error {{undefined}}
422 
423   template<int, const int &R> struct D; // expected-note 2{{template}}
424   template<int N> struct D<0, N> {};
425   // expected-error@-1 {{not more specialized than the primary}}
426   // expected-note@-2 {{'int' vs 'const int &'}}
427   extern const int K = 5;
428   D<0, K> d; // expected-error {{undefined}}
429 }
430 
431 namespace dependent_nested_partial_specialization {
432   template<typename> using X = int; // expected-warning {{C++11}}
433   template<typename T> using Y = T*; // expected-warning {{C++11}}
434   int n;
435 
436   template<template<typename> class X> struct A {
437     template<typename T, X<T> N> struct B; // expected-note 2{{here}}
438     template <typename T> struct B<T, 0> {}; // expected-error {{non-type template argument specializes a template parameter with dependent type 'Y<T>' (aka 'T *')}}
439   };
440   A<X>::B<int, 0> ax;
441   A<Y>::B<int, &n> ay; // expected-error {{undefined}} expected-note {{instantiation of}}
442 
443   template<template<typename> class X> struct C {
444     template<typename T, int N, int M> struct D; // expected-note {{here}}
445     template<typename T, X<T> N> struct D<T*, N, N + 1> {}; // expected-error {{type of specialized non-type template argument depends on}}
446   };
447   C<X>::D<int*, 0, 1> cx;
448   C<Y>::D<int*, 0, 1> cy; // expected-error {{undefined}} expected-note {{instantiation of}}
449 
450   template<typename T> struct E {
451     template<typename U, U V> struct F; // expected-note {{template}}
452     template<typename W, T V> struct F<W, V> {}; // expected-error {{not more specialized than the primary}}
453   };
454   E<int>::F<int, 0> e1; // expected-note {{instantiation of}}
455 }
456 
457 namespace nondependent_default_arg_ordering {
458   int n, m;
459   template<typename A, A B = &n> struct X {};
460 
461   template<typename A> void f(X<A>);
462   // expected-note@-1 {{candidate function}}
463   template<typename A> void f(X<A, &m>);
464   // expected-note@-1 {{candidate function}}
465   template<typename A, A B> void f(X<A, B>);
466   // expected-note@-1 2{{candidate function}}
467   template<template<typename U, U> class T, typename A, int *B> void f(T<A, B>);
468   // expected-note@-1 2{{candidate function}}
469 
470   // FIXME: When partial ordering, we get an inconsistent deduction between
471   // `A` (type-parameter-0-0) and `int *`, when deducing the first parameter.
472   // The deduction mechanism needs to be extended to be able to correctly
473   // handle these cases where the argument's template parameters appear in
474   // the result.
475   void g() {
476     X<int *, &n> x; f(x); // expected-error {{call to 'f' is ambiguous}}
477     X<int *, &m> y; f(y); // expected-error {{call to 'f' is ambiguous}}
478   }
479 }
480 
481 namespace pointer_to_char_array {
482   typedef char T[4];
483   template<T *P> struct A { void f(); };
484   template<T *P> void A<P>::f() {}
485   T foo = "foo";
486   void g() { A<&foo>().f(); }
487 }
488 
489 namespace dependent_backreference {
490   struct Incomplete; // expected-note 2{{forward declaration}}
491   Incomplete f(int); // expected-note 2{{here}}
492   int f(short);
493 
494   template<typename T, T Value, int(*)[sizeof(f(Value))]> struct X {}; // expected-error 2{{incomplete}}
495   int arr[sizeof(int)];
496   // When checking this template-id, we must not treat 'Value' as having type
497   // 'int'; its type is the dependent type 'T'.
498   template<typename T> void f() { X<T, 0, &arr> x; } // expected-note {{substituting}}
499   void g() { f<short>(); }
500   void h() { f<int>(); } // expected-note {{instantiation}}
501 
502   // The second of these is OK to diagnose eagerly because 'Value' has the
503   // non-dependent type 'int'.
504   template<short S> void a() { X<short, S, &arr> x; }
505   template<short S> void b() { X<int, S, &arr> x; } // expected-note {{substituting}}
506 }
507 
508 namespace instantiation_dependent {
509   template<typename T, __typeof(sizeof(T))> void f(int);
510   template<typename T, __typeof(sizeof(0))> int &f(...);
511   int &rf = f<struct incomplete, 0>(0);
512 
513   int arr[sizeof(sizeof(int))];
514   template<typename T, int (*)[sizeof(sizeof(T))]> void g(int);
515   template<typename T, int (*)[sizeof(sizeof(int))]> int &g(...);
516   int &rg = g<struct incomplete, &arr>(0);
517 }
518 
519 namespace complete_array_from_incomplete {
520   template <typename T, const char* const A[static_cast<int>(T::kNum)]>
521   class Base {};
522   template <class T, const char* const A[]>
523   class Derived : public Base<T, A> {};
524 
525   struct T {
526     static const int kNum = 3;
527   };
528   extern const char *const kStrs[3] = {};
529   Derived<T, kStrs> d;
530 }
531 
532 namespace type_of_pack {
533   template<typename ...T> struct A { // expected-warning 0-1{{extension}}
534     template<T *...V> void f() {
535       g(V.f() ...); // expected-error {{base type 'T *' is not a structure or union}}
536     }
537   };
538 }
539 
540 namespace match_type_after_substitution {
541   template<typename T> struct X {};
542   X<int> y;
543   template<typename T, X<T> &Y> struct B {
544     typedef B<T, Y> Self;
545   };
546 
547   // These two formulations should resolve to the same type.
548   typedef B<int, y> Z;
549   typedef Z::Self Z;
550 }
551