1084 lines · cpp
1// RUN: %clang_cc1 -std=c++1z -fcxx-exceptions -fexceptions -verify %s2// RUN: %clang_cc1 -std=c++2a -fcxx-exceptions -DUSE_CONSTEVAL -fexceptions -verify %s3// RUN: %clang_cc1 -std=c++2b -fcxx-exceptions -DUSE_CONSTEVAL -DPAREN_INIT -fexceptions -verify %s4// RUN: %clang_cc1 -std=c++1z -fcxx-exceptions -fms-extensions -DMS -fexceptions -fms-compatibility -verify %s5// RUN: %clang_cc1 -std=c++2a -fcxx-exceptions -fms-extensions -DMS -DUSE_CONSTEVAL -fexceptions -fms-compatibility -verify %s6//7// RUN: %clang_cc1 -std=c++1z -fcxx-exceptions -fexceptions -fexperimental-new-constant-interpreter -DNEW_INTERP -verify %s8// RUN: %clang_cc1 -std=c++2a -fcxx-exceptions -DUSE_CONSTEVAL -fexceptions -fexperimental-new-constant-interpreter -DNEW_INTERP -verify %s9// RUN: %clang_cc1 -std=c++2b -fcxx-exceptions -DUSE_CONSTEVAL -DPAREN_INIT -fexceptions -fexperimental-new-constant-interpreter -DNEW_INTERP -verify %s10// RUN: %clang_cc1 -std=c++1z -fcxx-exceptions -fms-extensions -DMS -fexceptions -fexperimental-new-constant-interpreter -DNEW_INTERP -fms-compatibility -verify %s11// RUN: %clang_cc1 -std=c++2a -fcxx-exceptions -fms-extensions -DMS -DUSE_CONSTEVAL -fexceptions -fexperimental-new-constant-interpreter -DNEW_INTERP -verify -fms-compatibility %s12// expected-no-diagnostics13 14#define assert(...) ((__VA_ARGS__) ? ((void)0) : throw 42)15#define CURRENT_FROM_MACRO() SL::current()16#define FORWARD(...) __VA_ARGS__17 18template <unsigned>19struct Printer;20 21#ifdef USE_CONSTEVAL22#define SOURCE_LOC_EVAL_KIND consteval23#else24#define SOURCE_LOC_EVAL_KIND constexpr25#endif26 27namespace std {28class source_location {29 struct __impl;30 31public:32 static SOURCE_LOC_EVAL_KIND source_location33 current(const __impl *__p = __builtin_source_location()) noexcept {34 source_location __loc;35 __loc.__m_impl = __p;36 return __loc;37 }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 : ""; }44 45private:46 // Note: The type name "std::source_location::__impl", and its constituent47 // 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;53 };54 const __impl *__m_impl = nullptr;55 56public:57 using public_impl_alias = __impl;58};59} // namespace std60 61using SL = std::source_location;62 63#include "Inputs/source-location-file.h"64namespace SLF = source_location_file;65 66constexpr 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;72 }73 return *LHS == 0 && *RHS == 0;74}75 76template <class T>77constexpr T identity(T t) {78 return t;79}80 81template <class T, class U>82struct Pair {83 T first;84 U second;85};86 87template <class T, class U>88constexpr bool is_same = false;89template <class T>90constexpr bool is_same<T, T> = true;91 92// test types93static_assert(is_same<decltype(__builtin_LINE()), unsigned>);94static_assert(is_same<decltype(__builtin_COLUMN()), unsigned>);95static_assert(is_same<decltype(__builtin_FILE()), const char *>);96static_assert(is_same<decltype(__builtin_FILE_NAME()), const char *>);97static_assert(is_same<decltype(__builtin_FUNCTION()), const char *>);98#ifdef MS99static_assert(is_same<decltype(__builtin_FUNCSIG()), const char *>);100#endif101static_assert(is_same<decltype(__builtin_source_location()), const std::source_location::public_impl_alias *>);102 103// test noexcept104static_assert(noexcept(__builtin_LINE()));105static_assert(noexcept(__builtin_COLUMN()));106static_assert(noexcept(__builtin_FILE()));107static_assert(noexcept(__builtin_FILE_NAME()));108static_assert(noexcept(__builtin_FUNCTION()));109#ifdef MS110static_assert(noexcept(__builtin_FUNCSIG()));111#endif112static_assert(noexcept(__builtin_source_location()));113 114//===----------------------------------------------------------------------===//115// __builtin_LINE()116//===----------------------------------------------------------------------===//117 118namespace test_line {119static_assert(SL::current().line() == __LINE__);120static_assert(SL::current().line() == CURRENT_FROM_MACRO().line());121 122static constexpr SL GlobalS = SL::current();123 124static_assert(GlobalS.line() == __LINE__ - 2);125 126// clang-format off127constexpr 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 S2133 =134 SL // Call expression starts here135 ::136 current137 (138 139 )140 ;141 static_assert(S2.line() == ExpectLine, "");142 143 static_assert(144 FORWARD(145 __builtin_LINE146 (147 )148 )149 == __LINE__ - 1, "");150 static_assert(\151\152 __builtin_LINE()\153\154 == __LINE__ - 2, "");155 static_assert(\156 _\157_builtin_LINE()158 == __LINE__ - 2, "");159 160 return true;161}162// clang-format on163static_assert(test_line_fn());164 165static_assert(__builtin_LINE() == __LINE__, "");166 167constexpr int baz() { return 101; }168 169constexpr int test_line_fn_simple(int z = baz(), int x = __builtin_LINE()) {170 return x;171}172void bar() {173 static_assert(test_line_fn_simple() == __LINE__, "");174 static_assert(test_line_fn_simple() == __LINE__, "");175}176 177struct CallExpr {178 constexpr int operator()(int x = __builtin_LINE()) const { return x; }179};180constexpr CallExpr get_call() { return CallExpr{}; }181static_assert(get_call()() == __LINE__, "");182 183template <class T>184constexpr bool test_line_fn_template(T Expect, int L = __builtin_LINE()) {185 return Expect == L;186}187static_assert(test_line_fn_template(__LINE__));188 189struct InMemInit {190 constexpr bool check(int expect) const {191 return info.line() == expect;192 }193 SL info = SL::current();194 InMemInit() = default;195 constexpr InMemInit(int) {}196};197static_assert(InMemInit{}.check(__LINE__ - 3), "");198static_assert(InMemInit{42}.check(__LINE__ - 3), "");199 200template <class T, class U = SL>201struct InMemInitTemplate {202 constexpr bool check(int expect) const {203 return info.line() == expect;204 }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) {}211};212void 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__), "");218}219 220struct AggInit {221 int x;222 int y = __builtin_LINE();223 constexpr bool check(int expect) const {224 return y == expect;225 }226};227constexpr AggInit AI{42};228static_assert(AI.check(__LINE__ - 1), "");229 230template <class T, class U = SL>231struct AggInitTemplate {232 constexpr bool check(int expect) const {233 return expect == info.line();234 }235 T x;236 U info = U::current();237};238 239template <class T, class U = SL>240constexpr U test_fn_template(T, U u = U::current()) {241 return u;242}243void fn_template_tests() {244 static_assert(test_fn_template(42).line() == __LINE__, "");245}246 247struct 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;252 }253};254void method_template_tests() {255 static_assert(TestMethodTemplate{}.get(42).line() == __LINE__, "");256}257 258struct 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();265};266const int InStaticInit::x3 = __builtin_LINE();267static_assert(InStaticInit::x1 == InStaticInit::LINE + 1, "");268static_assert(InStaticInit::x2 == InStaticInit::LINE + 2, "");269 270template <class T, int N = __builtin_LINE(), int Expect = -1>271constexpr void check_fn_template_param(T) {272 constexpr int RealExpect = Expect == -1 ? __LINE__ - 2 : Expect;273 static_assert(N == RealExpect);274}275template void check_fn_template_param(int);276template void check_fn_template_param<long, 42, 42>(long);277 278#line 100279struct AggBase {280#line 200281 int x = __builtin_LINE();282 int y = __builtin_LINE();283 int z = __builtin_LINE();284};285#line 300286struct AggDer : AggBase {287};288#line 400289static_assert(AggDer{}.x == 400, "");290 291struct ClassBase {292#line 400293 int x = __builtin_LINE();294 int y = 0;295 int z = 0;296#line 500297 ClassBase() = default;298 constexpr ClassBase(int yy, int zz = __builtin_LINE())299 : y(yy), z(zz) {}300};301struct ClassDer : ClassBase {302#line 600303 ClassDer() = default;304 constexpr ClassDer(int yy) : ClassBase(yy) {}305 constexpr ClassDer(int yy, int zz) : ClassBase(yy, zz) {}306};307#line 700308static_assert(ClassDer{}.x == 500, "");309static_assert(ClassDer{42}.x == 501, "");310static_assert(ClassDer{42}.z == 601, "");311static_assert(ClassDer{42, 42}.x == 501, "");312 313struct ClassAggDer : AggBase {314#line 800315 ClassAggDer() = default;316 constexpr ClassAggDer(int, int x = __builtin_LINE()) : AggBase{x} {}317};318static_assert(ClassAggDer{}.x == 100, "");319 320} // namespace test_line321 322//===----------------------------------------------------------------------===//323// __builtin_FILE()324//===----------------------------------------------------------------------===//325 326namespace test_file {327constexpr const char *test_file_simple(const char *__f = __builtin_FILE()) {328 return __f;329}330void test_function() {331#line 900332 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__), "");335 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()), "");338 339 static_assert(test_file_simple() != nullptr);340 static_assert(!is_equal(test_file_simple(), "source_location.cpp"));341}342 343void test_class() {344#line 315345 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__), "");354}355 356void 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__), "");362}363 364} // namespace test_file365 366//===----------------------------------------------------------------------===//367// __builtin_FILE_NAME()368//===----------------------------------------------------------------------===//369 370namespace test_file_name {371constexpr const char *test_file_name_simple(372 const char *__f = __builtin_FILE_NAME()) {373 return __f;374}375void test_function() {376#line 900377 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__), "");381 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), "");386 387 static_assert(test_file_name_simple() != nullptr);388 static_assert(is_equal(test_file_name_simple(), "source_location.cpp"));389}390 391void test_class() {392#line 315393 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__), "");402}403 404void 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__), "");410}411 412} // namespace test_file_name413 414//===----------------------------------------------------------------------===//415// __builtin_FUNCTION()416//===----------------------------------------------------------------------===//417 418namespace test_func {419 420constexpr const char *test_func_simple(const char *__f = __builtin_FUNCTION()) {421 return __f;422}423constexpr const char *get_function() {424 return __func__;425}426constexpr bool test_function() {427 return is_equal(__func__, test_func_simple()) &&428 !is_equal(get_function(), test_func_simple());429}430static_assert(test_function());431 432template <class T, class U = SL>433constexpr 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()};436}437template <class T>438void 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__), "");442}443template void func_template_tests<int>();444 445template <class = int, class T = SL>446struct 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) {}452};453void 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__));461}462 463constexpr SL global_sl = SL::current();464static_assert(is_equal(global_sl.function(), ""));465 466template <class T>467class TestBI {468public:469 TestBI() {470#ifdef MS471 static_assert(is_equal(__FUNCTION__, "test_func::TestBI<int>::TestBI"));472#else473 static_assert(is_equal(__FUNCTION__, "TestBI"));474#endif475 static_assert(is_equal(__func__, "TestBI"));476 }477};478 479template <class T>480class TestClass {481public:482 TestClass() {483#ifdef MS484 static_assert(is_equal(__FUNCTION__, "test_func::TestClass<class test_func::C>::TestClass"));485#else486 static_assert(is_equal(__FUNCTION__, "TestClass"));487#endif488 static_assert(is_equal(__func__, "TestClass"));489 }490};491 492template <class T>493class TestStruct {494public:495 TestStruct() {496#ifdef MS497 static_assert(is_equal(__FUNCTION__, "test_func::TestStruct<struct test_func::S>::TestStruct"));498#else499 static_assert(is_equal(__FUNCTION__, "TestStruct"));500#endif501 static_assert(is_equal(__func__, "TestStruct"));502 }503};504 505template <class T>506class TestEnum {507public:508 TestEnum() {509#ifdef MS510 static_assert(is_equal(__FUNCTION__, "test_func::TestEnum<enum test_func::E>::TestEnum"));511#else512 static_assert(is_equal(__FUNCTION__, "TestEnum"));513#endif514 static_assert(is_equal(__func__, "TestEnum"));515 }516};517 518class C {};519struct S {};520enum E {};521 522TestBI<int> t1;523TestClass<test_func::C> t2;524TestStruct<test_func::S> t3;525TestEnum<test_func::E> t4;526 527class A { int b;};528namespace inner {529 template <class Ty>530 class C {531 public:532 template <class T>533 static void f(int i) {534 (void)i;535#ifdef MS536 static_assert(is_equal(__FUNCTION__, "test_func::inner::C<class test_func::A>::f"));537#else538 static_assert(is_equal(__FUNCTION__, "f"));539#endif540 }541 template <class T>542 static constexpr void cf(int i) {543 (void)i;544#ifdef MS545 static_assert(is_equal(__FUNCTION__, "test_func::inner::C<class test_func::A>::cf"));546#else547 static_assert(is_equal(__FUNCTION__, "cf"));548#endif549 }550 template <class T>551 static void df(double f) {552 (void)f;553#ifdef MS554 static_assert(is_equal(__FUNCTION__, "test_func::inner::C<class test_func::A>::df"));555#else556 static_assert(is_equal(__FUNCTION__, "df"));557#endif558 }559 template <class T>560 static constexpr void cdf(double f) {561 (void)f;562#ifdef MS563 static_assert(is_equal(__FUNCTION__, "test_func::inner::C<class test_func::A>::cdf"));564#else565 static_assert(is_equal(__FUNCTION__, "cdf"));566#endif567 }568 };569}570 571 void foo() {572 test_func::inner::C<test_func::A>::f<char>(1);573 test_func::inner::C<test_func::A>::cf<char>(1);574 test_func::inner::C<test_func::A>::df<void>(1.0);575 test_func::inner::C<test_func::A>::cdf<void>(1.0);576}577 578} // namespace test_func579 580 581//===----------------------------------------------------------------------===//582// __builtin_FUNCSIG()583//===----------------------------------------------------------------------===//584 585#ifdef MS586namespace test_funcsig {587 588constexpr const char *test_funcsig_simple(const char *f = __builtin_FUNCSIG()) {589 return f;590}591constexpr const char *get_funcsig() {592 return __FUNCSIG__;593}594constexpr bool test_funcsig() {595 return is_equal(__FUNCSIG__, test_funcsig_simple()) &&596 !is_equal(get_funcsig(), test_funcsig_simple());597}598static_assert(test_funcsig());599 600template <class T>601constexpr Pair<const char*, const char*> test_funcsig_template(T, const char* f = __builtin_FUNCSIG()) {602 return {f, __builtin_FUNCSIG()};603}604template <class T>605void func_template_tests() {606 constexpr auto P = test_funcsig_template(42);607 static_assert(is_equal(P.first, __FUNCSIG__), "");608 static_assert(!is_equal(P.second, __FUNCSIG__), "");609}610template void func_template_tests<int>();611 612template <class = int, class T = const char*>613struct TestCtor {614 T funcsig = __builtin_FUNCSIG();615 T ctor_funcsig;616 TestCtor() = default;617 template <class F = const char*>618 constexpr TestCtor(int, F f = __builtin_FUNCSIG()) : ctor_funcsig(f) {}619};620void ctor_tests() {621 constexpr TestCtor<> Template{42};622 static_assert(is_equal(Template.funcsig, "__cdecl test_funcsig::TestCtor<>::TestCtor(int, F) [T = const char *, F = const char *]"));623 static_assert(is_equal(Template.ctor_funcsig, __FUNCSIG__));624}625 626constexpr const char* global_funcsig = __builtin_FUNCSIG();627static_assert(is_equal(global_funcsig, ""));628 629} // namespace test_funcsig630#endif631 632//===----------------------------------------------------------------------===//633// __builtin_COLUMN()634//===----------------------------------------------------------------------===//635 636namespace test_column {637 638// clang-format off639constexpr bool test_column_fn() {640 constexpr SL S = SL::current();641 static_assert(S.line() == (__LINE__ - 1), "");642 constexpr int Indent = 4;643 {644 // The start of the call expression to `current()` begins at the token `SL`645 constexpr int ExpectCol = Indent + 3;646 constexpr SL S2647 =648 SL // Call expression starts here649 ::650 current651 (652 653 )654 ;655 static_assert(S2.column() == ExpectCol, "");656 }657 {658 constexpr int ExpectCol = 2;659 constexpr int C =660 __builtin_COLUMN // Expect call expression to start here661 ();662 static_assert(C == ExpectCol);663 }664 return true;665}666#line 420667static_assert(test_column_fn());668 669// Test that the column matches the start of the call expression 'SL::current()'670static_assert(SL::current().column() == __builtin_strlen("static_assert(S"));671struct TestClass {672 int x = __builtin_COLUMN();673 TestClass() = default; /* indented to 3 spaces for testing */674 constexpr TestClass(int, int o = __builtin_COLUMN()) : x(o) {}675};676struct TestAggClass {677 int x = __builtin_COLUMN();678};679constexpr bool test_class() {680 681 auto check = [](int V, const char* S, int indent = 4) {682 assert(V == (__builtin_strlen(S) + indent));683 };684 {685 TestClass t{};686 check(t.x, " T", 0); // Start of default constructor decl.687 }688 {689 TestClass t1690 {42};691 check(t1.x, "TestClass t"); // Start of variable being constructed.692 }693 {694 TestAggClass t { };695 check(t.x, "TestAggClass t { }");696 }697 {698 TestAggClass t = { };699 check(t.x, "TestAggClass t = { }");700 }701 return true;702}703static_assert(test_class());704// clang-format on705} // namespace test_column706 707// Test [reflection.src_loc.creation]p2708// > The value should be affected by #line (C++14 16.4) in the same manner as709// > for __LINE__ and __FILE__.710namespace test_pragma_line {711constexpr int StartLine = 42;712#line 42713static_assert(__builtin_LINE() == StartLine);714static_assert(__builtin_LINE() == StartLine + 1);715static_assert(SL::current().line() == StartLine + 2);716#line 44 "test_file.c"717static_assert(is_equal("test_file.c", __FILE__));718static_assert(is_equal("test_file.c", __builtin_FILE()));719static_assert(is_equal("test_file.c", __builtin_FILE_NAME()));720static_assert(is_equal("test_file.c", SL::current().file()));721static_assert(is_equal("test_file.c", SLF::test_function().file()));722static_assert(is_equal(SLF::FILE, SLF::test_function_indirect().file()));723} // end namespace test_pragma_line724 725namespace test_out_of_line_init {726#line 4000 "test_out_of_line_init.cpp"727constexpr unsigned get_line(unsigned n = __builtin_LINE()) { return n; }728constexpr const char *get_file(const char *f = __builtin_FILE()) { return f; }729constexpr const char *get_func(const char *f = __builtin_FUNCTION()) { return f; }730#line 4100 "A.cpp"731struct A {732 int n = __builtin_LINE();733 int n2 = get_line();734 const char *f = __builtin_FILE();735 const char *f2 = get_file();736 const char *func = __builtin_FUNCTION();737 const char *func2 = get_func();738 SL info = SL::current();739};740#line 4200 "B.cpp"741struct B {742 A a = {};743};744#line 4300 "test_passed.cpp"745constexpr B b = {};746static_assert(b.a.n == 4300, "");747static_assert(b.a.n2 == 4300, "");748static_assert(b.a.info.line() == 4300, "");749static_assert(is_equal(b.a.f, "test_passed.cpp"));750static_assert(is_equal(b.a.f2, "test_passed.cpp"));751static_assert(is_equal(b.a.info.file(), "test_passed.cpp"));752static_assert(is_equal(b.a.func, ""));753static_assert(is_equal(b.a.func2, ""));754static_assert(is_equal(b.a.info.function(), ""));755 756constexpr bool test_in_func() {757#line 4400 "test_func_passed.cpp"758 constexpr B b = {};759 static_assert(b.a.n == 4400, "");760 static_assert(b.a.n2 == 4400, "");761 static_assert(b.a.info.line() == 4400, "");762 static_assert(is_equal(b.a.f, "test_func_passed.cpp"));763 static_assert(is_equal(b.a.f2, "test_func_passed.cpp"));764 static_assert(is_equal(b.a.info.file(), "test_func_passed.cpp"));765 static_assert(is_equal(b.a.func, "test_in_func"));766 static_assert(is_equal(b.a.func2, "test_in_func"));767 static_assert(is_equal(b.a.info.function(), "bool test_out_of_line_init::test_in_func()"));768 return true;769}770static_assert(test_in_func());771 772} // end namespace test_out_of_line_init773 774namespace test_global_scope {775#line 5000 "test_global_scope.cpp"776constexpr unsigned get_line(unsigned n = __builtin_LINE()) { return n; }777constexpr const char *get_file(const char *f = __builtin_FILE()) { return f; }778constexpr const char *get_func(const char *f = __builtin_FUNCTION()) { return f; }779#line 5100780struct InInit {781 unsigned l = get_line();782 const char *f = get_file();783 const char *func = get_func();784 785#line 5200 "in_init.cpp"786 constexpr InInit() {}787};788#line 5300789constexpr InInit II;790 791static_assert(II.l == 5200, "");792static_assert(is_equal(II.f, "in_init.cpp"));793static_assert(is_equal(II.func, "InInit"));794 795#line 5400796struct AggInit {797 unsigned l = get_line();798 const char *f = get_file();799 const char *func = get_func();800};801#line 5500 "brace_init.cpp"802constexpr AggInit AI = {};803static_assert(AI.l == 5500);804static_assert(is_equal(AI.f, "brace_init.cpp"));805static_assert(is_equal(AI.func, ""));806 807} // namespace test_global_scope808 809namespace TestFuncInInit {810#line 6000 "InitClass.cpp"811struct Init {812 SL info;813#line 6100 "InitCtor.cpp"814 constexpr Init(SL info = SL::current()) : info(info) {}815};816#line 6200 "InitGlobal.cpp"817constexpr Init I;818static_assert(I.info.line() == 6200);819static_assert(is_equal(I.info.file(), "InitGlobal.cpp"));820 821} // namespace TestFuncInInit822 823namespace TestConstexprContext {824#line 7000 "TestConstexprContext.cpp"825 constexpr const char* foo() { return __builtin_FILE(); }826#line 7100 "Bar.cpp"827 constexpr const char* bar(const char* x = foo()) { return x; }828 constexpr bool test() {829 static_assert(is_equal(bar(), "TestConstexprContext.cpp"));830 return true;831 }832 static_assert(test());833}834 835namespace Lambda {836#line 8000 "TestLambda.cpp"837constexpr int nested_lambda(int l = []{838 return SL::current().line();839}()) {840 return l;841}842static_assert(nested_lambda() == __LINE__ - 4);843 844constexpr int lambda_param(int l = [](int l = SL::current().line()) {845 return l;846}()) {847 return l;848}849static_assert(lambda_param() == __LINE__);850 851 852}853 854constexpr int compound_literal_fun(int a =855 (int){ SL::current().line() }856) { return a ;}857static_assert(compound_literal_fun() == __LINE__);858 859struct CompoundLiteral {860 int a = (int){ SL::current().line() };861};862static_assert(CompoundLiteral{}.a == __LINE__);863 864 865// FIXME866// Init captures are subexpressions of the lambda expression867// so according to the standard immediate invocations in init captures868// should be evaluated at the call site.869// However Clang does not yet implement this as it would introduce870// a fair bit of complexity.871// We intend to implement that functionality once we find real world872// use cases that require it.873constexpr int test_init_capture(int a =874 [b = SL::current().line()] { return b; }()) {875 return a;876}877#if defined(USE_CONSTEVAL) && !defined(NEW_INTERP)878static_assert(test_init_capture() == __LINE__ - 4);879#else880static_assert(test_init_capture() == __LINE__ );881#endif882 883namespace check_immediate_invocations_in_templates {884 885template <typename T = int>886struct G {887 T line = __builtin_LINE();888};889template <typename T>890struct S {891 int i = G<T>{}.line;892};893static_assert(S<int>{}.i != // intentional new line894 S<int>{}.i);895 896template <typename T>897constexpr int f(int i = G<T>{}.line) {898 return i;899}900 901static_assert(f<int>() != // intentional new line902 f<int>());903}904 905#ifdef PAREN_INIT906namespace GH63903 {907struct S {908 int _;909 int i = SL::current().line();910 int j = __builtin_LINE();911};912// Ensure parent aggregate initialization is consistent with brace913// aggregate initialization.914// Note: consteval functions are evaluated where they are used.915static_assert(S(0).i == __builtin_LINE());916static_assert(S(0).i == S{0}.i);917static_assert(S(0).j == S{0}.j);918static_assert(S(0).j == S{0}.i);919}920#endif921 922namespace GH78128 {923 924template<int N>925constexpr int f() {926 return N;927}928 929template<typename T>930void foo() {931 constexpr auto* F1 = std::source_location::current().function();932 static_assert(__builtin_strlen(F1) == f<__builtin_strlen(F1)>());933 934 constexpr auto* F2 = __builtin_FUNCTION();935 static_assert(__builtin_strlen(F2) == f<__builtin_strlen(F2)>());936 937#ifdef MS938 constexpr auto* F3 = __builtin_FUNCSIG();939 static_assert(__builtin_strlen(F3) == f<__builtin_strlen(F3)>());940#endif941}942 943void test() {944 foo<int>();945}946 947}948 949namespace GH80630 {950 951#define GH80630_LAMBDA \952 []( char const* fn ) { \953 static constexpr std::source_location loc = std::source_location::current(); \954 return &loc; \955 }( std::source_location::current().function() )956 957auto f( std::source_location const* loc = GH80630_LAMBDA ) {958 return loc;959}960 961auto g() {962 return f();963}964 965}966 967namespace GH92680 {968 969struct IntConstuctible {970 IntConstuctible(std::source_location = std::source_location::current());971};972 973template <typename>974auto construct_at(IntConstuctible) -> decltype(IntConstuctible()) {975 return {};976}977 978void test() {979 construct_at<IntConstuctible>({});980}981 982}983 984namespace GH106428 {985 986struct add_fn {987 template <typename T>988 constexpr auto operator()(T lhs, T rhs,989 const std::source_location loc = std::source_location::current())990 const -> T991 {992 return lhs + rhs;993 }994};995 996 997template <class _Fp, class... _Args>998decltype(_Fp{}(0, 0))999__invoke(_Fp&& __f);1000 1001template<typename T>1002struct type_identity { using type = T; };1003 1004template<class Fn>1005struct invoke_result : type_identity<decltype(__invoke(Fn{}))> {};1006 1007using i = invoke_result<add_fn>::type;1008static_assert(__is_same(i, int));1009 1010}1011 1012#if __cplusplus >= 202002L1013 1014namespace GH81155 {1015struct buff {1016 buff(buff &, const char * = __builtin_FUNCTION());1017};1018 1019template <class Ty>1020Ty declval();1021 1022template <class Fx>1023auto Call(buff arg) -> decltype(Fx{}(arg));1024 1025template <typename>1026struct F {};1027 1028template <class Fx>1029struct InvocableR : F<decltype(Call<Fx>(declval<buff>()))> {1030 static constexpr bool value = false;1031};1032 1033template <class Fx, bool = InvocableR<Fx>::value>1034void Help(Fx) {}1035 1036void Test() {1037 Help([](buff) {});1038}1039 1040}1041 1042#endif1043 1044 1045namespace GH67134 {1046template <int loc = std::source_location::current().line()>1047constexpr auto f(std::source_location loc2 = std::source_location::current()) { return loc; }1048 1049int g = []() -> decltype(f()) { return 0; }();1050 1051int call() {1052#if __cplusplus >= 202002L1053 return []<decltype(f()) = 0>() -> decltype(f()) { return 0; }();1054#endif1055 return []() -> decltype(f()) { return 0; }();1056}1057 1058#if __cplusplus >= 202002L1059template<typename T>1060int Var = requires { []() -> decltype(f()){}; };1061int h = Var<int>;1062#endif1063 1064 1065}1066 1067namespace GH119129 {1068struct X{1069 constexpr int foo(std::source_location loc = std::source_location::current()) {1070 return loc.line();1071 }1072};1073static_assert(X{}.foo() == __LINE__);1074static_assert(X{}.1075 foo() == __LINE__);1076static_assert(X{}.1077 1078 1079 foo() == __LINE__);1080#line 100001081static_assert(X{}.1082 foo() == 10001);1083}1084