<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/135049>135049</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
clang source-based code coverage *sometimes* incorrectly includes comments into coverage reports
</td>
</tr>
<tr>
<th>Labels</th>
<td>
clang
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
krinkinmu
</td>
</tr>
</table>
<pre>
Hi There,
I believe I found a bug in the clang source based coverage. It manifests for me on the following clang version:
```sh
clang++ --version
Ubuntu clang version 18.1.8 (++20240731024944+3b5b5c1ec4a3-1~exp1~20240731145000.144)
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
```
I posted the problem on LLVM discussions (see https://discourse.llvm.org/t/llvm-source-based-coverage-sometimes-generates-counter-for-comments/85730), however since then I found a sensibly small reproducer for the issue, so I'm reporting it as a bug now.
Here is C++ snippet I use to reproduce the issue:
```c++
#include <iostream>
#include <memory>
template <typename RequestType, typename ResponseType> class Stream {
public:
virtual ~Stream() = default;
virtual void onEvent() = 0;
};
template <typename RequestType, typename ResponseType>
class StreamImpl : public Stream<RequestType, ResponseType> {
public:
void onEvent() override {
// A comment that should not be counted by coverage.
std::cout << "onEvent\n";
}
};
using Request = int;
using Response = int;
using Processor = Stream<Request, Response>;
using ProcessorPtr = std::unique_ptr<Processor>;
inline ProcessorPtr createSomething() {
return std::make_unique<StreamImpl<Request, Response>>();
}
class TestLibrary {
public:
TestLibrary();
~TestLibrary();
void method();
};
TestLibrary::TestLibrary() = default;
TestLibrary::~TestLibrary() = default;
void TestLibrary::method() {
std::cout << "TestLibrary::method()\n";
}
int main() {
TestLibrary library;
library.method();
return 0;
}
```
For completeness here are the commands used to generate coverage:
```sh
clang++ -fprofile-instr-generate -fcoverage-mapping test.cc -o test
LLVM_PROFILE_FILE="prof.raw" ./test
llvm-profdata merge -sparse prof.raw -o prof.data
llvm-cov export --format=lcov ./test -instr-profile=prof.data
```
The re-producer is somewhat convoluted, but what I want to concentrate on here is coverage of `StreamImpl::onEvent` method and specifically the line with comment in that method (line 14).
There is a range of results that, I think, are sensible here:
1. `StreamImpl::onEvent` is not included in the coverage at all - it's not used, it's a method of a template that does not need to be instantiated in principle (`createSomething` function isn't used and there is no other places where this template is used).
2. `StreamImpl::onEvent` could be included in the coverage report with 0 coverage, but the comment on line 14 should not be included in the coverage report (e.g., we should not report 0 coverage for comments, instead we should not report coverage for comments at all).
However, what I actually get is the following:
```
FN:36,_ZN11TestLibraryC2Ev
FN:37,_ZN11TestLibraryD2Ev
FN:39,_ZN11TestLibrary6methodEv
FN:43,main
FN:25,_Z15createSomethingv
FN:13,_ZN10StreamImplIiiE7onEventEv
FNDA:1,_ZN11TestLibraryC2Ev
FNDA:1,_ZN11TestLibraryD2Ev
FNDA:1,_ZN11TestLibrary6methodEv
FNDA:1,main
FNDA:0,_Z15createSomethingv
FNDA:0,_ZN10StreamImplIiiE7onEventEv
FNF:6
FNH:4
DA:13,0
DA:14,0
DA:15,0
DA:16,0
DA:25,0
DA:26,0
DA:27,0
DA:36,1
DA:37,1
DA:39,1
DA:40,1
DA:41,1
DA:43,1
DA:44,1
DA:45,1
DA:46,1
DA:47,1
BRF:0
BRH:0
LF:17
LH:10
```
As you can see there is a 0 reported for line 14 which is not what I expect to see.
If I change the code to remove the `inline` modifier from `createSomething` function, I get a reasonable lcov:
```
FN:25,_Z15createSomethingv
FN:36,_ZN11TestLibraryC2Ev
FN:37,_ZN11TestLibraryD2Ev
FN:39,_ZN11TestLibrary6methodEv
FN:43,main
FN:6,_ZN6StreamIiiED2Ev
FN:13,_ZN10StreamImplIiiE7onEventEv
FNDA:0,_Z15createSomethingv
FNDA:1,_ZN11TestLibraryC2Ev
FNDA:1,_ZN11TestLibraryD2Ev
FNDA:1,_ZN11TestLibrary6methodEv
FNDA:1,main
FNDA:0,_ZN6StreamIiiED2Ev
FNDA:0,_ZN10StreamImplIiiE7onEventEv
FNF:7
FNH:4
DA:6,0
DA:13,0
DA:15,0
DA:16,0
DA:25,0
DA:26,0
DA:27,0
DA:36,1
DA:37,1
DA:39,1
DA:40,1
DA:41,1
DA:43,1
DA:44,1
DA:45,1
DA:46,1
DA:47,1
BRF:0
BRH:0
LF:17
LH:10
```
> NOTE: The reason why inline is there is that originally that function was defined in a header file.
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJzsOEuP47jRv4Z9KciQKD_aBx88dhtjYL7dwWx_OeTSoKSyzYxEaknKbl_mtwdFSrLU7pnOIofkEMAwRNa7WC9SWCuPCnHFZp_YbPsgGnfSZvXdSPVdqqp5yHRxXX2W8HxCg4xvWLxm8XoPGZYSzwh7OOhGFSAga44gFbgTQl4KdQSrG5MjZMJiAbk-oxFHnMDeQSWUPKB1Fg7aQIWgA91Bl6W-SHVsOZzRWKkVS9dBLJvH4WdPLF57HMY_Mf4JoqjDjdf_nzXKNWMWkDxOkskjMP4YKHjMp_EiTWI-XU6njH9Ks1k2yxPMpyKNkh_4Wic_OqRkOovjeJIQ4pLF62dhjuhYuobXx_nLfBrVeVRK1bxGR9UQ_GRQFFDpAkvCqrWVr-Q2ZZ0oSyy20tA-47vGGsZ3mVRD8zon19o6LLxraqOzEivy1Jcvf_s_KKTNG0umWTLKIsLJudqSr_iO8R0h6MZYnJTluZpoc2R85xjf0TIKZxP5s4m6s4msrtDJCm10RIVGOLRRrhvl0EQHbaJcVxUqZxnfPc4WaUze4Bs46Que0YCVKkfSVg3CwqKyMiuvYCtRlmCwNrpocjT-7Mk0aW1DoQVWw57xRUVI2jiKA-lA2Da4lL5Mgmc-oyEy2LSnb5Wsa3Swh8YiOH2TMhBwF0R5oKYtnkqVl02BwNKN1NYZFBVLn-5gFVbaXFtIvHZY1aVwHuSuNSpRIXzDPxu07vlae6sG-7bWyqIHpE8UoNbCH14WsAUpUjdZKfOgKpylcY0o4UdA8aG7BJZuocCDaErHUqKBHvGsZQFaPZ1RuQF2HPDYYtt-_Ht6h8zrNd9XdQk-yL3u7S5LN2_YvbX-HYPfM4BC00hyvseHENywhjYWwZ2EA3vSTVmA0g4yhBCyBWTXW9nx_AGsK0hYus5148h6lm6Acd4JnW0U47xzLLls7LjGUlS2pnnvStWeQwcKZo5hPfir0Tlaq42Hv_XV0E_k6QHfnvCrC7S9JY2Sfzb4UjvD0k2P1pOzeC1VKRWOWeQGhcM_KOFPkspoCJfgZIOuMeomohLf8SXIYenmdu6_0PwpcLyFntckBM4zWvdFZkaY67thMIAPuQD8-CnERw7Zoou3gjsvDGm9VXfM7nPrjuZeg3siFq-9OnfEQ_06V_80In9JPYrT3rtSUWuV6o2EobvLjqMHtavJveOgi4F4JGPcoHbaUBrWJTpUaC3QjADChKpLCSpUYakmF1SUu57SJ-W_0tcPtdEHWWIklXWm70sQHfquVYm6phRxaN0kzyHS_pPFa-qUL1-__b7bf3l6oT-WbhnnxHJixIVxDhPqigHbN0aCFcIJqNAcESJbC2N9-_UkxNx_E05Hk-sz4Cu1LIioT1bCsXRb0nbHHlr9W2tYuh1yeePX5xOCwahvlNICdeYLVbpcq7MuG4cFpVzWOPDbe7gIKoaaEHJUzjtJq3Ak0vY-B30ANo-HOUzB1dW_edxmEQhVgK0xlweZi7K8-jP1deQi3akvv37iE66jYvzR4yQ0KU16c4IOAoxQQQWDtimd9bRkyB6oDH2nT4qfdmhAr34fJsnkA9Wl9S2g7ddFP452tgsHNINEIB3ji4BM0Uli2y3RWaIPIKDvk97GQmOgURgiOkOgYxXKSeGCvNpIlcu6RD9qzuO3dXYew6FRuaOZVFrF-CKo4P3tOk8pDZoWUJciRwsXD3AnaW8qSdvq7v3MP_JN7juk1_gn3glTVzje-JakbZh1KU2HrhW0p_ym837Em_FHnBwnxPOCQ9oWfhPrp8PbvLnxjqah-l26d6na474F4ucwp3rpIWlEToNTeYUjOnLo6BJyX56o5v3G0nU6Z3zz8vffkmRQWzf86dwjLN5B2A4Rlu8gzEPo3bCmKeMbX9HbDT7zZMnsTVj1FEna8h2Ewl7Kp0UbCS3vLQVH8isjfoqx_RBjbEaP1tvhd-JfGTLA-MiSHUvXc__1mRzG4nUQSH6I-9V0tJqNVvPhio9gfAxbDFc-BpJ-tRitlsPVNB6tktEqHa2mo9VstBrJm3byPn3beV_R1-f26wttJQv6oq0kvm8xawtX3UAuFNDV0d1KdNzmFBY-mbo8v5xkfuoKbJs9-Fpj7puORWxzjO6tB9hDfvKlPhSBor2UVfocttg8DkOpbzi6kAdJF0KjK_h1zQy9grJVgEFhtRLUJqjX_jxdP8ya_1g-t3LnbYhL-TRk-leS-eN8-i9I93cN_YvJvrhP9lGWvsn8_-X6mm7bv_3-_ESX9DBaUt7A5XSF9mYYOp9pP4QDbeRRqnbsE-42slyEpcuOVKHHCzihKCh1ZYmTh2KVFst0KR5wlSymU54sFun04bTK0sdUCJzPZofFYlksimIpDoLH2WOeHObp4kGueMxn8TReJvPZLE0nh2SZzpbzHJNlyqePgk1jrIQs-8esB_-os0rSWTxdPpQiw9L6R0zO2_sDZ7Ptg1n5CT1rjpZN41JaZ28snHQlroaPlVH3WFkMZhfG1_3DGONrGnK0MZi78toNPPY2dEjlh_DR3GMfGlOuxu9zR-lOTTbJddW-yXVPc7XR_8DcMb7zJlrGd62V5xX_ZwAAAP__c1CyLQ">