1 // RUN: %clang_cc1 -std=c++1z -fcxx-exceptions -fexceptions -verify %s
2 // expected-no-diagnostics
3 
4 #define assert(...) ((__VA_ARGS__) ? ((void)0) : throw 42)
5 #define CURRENT_FROM_MACRO() SL::current()
6 #define FORWARD(...) __VA_ARGS__
7 
8 template <unsigned>
9 struct Printer;
10 
11 namespace std {
12 class source_location {
13   struct __impl;
14 
15 public:
current(const __impl * __p=__builtin_source_location ())16   static constexpr source_location current(const __impl *__p = __builtin_source_location()) noexcept {
17     source_location __loc;
18     __loc.__m_impl = __p;
19     return __loc;
20   }
21   constexpr source_location() = default;
22   constexpr source_location(source_location const &) = default;
line() const23   constexpr unsigned int line() const noexcept { return __m_impl ? __m_impl->_M_line : 0; }
column() const24   constexpr unsigned int column() const noexcept { return __m_impl ? __m_impl->_M_column : 0; }
file() const25   constexpr const char *file() const noexcept { return __m_impl ? __m_impl->_M_file_name : ""; }
function() const26   constexpr const char *function() const noexcept { return __m_impl ? __m_impl->_M_function_name : ""; }
27 
28 private:
29   // Note: The type name "std::source_location::__impl", and its constituent
30   // field-names are required by __builtin_source_location().
31   struct __impl {
32     const char *_M_file_name;
33     const char *_M_function_name;
34     unsigned _M_line;
35     unsigned _M_column;
36   };
37   const __impl *__m_impl = nullptr;
38 
39 public:
40   using public_impl_alias = __impl;
41 };
42 } // namespace std
43 
44 using SL = std::source_location;
45 
46 #include "Inputs/source-location-file.h"
47 namespace SLF = source_location_file;
48 
is_equal(const char * LHS,const char * RHS)49 constexpr bool is_equal(const char *LHS, const char *RHS) {
50   while (*LHS != 0 && *RHS != 0) {
51     if (*LHS != *RHS)
52       return false;
53     ++LHS;
54     ++RHS;
55   }
56   return *LHS == 0 && *RHS == 0;
57 }
58 
59 template <class T>
identity(T t)60 constexpr T identity(T t) {
61   return t;
62 }
63 
64 template <class T, class U>
65 struct Pair {
66   T first;
67   U second;
68 };
69 
70 template <class T, class U>
71 constexpr bool is_same = false;
72 template <class T>
73 constexpr bool is_same<T, T> = true;
74 
75 // test types
76 static_assert(is_same<decltype(__builtin_LINE()), unsigned>);
77 static_assert(is_same<decltype(__builtin_COLUMN()), unsigned>);
78 static_assert(is_same<decltype(__builtin_FILE()), const char *>);
79 static_assert(is_same<decltype(__builtin_FUNCTION()), const char *>);
80 static_assert(is_same<decltype(__builtin_source_location()), const std::source_location::public_impl_alias *>);
81 
82 // test noexcept
83 static_assert(noexcept(__builtin_LINE()));
84 static_assert(noexcept(__builtin_COLUMN()));
85 static_assert(noexcept(__builtin_FILE()));
86 static_assert(noexcept(__builtin_FUNCTION()));
87 static_assert(noexcept(__builtin_source_location()));
88 
89 //===----------------------------------------------------------------------===//
90 //                            __builtin_LINE()
91 //===----------------------------------------------------------------------===//
92 
93 namespace test_line {
94 static_assert(SL::current().line() == __LINE__);
95 static_assert(SL::current().line() == CURRENT_FROM_MACRO().line());
96 
97 static constexpr SL GlobalS = SL::current();
98 
99 static_assert(GlobalS.line() == __LINE__ - 2);
100 
101 // clang-format off
test_line_fn()102 constexpr bool test_line_fn() {
103   constexpr SL S = SL::current();
104   static_assert(S.line() == (__LINE__ - 1), "");
105   // The start of the call expression to `current()` begins at the token `SL`
106   constexpr int ExpectLine = __LINE__ + 3;
107   constexpr SL S2
108   =
109   SL // Call expression starts here
110   ::
111   current
112   (
113 
114   )
115   ;
116   static_assert(S2.line() == ExpectLine, "");
117 
118   static_assert(
119           FORWARD(
120              __builtin_LINE
121             (
122             )
123           )
124     == __LINE__ - 1, "");
125   static_assert(\
126 \
127   __builtin_LINE()\
128 \
129   == __LINE__ - 2, "");
130   static_assert(\
131           _\
132 _builtin_LINE()
133           == __LINE__ - 2, "");
134 
135   return true;
136 }
137 // clang-format on
138 static_assert(test_line_fn());
139 
140 static_assert(__builtin_LINE() == __LINE__, "");
141 
baz()142 constexpr int baz() { return 101; }
143 
test_line_fn_simple(int z=baz (),int x=__builtin_LINE ())144 constexpr int test_line_fn_simple(int z = baz(), int x = __builtin_LINE()) {
145   return x;
146 }
bar()147 void bar() {
148   static_assert(test_line_fn_simple() == __LINE__, "");
149   static_assert(test_line_fn_simple() == __LINE__, "");
150 }
151 
152 struct CallExpr {
operator ()test_line::CallExpr153   constexpr int operator()(int x = __builtin_LINE()) const { return x; }
154 };
get_call()155 constexpr CallExpr get_call() { return CallExpr{}; }
156 static_assert(get_call()() == __LINE__, "");
157 
158 template <class T>
test_line_fn_template(T Expect,int L=__builtin_LINE ())159 constexpr bool test_line_fn_template(T Expect, int L = __builtin_LINE()) {
160   return Expect == L;
161 }
162 static_assert(test_line_fn_template(__LINE__));
163 
164 struct InMemInit {
checktest_line::InMemInit165   constexpr bool check(int expect) const {
166     return info.line() == expect;
167   }
168   SL info = SL::current();
169   InMemInit() = default;
InMemInittest_line::InMemInit170   constexpr InMemInit(int) {}
171 };
172 static_assert(InMemInit{}.check(__LINE__ - 3), "");
173 static_assert(InMemInit{42}.check(__LINE__ - 3), "");
174 
175 template <class T, class U = SL>
176 struct InMemInitTemplate {
checktest_line::InMemInitTemplate177   constexpr bool check(int expect) const {
178     return info.line() == expect;
179   }
180   U info = U::current();
181   InMemInitTemplate() = default;
InMemInitTemplatetest_line::InMemInitTemplate182   constexpr InMemInitTemplate(T) {}
InMemInitTemplatetest_line::InMemInitTemplate183   constexpr InMemInitTemplate(T, T) : info(U::current()) {}
InMemInitTemplatetest_line::InMemInitTemplate184   template <class V = U> constexpr InMemInitTemplate(T, T, T, V info = U::current())
185       : info(info) {}
186 };
test_mem_init_template()187 void test_mem_init_template() {
188   constexpr int line_offset = 8;
189   static_assert(InMemInitTemplate<int>{}.check(__LINE__ - line_offset), "");
190   static_assert(InMemInitTemplate<unsigned>{42}.check(__LINE__ - line_offset), "");
191   static_assert(InMemInitTemplate<unsigned>{42, 42}.check(__LINE__ - line_offset), "");
192   static_assert(InMemInitTemplate<unsigned>{42, 42, 42}.check(__LINE__), "");
193 }
194 
195 struct AggInit {
196   int x;
197   int y = __builtin_LINE();
checktest_line::AggInit198   constexpr bool check(int expect) const {
199     return y == expect;
200   }
201 };
202 constexpr AggInit AI{42};
203 static_assert(AI.check(__LINE__ - 1), "");
204 
205 template <class T, class U = SL>
206 struct AggInitTemplate {
checktest_line::AggInitTemplate207   constexpr bool check(int expect) const {
208     return expect == info.line();
209   }
210   T x;
211   U info = U::current();
212 };
213 
214 template <class T, class U = SL>
test_fn_template(T,U u=U::current ())215 constexpr U test_fn_template(T, U u = U::current()) {
216   return u;
217 }
fn_template_tests()218 void fn_template_tests() {
219   static_assert(test_fn_template(42).line() == __LINE__, "");
220 }
221 
222 struct TestMethodTemplate {
223   template <class T, class U = SL, class U2 = SL>
gettest_line::TestMethodTemplate224   constexpr U get(T, U u = U::current(), U2 u2 = identity(U2::current())) const {
225     assert(u.line() == u2.line());
226     return u;
227   }
228 };
method_template_tests()229 void method_template_tests() {
230   static_assert(TestMethodTemplate{}.get(42).line() == __LINE__, "");
231 }
232 
233 struct InStaticInit {
234   static constexpr int LINE = __LINE__;
235   static constexpr const int x1 = __builtin_LINE();
236   static constexpr const int x2 = identity(__builtin_LINE());
237   static const int x3;
238   const int x4 = __builtin_LINE();
239   int x5 = __builtin_LINE();
240 };
241 const int InStaticInit::x3 = __builtin_LINE();
242 static_assert(InStaticInit::x1 == InStaticInit::LINE + 1, "");
243 static_assert(InStaticInit::x2 == InStaticInit::LINE + 2, "");
244 
245 template <class T, int N = __builtin_LINE(), int Expect = -1>
check_fn_template_param(T)246 constexpr void check_fn_template_param(T) {
247   constexpr int RealExpect = Expect == -1 ? __LINE__ - 2 : Expect;
248   static_assert(N == RealExpect);
249 }
250 template void check_fn_template_param(int);
251 template void check_fn_template_param<long, 42, 42>(long);
252 
253 #line 100
254 struct AggBase {
255 #line 200
256   int x = __builtin_LINE();
257   int y = __builtin_LINE();
258   int z = __builtin_LINE();
259 };
260 #line 300
261 struct AggDer : AggBase {
262 };
263 #line 400
264 static_assert(AggDer{}.x == 400, "");
265 
266 struct ClassBase {
267 #line 400
268   int x = __builtin_LINE();
269   int y = 0;
270   int z = 0;
271 #line 500
272   ClassBase() = default;
ClassBasetest_line::ClassBase273   constexpr ClassBase(int yy, int zz = __builtin_LINE())
274       : y(yy), z(zz) {}
275 };
276 struct ClassDer : ClassBase {
277 #line 600
278   ClassDer() = default;
ClassDertest_line::ClassDer279   constexpr ClassDer(int yy) : ClassBase(yy) {}
ClassDertest_line::ClassDer280   constexpr ClassDer(int yy, int zz) : ClassBase(yy, zz) {}
281 };
282 #line 700
283 static_assert(ClassDer{}.x == 500, "");
284 static_assert(ClassDer{42}.x == 501, "");
285 static_assert(ClassDer{42}.z == 601, "");
286 static_assert(ClassDer{42, 42}.x == 501, "");
287 
288 struct ClassAggDer : AggBase {
289 #line 800
290   ClassAggDer() = default;
ClassAggDertest_line::ClassAggDer291   constexpr ClassAggDer(int, int x = __builtin_LINE()) : AggBase{x} {}
292 };
293 static_assert(ClassAggDer{}.x == 100, "");
294 
295 } // namespace test_line
296 
297 //===----------------------------------------------------------------------===//
298 //                            __builtin_FILE()
299 //===----------------------------------------------------------------------===//
300 
301 namespace test_file {
test_file_simple(const char * __f=__builtin_FILE ())302 constexpr const char *test_file_simple(const char *__f = __builtin_FILE()) {
303   return __f;
304 }
test_function()305 void test_function() {
306 #line 900
307   static_assert(is_equal(test_file_simple(), __FILE__));
308   static_assert(is_equal(SLF::test_function().file(), __FILE__), "");
309   static_assert(is_equal(SLF::test_function_template(42).file(), __FILE__), "");
310 
311   static_assert(is_equal(SLF::test_function_indirect().file(), SLF::global_info.file()), "");
312   static_assert(is_equal(SLF::test_function_template_indirect(42).file(), SLF::global_info.file()), "");
313 
314   static_assert(test_file_simple() != nullptr);
315   static_assert(!is_equal(test_file_simple(), "source_location.cpp"));
316 }
317 
test_class()318 void test_class() {
319 #line 315
320   using SLF::TestClass;
321   constexpr TestClass Default;
322   constexpr TestClass InParam{42};
323   constexpr TestClass Template{42, 42};
324   constexpr auto *F = Default.info.file();
325   constexpr auto Char = F[0];
326   static_assert(is_equal(Default.info.file(), SLF::FILE), "");
327   static_assert(is_equal(InParam.info.file(), SLF::FILE), "");
328   static_assert(is_equal(InParam.ctor_info.file(), __FILE__), "");
329 }
330 
test_aggr_class()331 void test_aggr_class() {
332   using Agg = SLF::AggrClass<>;
333   constexpr Agg Default{};
334   constexpr Agg InitOne{42};
335   static_assert(is_equal(Default.init_info.file(), __FILE__), "");
336   static_assert(is_equal(InitOne.init_info.file(), __FILE__), "");
337 }
338 
339 } // namespace test_file
340 
341 //===----------------------------------------------------------------------===//
342 //                            __builtin_FUNCTION()
343 //===----------------------------------------------------------------------===//
344 
345 namespace test_func {
346 
test_func_simple(const char * __f=__builtin_FUNCTION ())347 constexpr const char *test_func_simple(const char *__f = __builtin_FUNCTION()) {
348   return __f;
349 }
get_function()350 constexpr const char *get_function() {
351   return __func__;
352 }
test_function()353 constexpr bool test_function() {
354   return is_equal(__func__, test_func_simple()) &&
355          !is_equal(get_function(), test_func_simple());
356 }
357 static_assert(test_function());
358 
359 template <class T, class U = SL>
test_func_template(T,U u=U::current ())360 constexpr Pair<U, U> test_func_template(T, U u = U::current()) {
361   static_assert(is_equal(__PRETTY_FUNCTION__, U::current().function()));
362   return {u, U::current()};
363 }
364 template <class T>
func_template_tests()365 void func_template_tests() {
366   constexpr auto P = test_func_template(42);
367   //static_assert(is_equal(P.first.function(), __func__), "");
368   //static_assert(!is_equal(P.second.function(), __func__), "");
369 }
370 template void func_template_tests<int>();
371 
372 template <class = int, class T = SL>
373 struct TestCtor {
374   T info = T::current();
375   T ctor_info;
376   TestCtor() = default;
377   template <class U = SL>
TestCtortest_func::TestCtor378   constexpr TestCtor(int, U u = U::current()) : ctor_info(u) {}
379 };
ctor_tests()380 void ctor_tests() {
381   constexpr TestCtor<> Default;
382   constexpr TestCtor<> Template{42};
383   static const char *XYZZY = Template.info.function();
384   static_assert(is_equal(Default.info.function(), "test_func::TestCtor<>::TestCtor() [T = std::source_location]"));
385   static_assert(is_equal(Default.ctor_info.function(), ""));
386   static_assert(is_equal(Template.info.function(), "test_func::TestCtor<>::TestCtor(int, U) [T = std::source_location, U = std::source_location]"));
387   static_assert(is_equal(Template.ctor_info.function(), __PRETTY_FUNCTION__));
388 }
389 
390 constexpr SL global_sl = SL::current();
391 static_assert(is_equal(global_sl.function(), ""));
392 
393 } // namespace test_func
394 
395 //===----------------------------------------------------------------------===//
396 //                            __builtin_COLUMN()
397 //===----------------------------------------------------------------------===//
398 
399 namespace test_column {
400 
401 // clang-format off
test_column_fn()402 constexpr bool test_column_fn() {
403   constexpr SL S = SL::current();
404   static_assert(S.line() == (__LINE__ - 1), "");
405   constexpr int Indent = 4;
406   {
407     // The start of the call expression to `current()` begins at the token `SL`
408     constexpr int ExpectCol = Indent + 3;
409     constexpr SL S2
410      =
411       SL // Call expression starts here
412         ::
413           current
414                  (
415 
416                   )
417                    ;
418     static_assert(S2.column() == ExpectCol, "");
419   }
420   {
421     constexpr int ExpectCol = 2;
422     constexpr int C =
423  __builtin_COLUMN // Expect call expression to start here
424       ();
425     static_assert(C == ExpectCol);
426   }
427   return true;
428 }
429 #line 420
430 static_assert(test_column_fn());
431 
432 // Test that the column matches the start of the call expression 'SL::current()'
433 static_assert(SL::current().column() == __builtin_strlen("static_assert(S"));
434 struct TestClass {
435   int x = __builtin_COLUMN();
436    TestClass() = default; /* indented to 3 spaces for testing */
TestClasstest_column::TestClass437   constexpr TestClass(int, int o = __builtin_COLUMN()) : x(o) {}
438 };
439 struct TestAggClass {
440   int x = __builtin_COLUMN();
441 };
test_class()442 constexpr bool test_class() {
443 
444   auto check = [](int V, const char* S, int indent = 4) {
445     assert(V == (__builtin_strlen(S) + indent));
446   };
447   {
448     TestClass t{};
449     check(t.x, "   T", 0); // Start of default constructor decl.
450   }
451   {
452     TestClass t1
453             {42};
454     check(t1.x, "TestClass t"); // Start of variable being constructed.
455   }
456   {
457     TestAggClass t  { };
458     check(t.x, "TestAggClass t  { }");
459   }
460   {
461     TestAggClass t = { };
462     check(t.x, "TestAggClass t = { }");
463   }
464   return true;
465 }
466 static_assert(test_class());
467 // clang-format on
468 } // namespace test_column
469 
470 // Test [reflection.src_loc.creation]p2
471 //  >  The value should be affected by #line (C++14 16.4) in the same manner as
472 //  >  for __LINE__ and __FILE__.
473 namespace test_pragma_line {
474 constexpr int StartLine = 42;
475 #line 42
476 static_assert(__builtin_LINE() == StartLine);
477 static_assert(__builtin_LINE() == StartLine + 1);
478 static_assert(SL::current().line() == StartLine + 2);
479 #line 44 "test_file.c"
480 static_assert(is_equal("test_file.c", __FILE__));
481 static_assert(is_equal("test_file.c", __builtin_FILE()));
482 static_assert(is_equal("test_file.c", SL::current().file()));
483 static_assert(is_equal("test_file.c", SLF::test_function().file()));
484 static_assert(is_equal(SLF::FILE, SLF::test_function_indirect().file()));
485 } // end namespace test_pragma_line
486 
487 namespace test_out_of_line_init {
488 #line 4000 "test_out_of_line_init.cpp"
get_line(unsigned n=__builtin_LINE ())489 constexpr unsigned get_line(unsigned n = __builtin_LINE()) { return n; }
get_file(const char * f=__builtin_FILE ())490 constexpr const char *get_file(const char *f = __builtin_FILE()) { return f; }
get_func(const char * f=__builtin_FUNCTION ())491 constexpr const char *get_func(const char *f = __builtin_FUNCTION()) { return f; }
492 #line 4100 "A.cpp"
493 struct A {
494   int n = __builtin_LINE();
495   int n2 = get_line();
496   const char *f = __builtin_FILE();
497   const char *f2 = get_file();
498   const char *func = __builtin_FUNCTION();
499   const char *func2 = get_func();
500   SL info = SL::current();
501 };
502 #line 4200 "B.cpp"
503 struct B {
504   A a = {};
505 };
506 #line 4300 "test_passed.cpp"
507 constexpr B b = {};
508 static_assert(b.a.n == 4300, "");
509 static_assert(b.a.n2 == 4300, "");
510 static_assert(b.a.info.line() == 4300, "");
511 static_assert(is_equal(b.a.f, "test_passed.cpp"));
512 static_assert(is_equal(b.a.f2, "test_passed.cpp"));
513 static_assert(is_equal(b.a.info.file(), "test_passed.cpp"));
514 static_assert(is_equal(b.a.func, ""));
515 static_assert(is_equal(b.a.func2, ""));
516 static_assert(is_equal(b.a.info.function(), ""));
517 
test_in_func()518 constexpr bool test_in_func() {
519 #line 4400 "test_func_passed.cpp"
520   constexpr B b = {};
521   static_assert(b.a.n == 4400, "");
522   static_assert(b.a.n2 == 4400, "");
523   static_assert(b.a.info.line() == 4400, "");
524   static_assert(is_equal(b.a.f, "test_func_passed.cpp"));
525   static_assert(is_equal(b.a.f2, "test_func_passed.cpp"));
526   static_assert(is_equal(b.a.info.file(), "test_func_passed.cpp"));
527   static_assert(is_equal(b.a.func, "test_in_func"));
528   static_assert(is_equal(b.a.func2, "test_in_func"));
529   static_assert(is_equal(b.a.info.function(), "bool test_out_of_line_init::test_in_func()"));
530   return true;
531 }
532 static_assert(test_in_func());
533 
534 } // end namespace test_out_of_line_init
535 
536 namespace test_global_scope {
537 #line 5000 "test_global_scope.cpp"
get_line(unsigned n=__builtin_LINE ())538 constexpr unsigned get_line(unsigned n = __builtin_LINE()) { return n; }
get_file(const char * f=__builtin_FILE ())539 constexpr const char *get_file(const char *f = __builtin_FILE()) { return f; }
get_func(const char * f=__builtin_FUNCTION ())540 constexpr const char *get_func(const char *f = __builtin_FUNCTION()) { return f; }
541 #line 5100
542 struct InInit {
543   unsigned l = get_line();
544   const char *f = get_file();
545   const char *func = get_func();
546 
547 #line 5200 "in_init.cpp"
InInittest_global_scope::InInit548   constexpr InInit() {}
549 };
550 #line 5300
551 constexpr InInit II;
552 
553 static_assert(II.l == 5200, "");
554 static_assert(is_equal(II.f, "in_init.cpp"));
555 static_assert(is_equal(II.func, "InInit"));
556 
557 #line 5400
558 struct AggInit {
559   unsigned l = get_line();
560   const char *f = get_file();
561   const char *func = get_func();
562 };
563 #line 5500 "brace_init.cpp"
564 constexpr AggInit AI = {};
565 static_assert(AI.l == 5500);
566 static_assert(is_equal(AI.f, "brace_init.cpp"));
567 static_assert(is_equal(AI.func, ""));
568 
569 } // namespace test_global_scope
570 
571 namespace TestFuncInInit {
572 #line 6000 "InitClass.cpp"
573 struct Init {
574   SL info;
575 #line 6100 "InitCtor.cpp"
InitTestFuncInInit::Init576   constexpr Init(SL info = SL::current()) : info(info) {}
577 };
578 #line 6200 "InitGlobal.cpp"
579 constexpr Init I;
580 static_assert(I.info.line() == 6200);
581 static_assert(is_equal(I.info.file(), "InitGlobal.cpp"));
582 
583 } // namespace TestFuncInInit
584 
585 namespace TestConstexprContext {
586 #line 7000 "TestConstexprContext.cpp"
foo()587   constexpr const char* foo() { return __builtin_FILE(); }
588 #line 7100 "Bar.cpp"
bar(const char * x=foo ())589   constexpr const char* bar(const char* x = foo()) { return x; }
test()590   constexpr bool test() {
591     static_assert(is_equal(bar(), "TestConstexprContext.cpp"));
592     return true;
593   }
594   static_assert(test());
595 }
596