Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / clang / test / SemaCXX / source_location.cpp
blobe92fb35b653a8f39be625cc0c4859b9b8e7d4af1
1 // RUN: %clang_cc1 -std=c++1z -fcxx-exceptions -fexceptions -verify %s
2 // RUN: %clang_cc1 -std=c++2a -fcxx-exceptions -DUSE_CONSTEVAL -fexceptions -verify %s
3 // RUN: %clang_cc1 -std=c++2b -fcxx-exceptions -DUSE_CONSTEVAL -DPAREN_INIT -fexceptions -verify %s
4 // RUN: %clang_cc1 -std=c++1z -fcxx-exceptions -fms-extensions -DMS -fexceptions -verify %s
5 // RUN: %clang_cc1 -std=c++2a -fcxx-exceptions -fms-extensions -DMS -DUSE_CONSTEVAL -fexceptions -verify %s
6 //
7 // RUN: %clang_cc1 -std=c++1z -fcxx-exceptions -fexceptions -fexperimental-new-constant-interpreter -DNEW_INTERP -verify %s
8 // RUN: %clang_cc1 -std=c++2a -fcxx-exceptions -DUSE_CONSTEVAL -fexceptions -fexperimental-new-constant-interpreter -DNEW_INTERP -verify %s
9 // RUN: %clang_cc1 -std=c++2b -fcxx-exceptions -DUSE_CONSTEVAL -DPAREN_INIT -fexceptions -fexperimental-new-constant-interpreter -DNEW_INTERP -verify %s
10 // RUN: %clang_cc1 -std=c++1z -fcxx-exceptions -fms-extensions -DMS -fexceptions -fexperimental-new-constant-interpreter -DNEW_INTERP -verify %s
11 // RUN: %clang_cc1 -std=c++2a -fcxx-exceptions -fms-extensions -DMS -DUSE_CONSTEVAL -fexceptions -fexperimental-new-constant-interpreter -DNEW_INTERP -verify %s
12 // expected-no-diagnostics
14 #define assert(...) ((__VA_ARGS__) ? ((void)0) : throw 42)
15 #define CURRENT_FROM_MACRO() SL::current()
16 #define FORWARD(...) __VA_ARGS__
18 template <unsigned>
19 struct Printer;
21 #ifdef USE_CONSTEVAL
22 #define SOURCE_LOC_EVAL_KIND consteval
23 #else
24 #define SOURCE_LOC_EVAL_KIND constexpr
25 #endif
27 namespace std {
28 class source_location {
29 struct __impl;
31 public:
32 static SOURCE_LOC_EVAL_KIND source_location
33 current(const __impl *__p = __builtin_source_location()) noexcept {
34 source_location __loc;
35 __loc.__m_impl = __p;
36 return __loc;
38 constexpr source_location() = default;
39 constexpr source_location(source_location const &) = default;
40 constexpr unsigned int line() const noexcept { return __m_impl ? __m_impl->_M_line : 0; }
41 constexpr unsigned int column() const noexcept { return __m_impl ? __m_impl->_M_column : 0; }
42 constexpr const char *file() const noexcept { return __m_impl ? __m_impl->_M_file_name : ""; }
43 constexpr const char *function() const noexcept { return __m_impl ? __m_impl->_M_function_name : ""; }
45 private:
46 // Note: The type name "std::source_location::__impl", and its constituent
47 // field-names are required by __builtin_source_location().
48 struct __impl {
49 const char *_M_file_name;
50 const char *_M_function_name;
51 unsigned _M_line;
52 unsigned _M_column;
54 const __impl *__m_impl = nullptr;
56 public:
57 using public_impl_alias = __impl;
59 } // namespace std
61 using SL = std::source_location;
63 #include "Inputs/source-location-file.h"
64 namespace SLF = source_location_file;
66 constexpr bool is_equal(const char *LHS, const char *RHS) {
67 while (*LHS != 0 && *RHS != 0) {
68 if (*LHS != *RHS)
69 return false;
70 ++LHS;
71 ++RHS;
73 return *LHS == 0 && *RHS == 0;
76 template <class T>
77 constexpr T identity(T t) {
78 return t;
81 template <class T, class U>
82 struct Pair {
83 T first;
84 U second;
87 template <class T, class U>
88 constexpr bool is_same = false;
89 template <class T>
90 constexpr bool is_same<T, T> = true;
92 // test types
93 static_assert(is_same<decltype(__builtin_LINE()), unsigned>);
94 static_assert(is_same<decltype(__builtin_COLUMN()), unsigned>);
95 static_assert(is_same<decltype(__builtin_FILE()), const char *>);
96 static_assert(is_same<decltype(__builtin_FILE_NAME()), const char *>);
97 static_assert(is_same<decltype(__builtin_FUNCTION()), const char *>);
98 #ifdef MS
99 static_assert(is_same<decltype(__builtin_FUNCSIG()), const char *>);
100 #endif
101 static_assert(is_same<decltype(__builtin_source_location()), const std::source_location::public_impl_alias *>);
103 // test noexcept
104 static_assert(noexcept(__builtin_LINE()));
105 static_assert(noexcept(__builtin_COLUMN()));
106 static_assert(noexcept(__builtin_FILE()));
107 static_assert(noexcept(__builtin_FILE_NAME()));
108 static_assert(noexcept(__builtin_FUNCTION()));
109 #ifdef MS
110 static_assert(noexcept(__builtin_FUNCSIG()));
111 #endif
112 static_assert(noexcept(__builtin_source_location()));
114 //===----------------------------------------------------------------------===//
115 // __builtin_LINE()
116 //===----------------------------------------------------------------------===//
118 namespace test_line {
119 static_assert(SL::current().line() == __LINE__);
120 static_assert(SL::current().line() == CURRENT_FROM_MACRO().line());
122 static constexpr SL GlobalS = SL::current();
124 static_assert(GlobalS.line() == __LINE__ - 2);
126 // clang-format off
127 constexpr bool test_line_fn() {
128 constexpr SL S = SL::current();
129 static_assert(S.line() == (__LINE__ - 1), "");
130 // The start of the call expression to `current()` begins at the token `SL`
131 constexpr int ExpectLine = __LINE__ + 3;
132 constexpr SL S2
134 SL // Call expression starts here
136 current
141 static_assert(S2.line() == ExpectLine, "");
143 static_assert(
144 FORWARD(
145 __builtin_LINE
149 == __LINE__ - 1, "");
150 static_assert(\
152 __builtin_LINE()\
154 == __LINE__ - 2, "");
155 static_assert(\
157 _builtin_LINE()
158 == __LINE__ - 2, "");
160 return true;
162 // clang-format on
163 static_assert(test_line_fn());
165 static_assert(__builtin_LINE() == __LINE__, "");
167 constexpr int baz() { return 101; }
169 constexpr int test_line_fn_simple(int z = baz(), int x = __builtin_LINE()) {
170 return x;
172 void bar() {
173 static_assert(test_line_fn_simple() == __LINE__, "");
174 static_assert(test_line_fn_simple() == __LINE__, "");
177 struct CallExpr {
178 constexpr int operator()(int x = __builtin_LINE()) const { return x; }
180 constexpr CallExpr get_call() { return CallExpr{}; }
181 static_assert(get_call()() == __LINE__, "");
183 template <class T>
184 constexpr bool test_line_fn_template(T Expect, int L = __builtin_LINE()) {
185 return Expect == L;
187 static_assert(test_line_fn_template(__LINE__));
189 struct InMemInit {
190 constexpr bool check(int expect) const {
191 return info.line() == expect;
193 SL info = SL::current();
194 InMemInit() = default;
195 constexpr InMemInit(int) {}
197 static_assert(InMemInit{}.check(__LINE__ - 3), "");
198 static_assert(InMemInit{42}.check(__LINE__ - 3), "");
200 template <class T, class U = SL>
201 struct InMemInitTemplate {
202 constexpr bool check(int expect) const {
203 return info.line() == expect;
205 U info = U::current();
206 InMemInitTemplate() = default;
207 constexpr InMemInitTemplate(T) {}
208 constexpr InMemInitTemplate(T, T) : info(U::current()) {}
209 template <class V = U> constexpr InMemInitTemplate(T, T, T, V info = U::current())
210 : info(info) {}
212 void test_mem_init_template() {
213 constexpr int line_offset = 8;
214 static_assert(InMemInitTemplate<int>{}.check(__LINE__ - line_offset), "");
215 static_assert(InMemInitTemplate<unsigned>{42}.check(__LINE__ - line_offset), "");
216 static_assert(InMemInitTemplate<unsigned>{42, 42}.check(__LINE__ - line_offset), "");
217 static_assert(InMemInitTemplate<unsigned>{42, 42, 42}.check(__LINE__), "");
220 struct AggInit {
221 int x;
222 int y = __builtin_LINE();
223 constexpr bool check(int expect) const {
224 return y == expect;
227 constexpr AggInit AI{42};
228 static_assert(AI.check(__LINE__ - 1), "");
230 template <class T, class U = SL>
231 struct AggInitTemplate {
232 constexpr bool check(int expect) const {
233 return expect == info.line();
235 T x;
236 U info = U::current();
239 template <class T, class U = SL>
240 constexpr U test_fn_template(T, U u = U::current()) {
241 return u;
243 void fn_template_tests() {
244 static_assert(test_fn_template(42).line() == __LINE__, "");
247 struct TestMethodTemplate {
248 template <class T, class U = SL, class U2 = SL>
249 constexpr U get(T, U u = U::current(), U2 u2 = identity(U2::current())) const {
250 assert(u.line() == u2.line());
251 return u;
254 void method_template_tests() {
255 static_assert(TestMethodTemplate{}.get(42).line() == __LINE__, "");
258 struct InStaticInit {
259 static constexpr int LINE = __LINE__;
260 static constexpr const int x1 = __builtin_LINE();
261 static constexpr const int x2 = identity(__builtin_LINE());
262 static const int x3;
263 const int x4 = __builtin_LINE();
264 int x5 = __builtin_LINE();
266 const int InStaticInit::x3 = __builtin_LINE();
267 static_assert(InStaticInit::x1 == InStaticInit::LINE + 1, "");
268 static_assert(InStaticInit::x2 == InStaticInit::LINE + 2, "");
270 template <class T, int N = __builtin_LINE(), int Expect = -1>
271 constexpr void check_fn_template_param(T) {
272 constexpr int RealExpect = Expect == -1 ? __LINE__ - 2 : Expect;
273 static_assert(N == RealExpect);
275 template void check_fn_template_param(int);
276 template void check_fn_template_param<long, 42, 42>(long);
278 #line 100
279 struct AggBase {
280 #line 200
281 int x = __builtin_LINE();
282 int y = __builtin_LINE();
283 int z = __builtin_LINE();
285 #line 300
286 struct AggDer : AggBase {
288 #line 400
289 static_assert(AggDer{}.x == 400, "");
291 struct ClassBase {
292 #line 400
293 int x = __builtin_LINE();
294 int y = 0;
295 int z = 0;
296 #line 500
297 ClassBase() = default;
298 constexpr ClassBase(int yy, int zz = __builtin_LINE())
299 : y(yy), z(zz) {}
301 struct ClassDer : ClassBase {
302 #line 600
303 ClassDer() = default;
304 constexpr ClassDer(int yy) : ClassBase(yy) {}
305 constexpr ClassDer(int yy, int zz) : ClassBase(yy, zz) {}
307 #line 700
308 static_assert(ClassDer{}.x == 500, "");
309 static_assert(ClassDer{42}.x == 501, "");
310 static_assert(ClassDer{42}.z == 601, "");
311 static_assert(ClassDer{42, 42}.x == 501, "");
313 struct ClassAggDer : AggBase {
314 #line 800
315 ClassAggDer() = default;
316 constexpr ClassAggDer(int, int x = __builtin_LINE()) : AggBase{x} {}
318 static_assert(ClassAggDer{}.x == 100, "");
320 } // namespace test_line
322 //===----------------------------------------------------------------------===//
323 // __builtin_FILE()
324 //===----------------------------------------------------------------------===//
326 namespace test_file {
327 constexpr const char *test_file_simple(const char *__f = __builtin_FILE()) {
328 return __f;
330 void test_function() {
331 #line 900
332 static_assert(is_equal(test_file_simple(), __FILE__));
333 static_assert(is_equal(SLF::test_function().file(), __FILE__), "");
334 static_assert(is_equal(SLF::test_function_template(42).file(), __FILE__), "");
336 static_assert(is_equal(SLF::test_function_indirect().file(), SLF::global_info.file()), "");
337 static_assert(is_equal(SLF::test_function_template_indirect(42).file(), SLF::global_info.file()), "");
339 static_assert(test_file_simple() != nullptr);
340 static_assert(!is_equal(test_file_simple(), "source_location.cpp"));
343 void test_class() {
344 #line 315
345 using SLF::TestClass;
346 constexpr TestClass Default;
347 constexpr TestClass InParam{42};
348 constexpr TestClass Template{42, 42};
349 constexpr auto *F = Default.info.file();
350 constexpr auto Char = F[0];
351 static_assert(is_equal(Default.info.file(), SLF::FILE), "");
352 static_assert(is_equal(InParam.info.file(), SLF::FILE), "");
353 static_assert(is_equal(InParam.ctor_info.file(), __FILE__), "");
356 void test_aggr_class() {
357 using Agg = SLF::AggrClass<>;
358 constexpr Agg Default{};
359 constexpr Agg InitOne{42};
360 static_assert(is_equal(Default.init_info.file(), __FILE__), "");
361 static_assert(is_equal(InitOne.init_info.file(), __FILE__), "");
364 } // namespace test_file
366 //===----------------------------------------------------------------------===//
367 // __builtin_FILE_NAME()
368 //===----------------------------------------------------------------------===//
370 namespace test_file_name {
371 constexpr const char *test_file_name_simple(
372 const char *__f = __builtin_FILE_NAME()) {
373 return __f;
375 void test_function() {
376 #line 900
377 static_assert(is_equal(test_file_name_simple(), __FILE_NAME__));
378 static_assert(is_equal(SLF::test_function_filename(), __FILE_NAME__), "");
379 static_assert(is_equal(SLF::test_function_filename_template(42),
380 __FILE_NAME__), "");
382 static_assert(is_equal(SLF::test_function_filename_indirect(),
383 SLF::global_info_filename), "");
384 static_assert(is_equal(SLF::test_function_filename_template_indirect(42),
385 SLF::global_info_filename), "");
387 static_assert(test_file_name_simple() != nullptr);
388 static_assert(is_equal(test_file_name_simple(), "source_location.cpp"));
391 void test_class() {
392 #line 315
393 using SLF::TestClass;
394 constexpr TestClass Default;
395 constexpr TestClass InParam{42};
396 constexpr TestClass Template{42, 42};
397 constexpr auto *F = Default.info_file_name;
398 constexpr auto Char = F[0];
399 static_assert(is_equal(Default.info_file_name, SLF::FILE_NAME), "");
400 static_assert(is_equal(InParam.info_file_name, SLF::FILE_NAME), "");
401 static_assert(is_equal(InParam.ctor_info_file_name, __FILE_NAME__), "");
404 void test_aggr_class() {
405 using Agg = SLF::AggrClass<>;
406 constexpr Agg Default{};
407 constexpr Agg InitOne{42};
408 static_assert(is_equal(Default.init_info_file_name, __FILE_NAME__), "");
409 static_assert(is_equal(InitOne.init_info_file_name, __FILE_NAME__), "");
412 } // namespace test_file_name
414 //===----------------------------------------------------------------------===//
415 // __builtin_FUNCTION()
416 //===----------------------------------------------------------------------===//
418 namespace test_func {
420 constexpr const char *test_func_simple(const char *__f = __builtin_FUNCTION()) {
421 return __f;
423 constexpr const char *get_function() {
424 return __func__;
426 constexpr bool test_function() {
427 return is_equal(__func__, test_func_simple()) &&
428 !is_equal(get_function(), test_func_simple());
430 static_assert(test_function());
432 template <class T, class U = SL>
433 constexpr Pair<U, U> test_func_template(T, U u = U::current()) {
434 static_assert(is_equal(__PRETTY_FUNCTION__, U::current().function()));
435 return {u, U::current()};
437 template <class T>
438 void func_template_tests() {
439 constexpr auto P = test_func_template(42);
440 //static_assert(is_equal(P.first.function(), __func__), "");
441 //static_assert(!is_equal(P.second.function(), __func__), "");
443 template void func_template_tests<int>();
445 template <class = int, class T = SL>
446 struct TestCtor {
447 T info = T::current();
448 T ctor_info;
449 TestCtor() = default;
450 template <class U = SL>
451 constexpr TestCtor(int, U u = U::current()) : ctor_info(u) {}
453 void ctor_tests() {
454 constexpr TestCtor<> Default;
455 constexpr TestCtor<> Template{42};
456 static const char *XYZZY = Template.info.function();
457 static_assert(is_equal(Default.info.function(), "test_func::TestCtor<>::TestCtor() [T = std::source_location]"));
458 static_assert(is_equal(Default.ctor_info.function(), ""));
459 static_assert(is_equal(Template.info.function(), "test_func::TestCtor<>::TestCtor(int, U) [T = std::source_location, U = std::source_location]"));
460 static_assert(is_equal(Template.ctor_info.function(), __PRETTY_FUNCTION__));
463 constexpr SL global_sl = SL::current();
464 static_assert(is_equal(global_sl.function(), ""));
466 } // namespace test_func
468 //===----------------------------------------------------------------------===//
469 // __builtin_FUNCSIG()
470 //===----------------------------------------------------------------------===//
472 #ifdef MS
473 namespace test_funcsig {
475 constexpr const char *test_funcsig_simple(const char *f = __builtin_FUNCSIG()) {
476 return f;
478 constexpr const char *get_funcsig() {
479 return __FUNCSIG__;
481 constexpr bool test_funcsig() {
482 return is_equal(__FUNCSIG__, test_funcsig_simple()) &&
483 !is_equal(get_funcsig(), test_funcsig_simple());
485 static_assert(test_funcsig());
487 template <class T>
488 constexpr Pair<const char*, const char*> test_funcsig_template(T, const char* f = __builtin_FUNCSIG()) {
489 return {f, __builtin_FUNCSIG()};
491 template <class T>
492 void func_template_tests() {
493 constexpr auto P = test_funcsig_template(42);
494 static_assert(is_equal(P.first, __FUNCSIG__), "");
495 static_assert(!is_equal(P.second, __FUNCSIG__), "");
497 template void func_template_tests<int>();
499 template <class = int, class T = const char*>
500 struct TestCtor {
501 T funcsig = __builtin_FUNCSIG();
502 T ctor_funcsig;
503 TestCtor() = default;
504 template <class F = const char*>
505 constexpr TestCtor(int, F f = __builtin_FUNCSIG()) : ctor_funcsig(f) {}
507 void ctor_tests() {
508 constexpr TestCtor<> Template{42};
509 static_assert(is_equal(Template.funcsig, "__cdecl test_funcsig::TestCtor<>::TestCtor(int, F) [T = const char *, F = const char *]"));
510 static_assert(is_equal(Template.ctor_funcsig, __FUNCSIG__));
513 constexpr const char* global_funcsig = __builtin_FUNCSIG();
514 static_assert(is_equal(global_funcsig, ""));
516 } // namespace test_funcsig
517 #endif
519 //===----------------------------------------------------------------------===//
520 // __builtin_COLUMN()
521 //===----------------------------------------------------------------------===//
523 namespace test_column {
525 // clang-format off
526 constexpr bool test_column_fn() {
527 constexpr SL S = SL::current();
528 static_assert(S.line() == (__LINE__ - 1), "");
529 constexpr int Indent = 4;
531 // The start of the call expression to `current()` begins at the token `SL`
532 constexpr int ExpectCol = Indent + 3;
533 constexpr SL S2
535 SL // Call expression starts here
537 current
542 static_assert(S2.column() == ExpectCol, "");
545 constexpr int ExpectCol = 2;
546 constexpr int C =
547 __builtin_COLUMN // Expect call expression to start here
549 static_assert(C == ExpectCol);
551 return true;
553 #line 420
554 static_assert(test_column_fn());
556 // Test that the column matches the start of the call expression 'SL::current()'
557 static_assert(SL::current().column() == __builtin_strlen("static_assert(S"));
558 struct TestClass {
559 int x = __builtin_COLUMN();
560 TestClass() = default; /* indented to 3 spaces for testing */
561 constexpr TestClass(int, int o = __builtin_COLUMN()) : x(o) {}
563 struct TestAggClass {
564 int x = __builtin_COLUMN();
566 constexpr bool test_class() {
568 auto check = [](int V, const char* S, int indent = 4) {
569 assert(V == (__builtin_strlen(S) + indent));
572 TestClass t{};
573 check(t.x, " T", 0); // Start of default constructor decl.
576 TestClass t1
577 {42};
578 check(t1.x, "TestClass t"); // Start of variable being constructed.
581 TestAggClass t { };
582 check(t.x, "TestAggClass t { }");
585 TestAggClass t = { };
586 check(t.x, "TestAggClass t = { }");
588 return true;
590 static_assert(test_class());
591 // clang-format on
592 } // namespace test_column
594 // Test [reflection.src_loc.creation]p2
595 // > The value should be affected by #line (C++14 16.4) in the same manner as
596 // > for __LINE__ and __FILE__.
597 namespace test_pragma_line {
598 constexpr int StartLine = 42;
599 #line 42
600 static_assert(__builtin_LINE() == StartLine);
601 static_assert(__builtin_LINE() == StartLine + 1);
602 static_assert(SL::current().line() == StartLine + 2);
603 #line 44 "test_file.c"
604 static_assert(is_equal("test_file.c", __FILE__));
605 static_assert(is_equal("test_file.c", __builtin_FILE()));
606 static_assert(is_equal("test_file.c", __builtin_FILE_NAME()));
607 static_assert(is_equal("test_file.c", SL::current().file()));
608 static_assert(is_equal("test_file.c", SLF::test_function().file()));
609 static_assert(is_equal(SLF::FILE, SLF::test_function_indirect().file()));
610 } // end namespace test_pragma_line
612 namespace test_out_of_line_init {
613 #line 4000 "test_out_of_line_init.cpp"
614 constexpr unsigned get_line(unsigned n = __builtin_LINE()) { return n; }
615 constexpr const char *get_file(const char *f = __builtin_FILE()) { return f; }
616 constexpr const char *get_func(const char *f = __builtin_FUNCTION()) { return f; }
617 #line 4100 "A.cpp"
618 struct A {
619 int n = __builtin_LINE();
620 int n2 = get_line();
621 const char *f = __builtin_FILE();
622 const char *f2 = get_file();
623 const char *func = __builtin_FUNCTION();
624 const char *func2 = get_func();
625 SL info = SL::current();
627 #line 4200 "B.cpp"
628 struct B {
629 A a = {};
631 #line 4300 "test_passed.cpp"
632 constexpr B b = {};
633 static_assert(b.a.n == 4300, "");
634 static_assert(b.a.n2 == 4300, "");
635 static_assert(b.a.info.line() == 4300, "");
636 static_assert(is_equal(b.a.f, "test_passed.cpp"));
637 static_assert(is_equal(b.a.f2, "test_passed.cpp"));
638 static_assert(is_equal(b.a.info.file(), "test_passed.cpp"));
639 static_assert(is_equal(b.a.func, ""));
640 static_assert(is_equal(b.a.func2, ""));
641 static_assert(is_equal(b.a.info.function(), ""));
643 constexpr bool test_in_func() {
644 #line 4400 "test_func_passed.cpp"
645 constexpr B b = {};
646 static_assert(b.a.n == 4400, "");
647 static_assert(b.a.n2 == 4400, "");
648 static_assert(b.a.info.line() == 4400, "");
649 static_assert(is_equal(b.a.f, "test_func_passed.cpp"));
650 static_assert(is_equal(b.a.f2, "test_func_passed.cpp"));
651 static_assert(is_equal(b.a.info.file(), "test_func_passed.cpp"));
652 static_assert(is_equal(b.a.func, "test_in_func"));
653 static_assert(is_equal(b.a.func2, "test_in_func"));
654 static_assert(is_equal(b.a.info.function(), "bool test_out_of_line_init::test_in_func()"));
655 return true;
657 static_assert(test_in_func());
659 } // end namespace test_out_of_line_init
661 namespace test_global_scope {
662 #line 5000 "test_global_scope.cpp"
663 constexpr unsigned get_line(unsigned n = __builtin_LINE()) { return n; }
664 constexpr const char *get_file(const char *f = __builtin_FILE()) { return f; }
665 constexpr const char *get_func(const char *f = __builtin_FUNCTION()) { return f; }
666 #line 5100
667 struct InInit {
668 unsigned l = get_line();
669 const char *f = get_file();
670 const char *func = get_func();
672 #line 5200 "in_init.cpp"
673 constexpr InInit() {}
675 #line 5300
676 constexpr InInit II;
678 static_assert(II.l == 5200, "");
679 static_assert(is_equal(II.f, "in_init.cpp"));
680 static_assert(is_equal(II.func, "InInit"));
682 #line 5400
683 struct AggInit {
684 unsigned l = get_line();
685 const char *f = get_file();
686 const char *func = get_func();
688 #line 5500 "brace_init.cpp"
689 constexpr AggInit AI = {};
690 static_assert(AI.l == 5500);
691 static_assert(is_equal(AI.f, "brace_init.cpp"));
692 static_assert(is_equal(AI.func, ""));
694 } // namespace test_global_scope
696 namespace TestFuncInInit {
697 #line 6000 "InitClass.cpp"
698 struct Init {
699 SL info;
700 #line 6100 "InitCtor.cpp"
701 constexpr Init(SL info = SL::current()) : info(info) {}
703 #line 6200 "InitGlobal.cpp"
704 constexpr Init I;
705 static_assert(I.info.line() == 6200);
706 static_assert(is_equal(I.info.file(), "InitGlobal.cpp"));
708 } // namespace TestFuncInInit
710 namespace TestConstexprContext {
711 #line 7000 "TestConstexprContext.cpp"
712 constexpr const char* foo() { return __builtin_FILE(); }
713 #line 7100 "Bar.cpp"
714 constexpr const char* bar(const char* x = foo()) { return x; }
715 constexpr bool test() {
716 static_assert(is_equal(bar(), "TestConstexprContext.cpp"));
717 return true;
719 static_assert(test());
722 namespace Lambda {
723 #line 8000 "TestLambda.cpp"
724 constexpr int nested_lambda(int l = []{
725 return SL::current().line();
726 }()) {
727 return l;
729 static_assert(nested_lambda() == __LINE__ - 4);
731 constexpr int lambda_param(int l = [](int l = SL::current().line()) {
732 return l;
733 }()) {
734 return l;
736 static_assert(lambda_param() == __LINE__);
741 constexpr int compound_literal_fun(int a =
742 (int){ SL::current().line() }
743 ) { return a ;}
744 static_assert(compound_literal_fun() == __LINE__);
746 struct CompoundLiteral {
747 int a = (int){ SL::current().line() };
749 static_assert(CompoundLiteral{}.a == __LINE__);
752 // FIXME
753 // Init captures are subexpressions of the lambda expression
754 // so according to the standard immediate invocations in init captures
755 // should be evaluated at the call site.
756 // However Clang does not yet implement this as it would introduce
757 // a fair bit of complexity.
758 // We intend to implement that functionality once we find real world
759 // use cases that require it.
760 constexpr int test_init_capture(int a =
761 [b = SL::current().line()] { return b; }()) {
762 return a;
764 #if defined(USE_CONSTEVAL) && !defined(NEW_INTERP)
765 static_assert(test_init_capture() == __LINE__ - 4);
766 #else
767 static_assert(test_init_capture() == __LINE__ );
768 #endif
770 namespace check_immediate_invocations_in_templates {
772 template <typename T = int>
773 struct G {
774 T line = __builtin_LINE();
776 template <typename T>
777 struct S {
778 int i = G<T>{}.line;
780 static_assert(S<int>{}.i != // intentional new line
781 S<int>{}.i);
783 template <typename T>
784 constexpr int f(int i = G<T>{}.line) {
785 return i;
788 static_assert(f<int>() != // intentional new line
789 f<int>());
792 #ifdef PAREN_INIT
793 namespace GH63903 {
794 struct S {
795 int _;
796 int i = SL::current().line();
797 int j = __builtin_LINE();
799 // Ensure parent aggregate initialization is consistent with brace
800 // aggregate initialization.
801 // Note: consteval functions are evaluated where they are used.
802 static_assert(S(0).i == __builtin_LINE());
803 static_assert(S(0).i == S{0}.i);
804 static_assert(S(0).j == S{0}.j);
805 static_assert(S(0).j == S{0}.i);
807 #endif