<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/128149>128149</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
Incorrect File Association in Debug Information of __cxx_global_var_init()
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
int-zjt
</td>
</tr>
</table>
<pre>
The debug information (scope and file) for `__cxx_global_var_init()` functions incorrectly points to the including file (e.g., `main.cpp`) instead of the actual definition file of the global variable (e.g., `foo.h`).
**Minimal Reproduction (Clang 16):**
`
// foo.h
class Foo {
public:
Foo() {}
void bar() {}
};
Foo foo; // Global variable definition
// main.cpp
#include "foo.h"
int main() {
foo.bar();
return 0;
}
`
**IR Analysis:**
Compile with `clang++ -O0 -g main.cpp -S -emit-llvm`:
`
; Function Attrs: noinline uwtable
define internal void @__cxx_global_var_init() #0 section ".text.startup" !dbg !21 {
entry:
call void @_ZN3FooC2Ev(ptr noundef nonnull align 1 dereferenceable(1) @foo), !dbg !25
ret void, !dbg !25
!3 = !DIFile(filename: "main.cpp", directory: "xxx/xxx/xxx")
!21 = distinct !DISubprogram(name: "__cxx_global_var_init", scope: !3, file: !3, type: !22, flags: DIFlagArtificial, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition, unit: !2, retainedNodes: !24)
}
`
It's obvious that the file in debug info of `__cxx_global_var_init()` is main.cpp but it should be foo.h.
===============================
This misattribution causes coverage analysis tools like gcov to report inaccurate line coverage statistics.
`
cat main.cpp.gcov
-: 0:Source:main.cpp
-: 0:Graph:main.gcno
-: 0:Data:main.gcda
-: 0:Runs:1
-: 0:Programs:1
-: 1:#include "foo.h"
-: 2:
-: 3:
1: 4:int main() {
1: 5: foo.bar();
2: 6: return 0; // Incorrect count (includes foo.h initialization)
-: 7:}
`
The coverage count of line 6 is two but one of them is actually belongs to foo.h.
=======================
**Root Cause Analysis:**
Through debugging LLVM, I identified that the issue arises from commit [D66328](https://reviews.llvm.org/D66328). In `CodeGenFunction::GenerateCXXGlobalVarDeclInitFunc`, an empty `SourceLocation` is passed to `CodeGenFunction::StartFunction` when generating `__cxx_global_var_init()`:

This empty `SourceLocation` causes `CGDebugInfo::emitFunctionStart` to default to the including file's location when creating the `DISubprogram`.
**Question to Community:**
Would modifying the `Loc` parameter (may be use `getOrCreateFile(D->getLocation())`) in `DBuilder.createFunction` when calling `CGDebugInfo::emitFunctionStart` be an appropriate fix? If so, I'd appreciate guidance on how to properly retrieve the global variable's definition location for this context.
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJy0V0uP47gR_jX0pWBDomzZPvjgx7phYPaR6clmkUuDokoyNxQpkJS7vb8-KEqWPZPumRySgdAak8V6fFX1FSW8V7VB3LDFji0OE9GFs3UbZcL0rz_DpLDldfPljFBi0dWgTGVdI4KyBhhfeWlbBGFKqJRGxtdQWQcsT15e5NvbS61tIfTLRbgXZVRgfMX4muUJVJ2RpMODMtI6hzLoK7RWmeAhWAhnpB3dlcrUUTdZw1k9Y3xP-huhzEy2LcsTsqqMDyhKsFU8KmTohIYSKzJLvkYVw27vFVyEU6L4D82VtbNzr3bGki3j9PysjGqEhs_YOlt28hb_XgtTQ5pTWNkgS4fyJB49Mn6EXmGylVp4D0drgS13LNm2XaGVpGPJFmi9hyfuLg9x8WJVCYVw3-7Q34x0kLbKWpbtAAZzT99EdweBDo5ejQDSStZjTVDw3l3OB-lkq0yI0g9OkG8QAxud6_2hZYehcwaSfmVweACEntNn2Bqhr175R8z2tmkpSa8qnCkPkqBlfMf4Dqa_JjCtR59h-gxTbFSYan1pSHf2gHq2g-NQXrANwZEVMFYZrQxC9xoIFpZsIzBUZgGdIcQIbDb_XukC41kCHm_557OAb2Hmg3ChaxnnwHhaFjW9eDpAhSa46y3NUugHS__8JTtau-c_XRhftcGBsZ0psQJjjem0BqFVbSCFEh1W6NBIjN7zVRrdmVO5EvpUu3fTi2jLYYim3tmMyUgzYNmB1g6nY2zfFbWJEQ0SZIzzsUg4JyWloka1MRrafnt7Y_z48JeTK1E1RZ8doFQ-KCNDb-S5K1pnaycaxlcPZj5APNqMDNPLpRktRKJ5-B2u435_otKijjk_nI5a1FsXVKWkEjqqa4_37eff6McnK4X-Yv9uVAC23I_rh3vj8D105NJghn47DEIZLH-xJfrbxnyI_6HmT4HxpQdbXJTtPISzCJGEIiEp80CrRE8_Zk7l721QdAFUAH-2nS6hwJ5qZkN-s8P_8YkmvpzJG-VFCE4VXWwKKTqPHqS9oBM1zYa-1SFYqz1o9S-EWtoLsbzD1roAyggpOycCQmzR8awPIlABST8b8ZQijADMSNHAOvRvSnkAIOrZPtvOSSqMB6L7SuDJifZ826-lsR8oOogg7mKl-FaMZD53hmog_UDFb33RfySSRhr8gINHKX6jkK8PZ18vp8PynGUfE_couBikP2Dym1l658P7gd3HkXO6zXCQtjPU7KshGN-XJMRGElr9Jfp-Wr8TyZIieegcunSMpdArtlVfITm1QXi1sQOsuU32hpb72a-vUKC2po7Xif99XwwUSs9nawPsqezfnWtfzs529blv9JquM58-_f4zUcgJVImG2AnLOzEo7zsE4RS1UeVsA9I2DXHTYnfI84yv2OLA-OocQtsbohw4vCh89TMaiDPrasaPgzBfz-BkiFn2tsQnNLfhSGez7RMapNbb__FHf3P4XbgDSn0yKpBkvAntQRjApg1X0tO3FtFmVNOTUiu8pzDsh5aeaUqOS3kCr2c0UPf2CZcfkt8w5uOAYYvdqRE1vgdGrcK5K2bSNowfO49uKkIQ8tygCZ7xI7ka_7PMVxlm68WUl1xO59mqmK5XVTZdlJXM5umaY1UOlD6w3XdAGJiPwn86ULJPprJ96HRXuUUeYSD5YOluJjod3r_xxrmhBwM9WNJhDxVJszz5aqTmyeyxLP_WoY8ng4W9bRoaYNfHwvxHnBqNLVV1fdD5yVLOoRVONBjQUTc3gtoJqMRZntQYfnV7cgWHa8NhyrKfagwjHH3G-qTF63n0dtcpXaKbyf7st6VAd6OhDv47BAsaLyDa1tnWKZoflXpj2RFOFXgbW4zxZRklUEaBulOlMBLBGjjbVwKHTqPTV6I2p_CC730kxGQ8fE-MeaHvnUCVIa2Jl8FJucnKdbYWE9yky3mS8lWazyfnzSKThVhkaVZwwcuMrzMu8yzhyYrjOsH1RG14whcJ52myWuTJfIZizSVmMqvkKl-mKZsn2Ailxy6fRLLYkIn5eqJFgdrH7zjODb72VEJjZHGYuA0dmhZd7dk80cqHO1lMggoaN3cap7TC1ntLoFGUykBMCJwevv9sBd_p10nn9OY7fRmv7v1r2jr7J8rA-DG6TK05xHTZ8H8HAAD__3UCbR4">