brintos

brintos / llvm-project-archived public Read only

0
0
Text · 30.0 KiB · c8b65d6 Raw
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