<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/106422>106422</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            LTO produces bogus call-site debug info
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            wrong-debug,
            debuginfo,
            LTO
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          pogo59
      </td>
    </tr>
</table>

<pre>
    While poking around looking at something else, I tripped over this. A
set of files compiled without LTO has perfectly reasonable debug info,
in particular "main" shows a call-site for calling "foo" and one for
"printf". The info for "foo" shows a call-site for calling
"A::Method1". All totally good.

But when built with LTO, we're able to inline "foo" into "main", and
something gets messed up. "main" shows a DW_TAG_inlined_subroutine for
"foo" followed by 3 call-sites like so:

```
0x000000a2:     DW_TAG_call_site
 DW_AT_call_origin      (0x000000b5)
 DW_AT_call_return_pc   (0x00000000000016fb)

0x000000a8: DW_TAG_call_site
                  DW_AT_call_origin     (0x000000b6 "printf")
 DW_AT_call_return_pc   (0x000000000000170b)

0x000000ae: DW_TAG_call_site
                  DW_AT_call_origin     (0x000000b5)
 DW_AT_call_return_pc   (0x0000000000001715)

0x000000b4: NULL

0x000000b5:   DW_TAG_subprogram

0x000000b6: DW_TAG_subprogram
                DW_AT_name      ("printf")
 DW_AT_decl_file        ("/usr/include/stdio.h")
 DW_AT_decl_line        (356)
                DW_AT_type      (0x0000005a "int")
                DW_AT_declaration       (true)
 DW_AT_external (true)

```
Two call-sites pointing to a DW_TAG_subprogram that is... empty??

The call-site for "printf" shows that we are perfectly capable of
emitting a call-site that points to a declaration DIE. My guess is
that LTO is throwing something away that we don't want thrown away,
but because it's gone we end up with the bizarre attribute-free
subprogram DIE.

Because it's LTO, the repro requires multiple files.

```
// ----- 8< -----
// header.h
struct A {
  int Method1(int);
  int Method2(int);
};
int foo();
// ----- 8< -----
// header.cpp
#include "header.h"

__attribute__((noinline))
int A::Method1(int x) {
 return 5 + x;
}

int A::Method2(int x) {
  return 6 + x;
}

extern A a;

int foo() {
  return a.Method1(2);
}
// ----- 8< -----
// main.cpp
#include "header.h"
#include <stdio.h>

A a;

int main() {
 printf("%d\n", foo());
  return a.Method1(3) + a.Method2(4);
}
// ----- 8< -----
# Define CLANG and LLD to point to your build, then execute:
$CLANG -I. -O2 -g -fuse-ld=$LLD main.cpp header.cpp  -o normal.elf
$CLANG -I. -O2 -g -fuse-ld=$LLD main.cpp header.cpp  -o lto.elf -flto
# and dump the debug info for the two files.
```

</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJysV81u27wSfRp6M7BgUf5deOHEdVEgbTe56NKgpJHEW5rUJYd1fJ_-AynZlhMnX1FUMBKLHB6eOSTP0MI5WWvENZs9sNl2JDw1xq5bU5vZapSb8rT-0UiF0JqfUtcgrPG6BGX6VwJnDkhNeEHlkPFH-AJkZdtiCeYXWqBGugQ2bLJlk41DAlNBJRU6KMyhlQpLOEpqjCd4ev4OjXDQoq2wIHUCi8IZLXKFUGLua5C6Mow_dmhSQyssycIrYYFxfhBSM87BNeboQEAhlBo7SQiVsfEtEGWcV8aEOKFLMDr2doiM89ZKTRXjPIHnBuOEcfR11IfoF5wNy8LnK1JjyjTibZQCMiSUOkFtTJn0wfHvgyc4Nqgh91JR1CQIEhQ9IuMLixB1IANSK6lxwEhqMoP8wxihy17yywLVSA4O6ByW4NvknmDbH_vnzed9N0G5dz63xpN8JVE_a2WUMkcsIT9BdlXDgZI_EZwJAgwSZPNJ_4mvk5dJfARn2QbC008egPYBqIsLzZvnrtVYWUvNJivGl-fx-Yzx1dtQi-St3rfFbXT3pPMqv4x6RWcZ6LxD5c3zb9zmMNxRf0B0MXmXKP5Non8i4iKdvcMtnwZu3_7z9HS3d9ateM_d-by1prbicDd4Pkjzdej9LLU4YEf4I_FLLNQ-GNEllPGdd5bxndSF8iUyvnNUSpM07w0Pp6Qbns3m14i7rOjU4q2MMxF2h9R0A393cJhNWEHS9AtH1uNrSvhCaLVQdyLunsDnoxme2tZITcEnyFyd4Ko4UCMIpEuSBPDQ0ollu_AZ4Ae_vDXF4QL0JhNhjgjC4sDoC9FGdzNVB4UHSZHM0Gbj0EjTdSQHssD2y6cEvp6g9ugcSNfhxCGhrsgwszXHgHm1RHEUpwuj0mjGFwRHoakL1jHgUm9yT5BjIbxDkMT4wkEdyscRAXXw1M61qUHI5f-FDZZNZGXuCceVxf50DjQNpG-KwC167_8B0GJrDVj8n5cWHRy8Itkq7Epp8sEqM75jfAfj8MCSZY_d15vOBkWJNml6fmR9QbABtng4b0qpCS6lbBn37Ipld7r522622F6-h8BYPpY3Eb_PsWjbc3PWn9Owyy4ZcD7UYr-_LMB-HyddatNVtzD_-XgEVq_rdcgCXhhfDWTo_BBmwPgDvNwkOJj0DRq_j3aGm38M1x1r2IC4RrzV8g6uSK7J8NcL8tu6hyvC76s-6M4ez-6ZfRrSvp9IdxN5lcnZOzp3npVs9ni-31w30c1GvJN6FjH5w6UxLMf0T_TIYItVuAw9Pm2-fY63x6enbbCiaErhy8l4G29wZX9wNeALFp7wehvi0278-EsC4-8cxjWMK-9wrEqWbRmfBtCz7IN9DzA2oI09CJWgqv4GmiIToGBcKTLXNENmpT-00XmuF-9o6aGJjubWeG4tZ1Sus3KVrcQI1-mCT5fzeTrNRs06na2W8zQtslkqsqrCNF_Ms3TOc56VmJZ8JNd8wqeTJV-mC76aZElaTovloiiW2XxSLqYLNp3gQUiVKPXrkBhbj6RzHtfpZD7lfKREjsrFXzOcH63R9TjS7zYN4zy-dT8i-pbosTz8-LHrADrOfe3YdKKkI3edhiQpXIdK0lpT-gId5Kb2blCerkKNvFXrhqh1YdXjpqolNT5PCnNgfBdQ-3_j1pr_YkHh2hEycYzv-mR-rfk_AQAA__87Su-y">