1*d6148749SJames Y Knight // RUN: %clang_cc1 -std=c++1z -fcxx-exceptions -fexceptions -verify -DTEST=1 %s 2*d6148749SJames Y Knight // RUN: %clang_cc1 -std=c++1z -fcxx-exceptions -fexceptions -verify -DTEST=2 %s 3*d6148749SJames Y Knight // RUN: %clang_cc1 -std=c++1z -fcxx-exceptions -fexceptions -verify -DTEST=3 %s 4*d6148749SJames Y Knight // RUN: %clang_cc1 -std=c++1z -fcxx-exceptions -fexceptions -verify -DTEST=4 %s 5*d6148749SJames Y Knight // RUN: %clang_cc1 -std=c++1z -fcxx-exceptions -fexceptions -verify -DTEST=5 %s 6*d6148749SJames Y Knight 7*d6148749SJames Y Knight #if TEST == 1 8*d6148749SJames Y Knight auto test1a = __builtin_source_location(); // expected-error {{'std::source_location::__impl' was not found}} 9*d6148749SJames Y Knight 10*d6148749SJames Y Knight namespace std { 11*d6148749SJames Y Knight inline namespace NS { 12*d6148749SJames Y Knight struct source_location; 13*d6148749SJames Y Knight } 14*d6148749SJames Y Knight } 15*d6148749SJames Y Knight 16*d6148749SJames Y Knight auto test1b = __builtin_source_location(); // expected-error {{'std::source_location::__impl' was not found}} 17*d6148749SJames Y Knight 18*d6148749SJames Y Knight namespace std { 19*d6148749SJames Y Knight inline namespace NS { 20*d6148749SJames Y Knight struct source_location { 21*d6148749SJames Y Knight struct __impl; 22*d6148749SJames Y Knight }; 23*d6148749SJames Y Knight } 24*d6148749SJames Y Knight } 25*d6148749SJames Y Knight auto test1c = __builtin_source_location(); // expected-error {{'std::source_location::__impl' was not found}} 26*d6148749SJames Y Knight 27*d6148749SJames Y Knight #elif TEST == 2 28*d6148749SJames Y Knight auto test2a = __builtin_source_location(); // expected-error {{'std::source_location::__impl' was not found}} 29*d6148749SJames Y Knight 30*d6148749SJames Y Knight namespace std { 31*d6148749SJames Y Knight inline namespace NS { 32*d6148749SJames Y Knight struct source_location { 33*d6148749SJames Y Knight struct __impl { int x; }; 34*d6148749SJames Y Knight }; 35*d6148749SJames Y Knight } 36*d6148749SJames Y Knight } 37*d6148749SJames Y Knight auto test2b = __builtin_source_location(); // expected-error {{'std::source_location::__impl' must be standard-layout and have only two 'const char *' fields '_M_file_name' and '_M_function_name', and two integral fields '_M_line' and '_M_column'}} 38*d6148749SJames Y Knight 39*d6148749SJames Y Knight #elif TEST == 3 40*d6148749SJames Y Knight namespace std { 41*d6148749SJames Y Knight struct source_location { 42*d6148749SJames Y Knight struct __impl { 43*d6148749SJames Y Knight int other_member; 44*d6148749SJames Y Knight char _M_line; 45*d6148749SJames Y Knight const char *_M_file_name; 46*d6148749SJames Y Knight char _M_column; 47*d6148749SJames Y Knight const char *_M_function_name; 48*d6148749SJames Y Knight }; 49*d6148749SJames Y Knight }; 50*d6148749SJames Y Knight } 51*d6148749SJames Y Knight auto test3 = __builtin_source_location(); // expected-error {{'std::source_location::__impl' must be standard-layout and have only two 'const char *' fields '_M_file_name' and '_M_function_name', and two integral fields '_M_line' and '_M_column'}} 52*d6148749SJames Y Knight 53*d6148749SJames Y Knight #elif TEST == 4 54*d6148749SJames Y Knight namespace std { 55*d6148749SJames Y Knight struct source_location { 56*d6148749SJames Y Knight struct parent {}; 57*d6148749SJames Y Knight struct __impl : public parent { 58*d6148749SJames Y Knight char _M_line; 59*d6148749SJames Y Knight const char *_M_file_name; 60*d6148749SJames Y Knight char _M_column; 61*d6148749SJames Y Knight const char *_M_function_name; 62*d6148749SJames Y Knight }; 63*d6148749SJames Y Knight }; 64*d6148749SJames Y Knight } 65*d6148749SJames Y Knight auto test4 = __builtin_source_location(); // expected-error {{'std::source_location::__impl' must be standard-layout and have only two 'const char *' fields '_M_file_name' and '_M_function_name', and two integral fields '_M_line' and '_M_column'}} 66*d6148749SJames Y Knight 67*d6148749SJames Y Knight 68*d6148749SJames Y Knight #elif TEST == 5 69*d6148749SJames Y Knight namespace std { 70*d6148749SJames Y Knight struct source_location { 71*d6148749SJames Y Knight struct __impl { 72*d6148749SJames Y Knight signed char _M_line; // odd integral type to choose, but ok! 73*d6148749SJames Y Knight const char *_M_file_name; 74*d6148749SJames Y Knight signed char _M_column; 75*d6148749SJames Y Knight const char *_M_function_name; 76*d6148749SJames Y Knight static int other_member; // static members are OK 77*d6148749SJames Y Knight }; 78*d6148749SJames Y Knight using BuiltinT = decltype(__builtin_source_location()); // OK. 79*d6148749SJames Y Knight }; 80*d6148749SJames Y Knight } 81*d6148749SJames Y Knight 82*d6148749SJames Y Knight // Verify that the address cannot be used as a non-type template argument. 83*d6148749SJames Y Knight template <auto X = __builtin_source_location()> fn1()84*d6148749SJames Y Knightauto fn1() {return X;} // expected-note {{candidate template ignored: substitution failure: non-type template argument does not refer to any declaration}} 85*d6148749SJames Y Knight auto test5a = fn1<>(); // expected-error {{no matching function for call to 'fn1'}} 86*d6148749SJames Y Knight 87*d6148749SJames Y Knight // (But using integer subobjects by value is okay.) 88*d6148749SJames Y Knight template <auto X = __builtin_source_location()->_M_column> fn2()89*d6148749SJames Y Knightauto fn2() {return X;} 90*d6148749SJames Y Knight auto test5b = fn2<>(); 91*d6148749SJames Y Knight 92*d6148749SJames Y Knight // While it's not semantically required, for efficiency, we ensure that two 93*d6148749SJames Y Knight // source-locations with the same content will point to the same object. Given 94*d6148749SJames Y Knight // the odd definition of the struct used here (using 'signed char'), any 95*d6148749SJames Y Knight // line-number modulo 256 will thus have the same content, and be deduplicated. 96*d6148749SJames Y Knight #line 128 97*d6148749SJames Y Knight constexpr auto sl1 = __builtin_source_location(); 98*d6148749SJames Y Knight #line 384 99*d6148749SJames Y Knight constexpr auto sl2 = __builtin_source_location(); 100*d6148749SJames Y Knight constexpr auto sl3 = __builtin_source_location(); 101*d6148749SJames Y Knight static_assert(sl1 == sl2); 102*d6148749SJames Y Knight static_assert(sl1 != sl3); 103*d6148749SJames Y Knight static_assert(sl1->_M_line == -128); 104*d6148749SJames Y Knight 105*d6148749SJames Y Knight #endif 106