1 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++20 %s
2 
3 using size_t = __SIZE_TYPE__;
4 
5 namespace std {
6   struct type_info;
7 }
8 
9 // floating-point arguments
10 template<float> struct Float {};
11 using F1 = Float<1.0f>; // FIXME expected-error {{sorry}}
12 using F1 = Float<2.0f / 2>; // FIXME expected-error {{sorry}}
13 
14 struct S { int n[3]; } s; // expected-note 1+{{here}}
15 union U { int a, b; } u;
16 int n; // expected-note 1+{{here}}
17 
18 // pointers to subobjects
19 template<int *> struct IntPtr {};
20 using IPn = IntPtr<&n + 1>; // FIXME expected-error {{refers to subobject}}
21 using IPn = IntPtr<&n + 1>; // FIXME expected-error {{refers to subobject}}
22 
23 using IP2 = IntPtr<&s.n[2]>; // FIXME expected-error {{refers to subobject}}
24 using IP2 = IntPtr<s.n + 2>; // FIXME expected-error {{refers to subobject}}
25 
26 using IP3 = IntPtr<&s.n[3]>; // FIXME expected-error {{refers to subobject}}
27 using IP3 = IntPtr<s.n + 3>; // FIXME expected-error {{refers to subobject}}
28 
29 template<int &> struct IntRef {};
30 using IPn = IntRef<*(&n + 1)>; // expected-error {{not a constant expression}} expected-note {{dereferenced pointer past the end of 'n'}}
31 using IPn = IntRef<*(&n + 1)>; // expected-error {{not a constant expression}} expected-note {{dereferenced pointer past the end of 'n'}}
32 
33 using IP2 = IntRef<s.n[2]>; // FIXME expected-error {{refers to subobject}}
34 using IP2 = IntRef<*(s.n + 2)>; // FIXME expected-error {{refers to subobject}}
35 
36 using IP3 = IntRef<s.n[3]>; // expected-error {{not a constant expression}} expected-note {{dereferenced pointer past the end of subobject of 's'}}
37 using IP3 = IntRef<*(s.n + 3)>; // expected-error {{not a constant expression}} expected-note {{dereferenced pointer past the end of subobject of 's'}}
38 
39 // classes
40 template<S> struct Struct {};
41 using S123 = Struct<S{1, 2, 3}>;
42 using S123 = Struct<S{1, 2, 3}>; // expected-note {{previous}}
43 using S123 = Struct<S{1, 2, 4}>; // expected-error {{different types}}
44 template<U> struct Union {};
45 using U1 = Union<U{1}>;
46 using U1 = Union<U{.a = 1}>; // expected-note {{previous}}
47 using U1 = Union<U{.b = 1}>; // expected-error {{different types}}
48 
49 // miscellaneous scalar types
50 template<_Complex int> struct ComplexInt {};
51 using CI = ComplexInt<1 + 3i>; // FIXME: expected-error {{sorry}}
52 using CI = ComplexInt<1 + 3i>; // FIXME: expected-error {{sorry}}
53 
54 template<_Complex float> struct ComplexFloat {};
55 using CF = ComplexFloat<1.0f + 3.0fi>; // FIXME: expected-error {{sorry}}
56 using CF = ComplexFloat<1.0f + 3.0fi>; // FIXME: expected-error {{sorry}}
57 
58 namespace ClassNTTP {
59   struct A { // expected-note 2{{candidate}}
60     int x, y;
61   };
f()62   template<A a> constexpr int f() { return a.y; }
63   static_assert(f<A{1,2}>() == 2);
64 
65   template<A a> int id;
66   constexpr A a = {1, 2};
67   static_assert(&id<A{1,2}> == &id<a>);
68   static_assert(&id<A{1,3}> != &id<a>);
69 
70   int k = id<1>; // expected-error {{no viable conversion from 'int' to 'ClassNTTP::A'}}
71 
72   struct B {
BClassNTTP::B73     constexpr B() {}
74     constexpr B(int) = delete; // expected-note {{here}}
75   };
76   template<B> struct Q {}; // expected-note {{passing argument to parameter here}}
77   Q<1> q; // expected-error {{conversion function from 'int' to 'ClassNTTP::B' invokes a deleted function}}
78 
79   struct C {
CClassNTTP::C80     constexpr C() {}
81     C(const C&) = delete; // expected-note {{here}}
82   };
83   template<C> struct R {}; // expected-note {{passing argument to parameter here}}
84   constexpr C c;
85   R<c> r; // expected-error {{call to deleted constructor}}
86 }
87 
88 namespace ConvertedConstant {
89   struct A {
AConvertedConstant::A90     constexpr A(float) {}
91   };
92   template <A> struct X {};
f(X<1.0f>)93   void f(X<1.0f>) {} // OK, user-defined conversion
f(X<2>)94   void f(X<2>) {} // expected-error {{conversion from 'int' to 'ConvertedConstant::A' is not allowed in a converted constant expression}}
95 }
96 
97 namespace CopyCounting {
98   // Make sure we don't use the copy constructor when transferring the "same"
99   // template parameter object around.
ACopyCounting::A100   struct A { int n; constexpr A(int n = 0) : n(n) {} constexpr A(const A &a) : n(a.n+1) {} };
101   template<A a> struct X {};
f(X<a> x)102   template<A a> constexpr int f(X<a> x) { return a.n; }
103 
104   static_assert(f(X<A{}>()) == 0);
105 
106   template<A a> struct Y { void f(); };
g(Y<a> y)107   template<A a> void g(Y<a> y) { y.Y<a>::f(); }
h()108   void h() { constexpr A a; g<a>(Y<a>{}); }
109 
110   template<A a> struct Z {
fCopyCounting::Z111     constexpr int f() {
112       constexpr A v = a; // this is {a.n+1}
113       return Z<v>().f() + 1; // this is Z<{a.n+2}>
114     }
115   };
116   template<> struct Z<A{20}> {
fCopyCounting::Z117     constexpr int f() {
118       return 32;
119     }
120   };
121   static_assert(Z<A{}>().f() == 42);
122 }
123 
124 namespace StableAddress {
125   template<size_t N> struct str {
126     char arr[N];
127   };
128   // FIXME: Deduction guide not needed with P1816R0.
129   template<size_t N> str(const char (&)[N]) -> str<N>;
130 
sum()131   template<str s> constexpr int sum() {
132     int n = 0;
133     for (char c : s.arr)
134       n += c;
135     return n;
136   }
137   static_assert(sum<str{"$hello $world."}>() == 1234);
138 }
139 
140 namespace TemplateSpecializations {
141   struct A { int arr[10]; };
142   template<A> struct X; // expected-note {{here}}
143 
144   using T = X<A{1, 2, 3}>;
145   using T = X<A{1, 2, 3, 0}>;
146   using T = X<A{1, 2, 3, 0, 0}>;
147   using T = X<A{1, 2, 3, 0, 0, 0}>;
148 
149   template<> struct X<A{1, 2, 3, 4}> {};
150   X<A{1, 2, 3, 4, 0}> x;
151 
152   template<auto V, auto W> constexpr bool Same = false;
153   template<auto V> constexpr bool Same<V, V> = true;
154   static_assert(Same<A{}, A{0, 0}>);
155   static_assert(Same<A{1}, A{1, 0}>);
156   static_assert(!Same<A{1}, A{1, 1}>);
157 
158   // We can't directly specialize on member values...
159   template<int N> // expected-note {{parameter 'N'}}
160     struct X<A{N, N}> {}; // expected-error {{cannot be deduced}}
161 
162   // ... but we can fake it up.
163   // template<int N> struct X<A{N, N}>
164   template <A V> requires Same<V, A{V.arr[0], V.arr[0]}>
165   struct X<V> {
166     static constexpr bool match = true;
167   };
168   static_assert(X<A{1, 1}>::match);
169   static_assert(X<A{2, 2}>::match);
170   static_assert(X<A{1, 2}>::match); // expected-error {{undefined}}
171 
172   template<int, A> struct Y; // expected-note {{here}}
173   template<int N> struct Y<N, A{N, N, N}> {};
174   Y<1, A{1, 1, 1, 0}> y1;
175   Y<1, A{1, 1, 1, 1}> y2; // expected-error {{undefined}}
176 
177   template<A, A> struct Z; // expected-note {{here}}
178   template<A V> struct Z<V, V> {};
179   Z<A{1, 2}, A{1, 2, 0}> z1;
180   Z<A{1, 2}, A{1, 3}> z2; // expected-error {{undefined}}
181 
182   template struct Z<A{1}, A{1, 0}>;
183 }
184 
185 namespace Diags {
186   struct A { int n, m; };
187   template<A a> struct X { static_assert(a.n == a.m); }; // expected-error {{static_assert failed due to requirement 'Diags::A{1, 2}.n == Diags::A{1, 2}.m'}}
188   template struct X<A{1, 2}>; // expected-note {{in instantiation of template class 'Diags::X<{1, 2}>' requested here}}
189 }
190 
191 namespace CTADPartialOrder {
192   template<int> struct A {};
193   template<typename T, typename U, A a> struct X; // expected-note {{declared here}}
194   template<typename T, A a> struct X<T, int, a> { static constexpr int n = 1; }; // expected-note {{matches}}
195   template<typename T, A a> struct X<T *, int, a> { static constexpr int n = 2; };
196   template<typename T, A a> struct X<T, T, a> { static constexpr int n = 3; }; // expected-note {{matches}}
197 
198   A<0> a;
199   static_assert(X<void, int, a>::n == 1);
200   static_assert(X<int*, int, a>::n == 2);
201   static_assert(X<void, void, a>::n == 3);
202   static_assert(X<int, int, a>::n == -1); // expected-error {{ambiguous}}
203   static_assert(X<int*, void, a>::n == 2); // expected-error {{undefined}}
204 
205   template<typename T, A<0> a> struct X<T, T, a> { static constexpr int n = 4; };
206   static_assert(X<float, float, a>::n == 4);
207 }
208 
209 namespace UnnamedBitfield {
210   struct A {
211     __INT32_TYPE__ : 32;
212   };
213   // Make sure we don't distinguish between the unnamed bit-field being
214   // uninitialized and it being zeroed. Those are not distinct states
215   // according to [temp.type]p2.
216   //
217   // FIXME: We shouldn't track a value for unnamed bit-fields, nor number
218   // them when computing field indexes.
219   template <A> struct X {};
220   constexpr A a;
221   using T = X<a>;
222   using T = X<A{}>;
223   using T = X<(A())>;
224   // Once we support bit-casts involving bit-fields, this should be valid too.
225   using T = X<__builtin_bit_cast(A, 0)>; // expected-error {{constant}} expected-note {{not yet supported}}
226 }
227 
228 namespace Temporary {
229   template<const int &> struct A {};
230   A<0> a0; // expected-error {{conversion from 'int' to 'const int &' in converted constant expression would bind reference to a temporary}}
231 
232   A<(const int&)1> a1; // expected-error {{reference to temporary object is not allowed in a template argument}}
233   A<(int&&)2> a2; // expected-error {{reference to temporary object is not allowed in a template argument}}
234 
235   // FIXME: There's really no good reason to reject these cases.
236   int &&r3 = 3;
237   const int &r4 = 4;
238   A<r3> a3; // expected-error {{reference to temporary object is not allowed in a template argument}}
239   A<r4> a4; // expected-error {{reference to temporary object is not allowed in a template argument}}
240 
241   struct X { int a[5]; };
242   X &&x = X{};
243   A<x.a[3]> a5; // expected-error {{reference to subobject of temporary object}}
244 
245   template<const int*> struct B {};
246   B<&(int&)(int&&)0> b0; // expected-error {{pointer to temporary object}}
247   B<&r3> b3; // expected-error {{pointer to temporary object}}
248   B<&x.a[3]> b5; // expected-error {{pointer to subobject of temporary object}}
249 
250   struct C { const int *p[2]; };
251   template<C> struct D {};
252   D<C{nullptr, &r3}> d; // expected-error {{pointer to temporary object}}
253 }
254 
255 namespace StringLiteral {
256   template<decltype(auto)> struct Y {};
257   Y<&"hello"> y1; // expected-error {{pointer to string literal}}
258   Y<"hello"> y2; // expected-error {{reference to string literal}}
259   Y<+"hello"> y3; // expected-error {{pointer to subobject of string literal}}
260   Y<"hello"[2]> y4; // expected-error {{reference to subobject of string literal}}
261 
262   struct A { const char *p; };
263   struct B { const char &r; };
264   Y<A{"hello"}> y5; // expected-error {{pointer to subobject of string literal}}
265   Y<B{"hello"[2]}> y6; // expected-error {{reference to subobject of string literal}}
266 }
267 
268 namespace TypeInfo {
269   template<decltype(auto)> struct Y {};
270   Y<&typeid(int)> y1; // expected-error {{pointer to type_info object}}
271   Y<typeid(int)> y2; // expected-error {{reference to type_info object}}
272 
273   struct A { const std::type_info *p; };
274   struct B { const std::type_info &r; };
275   Y<A{&typeid(int)}> y3; // expected-error {{pointer to type_info object}}
276   Y<B{typeid(int)}> y4; // expected-error {{reference to type_info object}}
277 }
278 
279 namespace Predefined {
280   template<decltype(auto)> struct Y {};
281 
282   struct A { const char *p; };
283   struct B { const char &r; };
f()284   void f() {
285     // decltype(__func__) is an array, which decays to a pointer parameter.
286     Y<__func__>(); // expected-error {{pointer to subobject of predefined '__func__' variable}}
287     Y<__PRETTY_FUNCTION__>(); // expected-error {{pointer to subobject}}
288     Y<(__func__)>(); // expected-error {{reference to predefined '__func__' variable}}
289     Y<&__func__>(); // expected-error {{pointer to predefined '__func__' variable}}
290     Y<*&__func__>(); // expected-error {{reference to predefined '__func__' variable}}
291     Y<A{__func__}>(); // expected-error {{pointer to subobject of predefined '__func__' variable}}
292     Y<B{__func__[0]}>(); // expected-error {{reference to subobject of predefined '__func__' variable}}
293   }
294 }
295 
296 namespace DependentCTAD {
297   template<auto> struct A {};
298   template<template<typename> typename T, T V> void f(A<V>); // expected-note {{couldn't infer template argument 'T'}}
BDependentCTAD::B299   template<typename T> struct B { constexpr B(T) {} };
300 
g()301   void g() {
302     // PR50039: Note that we could in principle deduce T here, but the language
303     // deduction rules don't support that.
304     f(A<B(0)>()); // expected-error {{no matching function}}
305     f<B>(A<B(0)>()); // OK
306   }
307 }
308