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