xref: /llvm-project/clang/test/SemaCXX/static-assert-cxx26.cpp (revision b6628c24ef017138b8d6eb288e94c141e7c846b0)
1 // RUN: %clang_cc1 -std=c++2c -triple=x86_64-linux -fsyntax-only %s -verify
2 
3 static_assert(true, "");
4 static_assert(true, 0); // expected-error {{the message in a static assertion must be a string literal or an object with 'data()' and 'size()' member functions}}
5 struct Empty{};
6 static_assert(true, Empty{}); // expected-error {{the message object in this static assertion is missing 'data()' and 'size()' member functions}}
7 struct NoData {
8     unsigned long size() const;
9 };
10 struct NoSize {
11     const char* data() const;
12 };
13 static_assert(true, NoData{}); // expected-error {{the message object in this static assertion is missing a 'data()' member function}}
14 static_assert(true, NoSize{}); // expected-error {{the message object in this static assertion is missing a 'size()' member function}}
15 
16 struct InvalidSize {
17     const char* size() const;
18     const char* data() const;
19 };
20 static_assert(true, InvalidSize{}); // expected-error {{the message in a static assertion must have a 'size()' member function returning an object convertible to 'std::size_t'}} \
21                                     // expected-error {{value of type 'const char *' is not implicitly convertible to 'unsigned long'}}
22 struct InvalidData {
23     unsigned long size() const;
24     unsigned long data() const;
25 };
26 static_assert(true, InvalidData{}); // expected-error {{the message in a static assertion must have a 'data()' member function returning an object convertible to 'const char *'}} \
27                                     // expected-error {{value of type 'unsigned long' is not implicitly convertible to 'const char *'}}
28 
29 struct NonConstexprSize {
30     unsigned long size() const; // expected-note 2{{declared here}}
31     constexpr const char* data() const;
32 };
33 
34 static_assert(true, NonConstexprSize{}); // expected-error {{the message in this static assertion is not a constant expression}} \
35                                          // expected-note  {{non-constexpr function 'size' cannot be used in a constant expression}}
36 
37 static_assert(false, NonConstexprSize{}); // expected-error {{the message in a static assertion must be produced by a constant expression}} \
38                                           // expected-error {{static assertion failed}} \
39                                           // expected-note  {{non-constexpr function 'size' cannot be used in a constant expression}}
40 
41 struct NonConstexprData {
sizeNonConstexprData42     constexpr unsigned long size() const {
43         return 32;
44     }
45     const char* data() const;  // expected-note 2{{declared here}}
46 };
47 
48 static_assert(true, NonConstexprData{});  // expected-error {{the message in this static assertion is not a constant expression}} \
49                                           // expected-note  {{non-constexpr function 'data' cannot be used in a constant expression}}
50 
51 static_assert(false, NonConstexprData{}); // expected-error {{the message in a static assertion must be produced by a constant expression}} \
52                                           // expected-error {{static assertion failed}} \
53                                           // expected-note  {{non-constexpr function 'data' cannot be used in a constant expression}}
54 
55 struct string_view {
56     int S;
57     const char* D;
string_viewstring_view58     constexpr string_view(const char* Str) : S(__builtin_strlen(Str)), D(Str) {}
string_viewstring_view59     constexpr string_view(int Size, const char* Str) : S(Size), D(Str) {}
sizestring_view60     constexpr int size() const {
61         return S;
62     }
datastring_view63     constexpr const char* data() const {
64         return D;
65     }
66 };
67 
operator +(auto,string_view S)68 constexpr string_view operator+(auto, string_view S) {
69     return S;
70 }
71 
72 constexpr const char g_[] = "long string";
73 
74 template <typename T, int S>
75 struct array {
sizearray76     constexpr unsigned long size() const {
77         return S;
78     }
dataarray79     constexpr const char* data() const {
80         return d_;
81     }
82     const char d_[S];
83 };
84 
85 static_assert(false, string_view("test")); // expected-error {{static assertion failed: test}}
86 static_assert(false, "Literal" + string_view("test")); // expected-error {{static assertion failed: test}}
87 static_assert(false, L"Wide Literal" + string_view("test")); // expected-error {{static assertion failed: test}}
88 static_assert(false, "Wild" "Literal" "Concatenation" + string_view("test")); // expected-error {{static assertion failed: test}}
89 static_assert(false, "Wild" "Literal" L"Concatenation" + string_view("test")); // expected-error {{static assertion failed: test}}
90 static_assert(false, "Wild" u"Literal" L"Concatenation" + string_view("test")); // expected-error {{unsupported non-standard concatenation of string literals}}
91 static_assert(false, string_view("��")); // expected-error {{static assertion failed: ��}}
92 static_assert(false, string_view(0, nullptr)); // expected-error {{static assertion failed:}}
93 static_assert(false, string_view(1, "ABC")); // expected-error {{static assertion failed: A}}
94 static_assert(false, string_view(42, "ABC")); // expected-error {{static assertion failed: ABC}} \
95                                               // expected-error {{the message in a static assertion must be produced by a constant expression}} \
96                                               // expected-note {{read of dereferenced one-past-the-end pointer is not allowed in a constant expression}}
97 static_assert(false, array<char, 2>{'a', 'b'}); // expected-error {{static assertion failed: ab}}
98 
99 
100 
101 struct ConvertibleToInt {
operator intConvertibleToInt102     constexpr operator int() {
103         return 4;
104     }
105 };
106 struct ConvertibleToCharPtr {
operator const char*ConvertibleToCharPtr107     constexpr operator const char*() {
108         return "test";
109     }
110 };
111 struct MessageFromConvertible {
sizeMessageFromConvertible112     constexpr ConvertibleToInt size() const {
113         return {};
114     }
dataMessageFromConvertible115     constexpr ConvertibleToCharPtr data() const {
116         return {};
117     }
118 };
119 
120 static_assert(true, MessageFromConvertible{});
121 static_assert(false, MessageFromConvertible{}); // expected-error{{static assertion failed: test}}
122 
123 
124 
125 struct Leaks {
sizeLeaks126     constexpr unsigned long size() const {
127         return 2;
128     }
dataLeaks129     constexpr const char* data() const {
130         return new char[2]{'u', 'b'}; // expected-note {{allocation performed here was not deallocated}}
131     }
132 };
133 
134 static_assert(false, Leaks{}); //expected-error {{the message in a static assertion must be produced by a constant expression}} \
135                               // expected-error {{static assertion failed: ub}}
136 
137 struct RAII {
__anon553797ed0202RAII138     const char* d = new char[2]{'o', 'k'};
sizeRAII139     constexpr unsigned long size() const {
140         return 2;
141     }
142 
dataRAII143     constexpr const char* data() const {
144         return d;
145     }
146 
~RAIIRAII147     constexpr ~RAII() {
148         delete[] d;
149     }
150 };
151 static_assert(false, RAII{}); // expected-error {{static assertion failed: ok}}
152 
153 namespace MoreTemporary {
154 
155 struct Data{
operator const char*MoreTemporary::Data156 constexpr operator const char*() const {
157     return d;
158 }
159 char d[6] = { "Hello" };
160 };
161 
162 struct Size {
operator intMoreTemporary::Size163      constexpr operator int() const {
164         return 5;
165     }
166 };
167 
168 struct Message {
sizeMoreTemporary::Message169     constexpr auto size() const {
170         return Size{};
171     }
dataMoreTemporary::Message172     constexpr auto data() const {
173         return Data{};
174     }
175 };
176 
177 static_assert(false, Message{}); // expected-error {{static assertion failed: Hello}}
178 
179 }
180 
181 struct MessageInvalidSize {
182     constexpr unsigned long size(int) const; // expected-note {{'size' declared here}}
183     constexpr const char* data() const;
184 };
185 struct MessageInvalidData {
186     constexpr unsigned long size() const;
187     constexpr const char* data(int) const; // expected-note {{'data' declared here}}
188 };
189 
190 static_assert(false, MessageInvalidSize{});  // expected-error {{static assertion failed}} \
191                                              // expected-error {{the message in a static assertion must have a 'size()' member function returning an object convertible to 'std::size_t'}} \
192                                              // expected-error {{too few arguments to function call, expected 1, have 0}}
193 static_assert(false, MessageInvalidData{});  // expected-error {{static assertion failed}} \
194                                              // expected-error {{the message in a static assertion must have a 'data()' member function returning an object convertible to 'const char *'}} \
195                                              // expected-error {{too few arguments to function call, expected 1, have 0}}
196 
197 struct NonConstMembers {
sizeNonConstMembers198     constexpr int size() {
199         return 1;
200     }
dataNonConstMembers201     constexpr const char* data() {
202         return "A";
203     }
204 };
205 
206 static_assert(false, NonConstMembers{}); // expected-error {{static assertion failed: A}}
207 
208 struct DefaultArgs {
sizeDefaultArgs209     constexpr int size(int i = 0) {
210         return 2;
211     }
dataDefaultArgs212     constexpr const char* data(int i =0, int j = 42) {
213         return "OK";
214     }
215 };
216 
217 static_assert(false, DefaultArgs{}); // expected-error {{static assertion failed: OK}}
218 
219 struct Variadic {
sizeVariadic220     constexpr int size(auto...) {
221         return 2;
222     }
dataVariadic223     constexpr const char* data(auto...) {
224         return "OK";
225     }
226 };
227 
228 static_assert(false, Variadic{}); // expected-error {{static assertion failed: OK}}
229 
230 template <typename T>
231 struct DeleteAndRequires {
232     constexpr int size() = delete; // expected-note {{'size' has been explicitly marked deleted here}}
233     constexpr const char* data() requires false; // expected-note {{because 'false' evaluated to false}}
234 };
235 static_assert(false, DeleteAndRequires<void>{});
236 // expected-error@-1 {{static assertion failed}} \
237 // expected-error@-1 {{the message in a static assertion must have a 'size()' member function returning an object convertible to 'std::size_t'}}\
238 // expected-error@-1 {{invalid reference to function 'data': constraints not satisfied}} \
239 // expected-error@-1 {{attempt to use a deleted function}}
240 
241 class Private {
size(int i=0)242     constexpr int size(int i = 0) { // expected-note {{implicitly declared private here}}
243         return 2;
244     }
data(int i=0,int j=42)245     constexpr const char* data(int i =0, int j = 42) { // expected-note {{implicitly declared private here}}
246         return "OK";
247     }
248 };
249 
250 static_assert(false, Private{}); // expected-error {{'data' is a private member of 'Private'}}\
251                                  // expected-error {{'size' is a private member of 'Private'}}\
252                                  // expected-error {{static assertion failed: OK}}
253 
254 struct MessageOverload {
sizeMessageOverload255     constexpr int size() {
256         return 1;
257     }
258     constexpr int size() const;
259 
dataMessageOverload260     constexpr const char* data() {
261         return "A";
262     }
263     constexpr const char* data() const;
264 };
265 
266 static_assert(false, MessageOverload{}); // expected-error {{static assertion failed: A}}
267 
268 struct InvalidPtr {
sizeInvalidPtr269     consteval auto size() {
270         return 42;
271     }
dataInvalidPtr272     consteval const char *data() {
273     const char *ptr; // Garbage
274     return ptr; // expected-note {{read of uninitialized object is not allowed in a constant expression}}
275     }
276 };
277 
278 static_assert(false, InvalidPtr{}); // expected-error{{the message in a static assertion must be produced by a constant expression}} \
279                            //expected-error {{static assertion failed}} \
280                            // expected-note {{in call to 'InvalidPtr{}.data()'}}
281 
282 namespace DependentMessage {
283 template <typename Ty>
284 struct Good {
285   static_assert(false, Ty{}); // expected-error {{static assertion failed: hello}}
286 };
287 
288 template <typename Ty>
289 struct Bad {
290   static_assert(false, Ty{}); // expected-error {{the message in a static assertion must be a string literal or an object with 'data()' and 'size()' member functions}} \
291                               // expected-error {{static assertion failed}}
292 };
293 
294 struct Frobble {
sizeDependentMessage::Frobble295   constexpr int size() const { return 5; }
dataDependentMessage::Frobble296   constexpr const char *data() const { return "hello"; }
297 };
298 
operator ""_myd(const char *,unsigned long)299 constexpr Frobble operator ""_myd (const char *, unsigned long) { return Frobble{}; }
300 static_assert (false, "foo"_myd); // expected-error {{static assertion failed: hello}}
301 
302 Good<Frobble> a; // expected-note {{in instantiation}}
303 Bad<int> b; // expected-note {{in instantiation}}
304 
305 }
306 
307 namespace EscapeInDiagnostic {
308 static_assert('\u{9}' == (char)1, ""); // expected-error {{failed}} \
309                                        // expected-note {{evaluates to ''\t' (0x09, 9) == '<U+0001>' (0x01, 1)'}}
310 static_assert((char8_t)-128 == (char8_t)-123, ""); // expected-error {{failed}} \
311                                                    // expected-note {{evaluates to 'u8'<80>' (0x80, 128) == u8'<85>' (0x85, 133)'}}
312 static_assert((char16_t)0xFEFF == (char16_t)0xDB93, ""); // expected-error {{failed}} \
313                                                          // expected-note {{evaluates to 'u'' (0xFEFF, 65279) == u'\xDB93' (0xDB93, 56211)'}}
314 }
315 
316 struct Static {
sizeStatic317   static constexpr int size() { return 5; }
dataStatic318   static constexpr const char *data() { return "hello"; }
319 };
320 static_assert(false, Static{}); // expected-error {{static assertion failed: hello}}
321 
322 struct Data {
323     unsigned long size = 0;
324     const char* data = "hello";
325 };
326 static_assert(false, Data{}); // expected-error {{called object type 'unsigned long' is not a function or function pointer}} \
327                               // expected-error {{called object type 'const char *' is not a function or function pointer}} \
328                               // expected-error {{the message in a static assertion must have a 'size()' member function returning an object convertible to 'std::size_t'}} \
329                               // expected-error {{static assertion failed}}
330 
331 struct Callable {
332     struct {
operator ()Callable::__anon553797ed0308333         constexpr auto operator()() const {
334             return 5;
335         };
336     } size;
337     struct {
operator ()Callable::__anon553797ed0408338         constexpr auto operator()() const {
339             return "hello";
340         };
341     } data;
342 };
343 static_assert(false, Callable{}); // expected-error {{static assertion failed: hello}}
344 
345 namespace GH89407 {
346 struct A {
sizeGH89407::A347   constexpr __SIZE_TYPE__ size() const { return -1; }
dataGH89407::A348   constexpr const char* data() const { return ""; }
349 };
350 
351 struct B {
sizeGH89407::B352   constexpr long long size() const { return 18446744073709551615U; }
dataGH89407::B353   constexpr const char* data() const { return ""; }
354 };
355 
356 struct C {
sizeGH89407::C357   constexpr __int128 size() const { return -1; }
dataGH89407::C358   constexpr const char* data() const { return ""; }
359 };
360 
361 struct D {
sizeGH89407::D362   constexpr unsigned __int128 size() const { return -1; }
dataGH89407::D363   constexpr const char* data() const { return ""; }
364 };
365 
366 struct E {
sizeGH89407::E367   constexpr __SIZE_TYPE__ size() const { return 18446744073709551615U; }
dataGH89407::E368   constexpr const char* data() const { return ""; }
369 };
370 
371 static_assert(true, A{}); // expected-error {{the message in this static assertion is not a constant expression}}
372                           // expected-note@-1 {{read of dereferenced one-past-the-end pointer is not allowed in a constant expression}}
373 static_assert(true, B{}); // expected-error {{call to 'size()' evaluates to -1, which cannot be narrowed to type 'unsigned long'}}
374                           // expected-error@-1 {{the message in this static assertion is not a constant expression}}
375                           // expected-note@-2 {{read of dereferenced one-past-the-end pointer is not allowed in a constant expression}}
376 static_assert(true, C{}); // expected-error {{call to 'size()' evaluates to -1, which cannot be narrowed to type 'unsigned long'}}
377                           // expected-error@-1 {{the message in this static assertion is not a constant expression}}
378                           // expected-note@-2 {{read of dereferenced one-past-the-end pointer is not allowed in a constant expression}}
379 static_assert(true, D{}); // expected-error {{call to 'size()' evaluates to 340282366920938463463374607431768211455, which cannot be narrowed to type 'unsigned long'}}
380                           // expected-error@-1 {{the message in this static assertion is not a constant expression}}
381                           // expected-note@-2 {{read of dereferenced one-past-the-end pointer is not allowed in a constant expression}}
382 static_assert(true, E{}); // expected-error {{the message in this static assertion is not a constant expression}}
383                           // expected-note@-1 {{read of dereferenced one-past-the-end pointer is not allowed in a constant expression}}
384 
385 static_assert(
386   false, // expected-error {{static assertion failed}}
387   A{} // expected-error {{the message in a static assertion must be produced by a constant expression}}
388       // expected-note@-1 {{read of dereferenced one-past-the-end pointer is not allowed in a constant expression}}
389 );
390 
391 static_assert(
392   false, // expected-error {{static assertion failed}}
393   B{} // expected-error {{call to 'size()' evaluates to -1, which cannot be narrowed to type 'unsigned long'}}
394       // expected-error@-1 {{the message in a static assertion must be produced by a constant expression}}
395       // expected-note@-2 {{read of dereferenced one-past-the-end pointer is not allowed in a constant expression}}
396 );
397 
398 static_assert(
399   false, // expected-error {{static assertion failed}}
400   C{} // expected-error {{call to 'size()' evaluates to -1, which cannot be narrowed to type 'unsigned long'}}
401       // expected-error@-1 {{the message in a static assertion must be produced by a constant expression}}
402       // expected-note@-2 {{read of dereferenced one-past-the-end pointer is not allowed in a constant expression}}
403 );
404 
405 static_assert(
406   false, // expected-error {{static assertion failed}}
407   D{} // expected-error {{call to 'size()' evaluates to 340282366920938463463374607431768211455, which cannot be narrowed to type 'unsigned long'}}
408       // expected-error@-1 {{the message in a static assertion must be produced by a constant expression}}
409       // expected-note@-2 {{read of dereferenced one-past-the-end pointer is not allowed in a constant expression}}
410 );
411 
412 static_assert(
413   false, // expected-error {{static assertion failed}}
414   E{} // expected-error {{the message in a static assertion must be produced by a constant expression}}
415       // expected-note@-1 {{read of dereferenced one-past-the-end pointer is not allowed in a constant expression}}
416 );
417 }
418