https://gcc.gnu.org/bugzilla/show_bug.cgi?id=126233

            Bug ID: 126233
           Summary: source_location::current() in default template
                    argument produces garbage
           Product: gcc
           Version: 17.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: ivan.lazaric.gcc at gmail dot com
  Target Milestone: ---

```cpp
#include <format>
#include <source_location>

consteval bool check(std::source_location loc) {
  __builtin_constexpr_diag(0, "", std::format("line: {}", loc.line()));
  __builtin_constexpr_diag(0, "", std::format("function name: {}",
loc.function_name()));
  return true;
}

template<auto S = check(std::source_location::current())>
void fn() {}

int main() { fn(); }
```

Flags: "-std=c++26 -O3"

Compiler output:
```
<source>: In substitution of 'template<auto S> void fn() [with auto S =
<missing>]':
<source>:13:16:   required from here
   13 | int main() { fn(); }
      |              ~~^~
<source>:10:24:   in 'constexpr' expansion of
'check(std::source_location::current(__builtin_source_location()))'
   10 | template<auto S = check(std::source_location::current())>
      |                   ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:5:27: note: constexpr message: line: 10
    5 |   __builtin_constexpr_diag(0, "", std::format("line: {}", loc.line()));
      |   ~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:10:24:   in 'constexpr' expansion of
'check(std::source_location::current(__builtin_source_location()))'
   10 | template<auto S = check(std::source_location::current())>
      |                   ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:6:27: note: constexpr message: function name: int main()
    6 |   __builtin_constexpr_diag(0, "", std::format("function name: {}",
loc.function_name()));
      |  
~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
```

Of note are the following two lines:
```
<source>:5:27: note: constexpr message: line: 10
<source>:6:27: note: constexpr message: function name: int main()
```

This makes no sense because `main()` does not cross line 10, it is fully in
line 13.
It seems `source_location::current()` created a mixed object, 
with `line()` for the location of the default template argument,
and with `function_name()` for the location where we use the function template.

Noting this is unrelated to `__builtin_constexpr_diag()`, example without it:
```
#include <source_location>
#include <cassert>
#include <string_view>

consteval bool check(std::source_location loc) {
  assert(loc.line() == 11); // outside of main
  assert(std::string_view(loc.function_name()) == "int main()");
  return true;
}

template<auto S = check(std::source_location::current())>
void fn() {}

int main() { fn(); }
```

Godbolt of first example: https://godbolt.org/z/65cYM4q1G
Godbolt of second example: https://godbolt.org/z/YWzaa4aoY

Reply via email to