The line is wrong, we should be stopped on line 9. As was the case in issue 48432, the problem is that the LF_FUNC_ID records for the specialization of foo and the foo template are identical. The linker merges identical LF_FUNC_ID records, and the LF_FUNC_ID index is used as a key in a map which maps from function id to the starting line number of the function.
However, MSVC has the same bug! If you follow the same steps, the debugger stops on line 4, but is otherwise no different:
Extended Description
This is similar to llvm.org/pr48432, but it's a corner case that deserves its own bug. Consider this program:
$ cat -n t.cpp 1 #include
2 volatile int gv;
3 template void foo() { gv += sizeof(T); }
4 // not here
5 // not here
6
7 template <> void foo() {
8 gv += 1;
9 __debugbreak();
10 }
11 int main() {
12 puts("asdf");
13 foo();
14 foo();
15 foo();
16 puts("asdf");
17 }
Compiled like so:
$ clang-cl -Z7 -O2 t.cpp
If you load it in windbg and run to the breakpoint, it stops on line 5, which is not in any function. See the stack trace:
0:000> k
Child-SP RetAddr Call Site
00 (Inline Function) --------
-------- t!foo+0xa [C:\src\llvm-project\build\t.cpp @ 5] 01 00000069
8deffda0 00007ff6`de54965c t!main+0x28 [C:\src\llvm-project\build\t.cpp @ 14] ...The line is wrong, we should be stopped on line 9. As was the case in issue 48432, the problem is that the LF_FUNC_ID records for the specialization of foo and the foo template are identical. The linker merges identical LF_FUNC_ID records, and the LF_FUNC_ID index is used as a key in a map which maps from function id to the starting line number of the function.
However, MSVC has the same bug! If you follow the same steps, the debugger stops on line 4, but is otherwise no different:
$ cl -O2 -Z7 t.cpp ... windbg... 0:000> k
Child-SP RetAddr Call Site
00 (Inline Function) --------
-------- t!foo+0xe [C:\src\llvm-project\build\t.cpp @ 4] 01 000000ae
507df750 00007ff7`28d56fb0 t!main+0x2d [C:\src\llvm-project\build\t.cpp @ 14]So, this is a bit of a corner case bug, and it may not be worth fixing. If we want to fix the bug, we would need to find a way to make the names of template specializations uniquely different from template instantiations. Right now we remove all template arguments here: https://github.com/llvm/llvm-project/blob/e090182fe153c9ceea50b1807f8ca5c13729e402/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp#L361
We do this to match MSVC, but if we adjust that logic, we could have unique names and the inlinee line map would work again.