c++: Implement LWG3396 Clarify point of reference for source_location::current()...
[gcc.git] / gcc / testsuite / g++.dg / cpp2a / srcloc15.C
1 // { dg-do run { target c++20 } }
2
3 namespace std {
4 struct source_location {
5 struct __impl {
6 const char *_M_file_name;
7 const char *_M_function_name;
8 unsigned int _M_line, _M_column;
9 };
10 const __impl *__ptr;
11 constexpr source_location () : __ptr (nullptr) {}
12 static consteval source_location
13 current (const void *__p = __builtin_source_location ()) {
14 source_location __ret;
15 __ret.__ptr = static_cast <const __impl *> (__p);
16 return __ret;
17 }
18 constexpr const char *file_name () const {
19 return __ptr ? __ptr->_M_file_name : "";
20 }
21 constexpr const char *function_name () const {
22 return __ptr ? __ptr->_M_function_name : "";
23 }
24 constexpr unsigned line () const {
25 return __ptr ? __ptr->_M_line : 0;
26 }
27 constexpr unsigned column () const {
28 return __ptr ? __ptr->_M_column : 0;
29 }
30 };
31 }
32
33 using namespace std;
34
35 constexpr source_location
36 foo (const source_location x = source_location::current ())
37 {
38 return x;
39 }
40
41 struct S {
42 const char *func;
43 unsigned line = 0;
44 source_location loc = source_location::current ();
45
46 constexpr S (int l, source_location loc = source_location::current ())
47 : func(__FUNCTION__), line(l), loc(loc)
48 {}
49
50 constexpr S (double)
51 : func(__FUNCTION__), line(__LINE__)
52 // ^ column 38
53 {}
54 };
55
56 constexpr bool
57 cmp (const char *p, const char *q)
58 {
59 for (; *p && *q; p++, q++)
60 if (*p != *q)
61 return true;
62 return *p || *q;
63 }
64
65 constexpr bool
66 bar ()
67 {
68 int line = __LINE__;
69 source_location a = foo ();
70 source_location b = source_location::current ();
71 source_location c = foo ();
72 // ^ column 28
73 // ^ column 49
74 const source_location *d[3] = { &a, &b, &c };
75 const char *file1 = __FILE__;
76 const char *function1 = __FUNCTION__;
77 for (int j = 0; j < 3; j++)
78 {
79 int i= 0;
80 if (cmp (d[j]->file_name (), file1))
81 return false;
82 if (cmp (d[j]->function_name (), function1))
83 return false;
84 if (d[j]->line () != line + j + 1)
85 return false;
86 if (d[j]->column () != (j == 1 ? 49 : 28))
87 return false;
88 }
89
90 S e = __LINE__;
91 // ^ column 9
92 S f = 1.0;
93 if (cmp (e.loc.file_name (), file1))
94 return false;
95 if (cmp (f.loc.file_name (), file1))
96 return false;
97 if (cmp (e.loc.function_name (), function1))
98 return false;
99 if (cmp (f.loc.function_name (), f.func))
100 return false;
101 if (e.loc.line () != e.line)
102 return false;
103 if (f.loc.line () != f.line)
104 return false;
105 if (e.loc.column () != 9)
106 return false;
107 if (f.loc.column () != 38)
108 return false;
109 return true;
110 }
111
112 static_assert (bar ());
113
114 int
115 main ()
116 {
117 if (!bar ())
118 __builtin_abort ();
119 }