<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/208237>208237</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
[llvm-cov] Wrong `show` output if a macro defined in a system header defines an inline function
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
kanje
</td>
</tr>
</table>
<pre>
### Problem Statement
Given this project structure
```
CMakeLists.txt
include
└── mymacro.hh
main.cc
main.hh
test.cc
```
when
1. `include` is a system include path specified with `-isystem`
2. `mymacro.hh` defines `MY_MACRO()` as `inline void func_from_macro() {}`
3. `MY_MACRO()` is used in `main.hh`
4. `main.hh` contains another inlined function after using `MY_MACRO()`
5. `func_from_macro()` is not used in tests
then `llvm-cov show` marks `MY_MACRO()` as not covered (which is correct) **and** also marks a region afterwards as not covered as well, including empty lines, comments and function declarations (even if their definitions are covered).
### Reproduction
1. Take the code (attached, or see the [listing](#code-listing) below).
2. Make a `build` directory.
```bash
mkdir build && cd build
```
3. Build the project with Clang.
```bash
CXX=clang++ cmake .. && cmake --build .
```
4. Run the tests.
```bash
find . -name "*.profraw" -delete && ctest
```
5. Generate the coverage report.
```bash
llvm-profdata merge -o merged.profdata default.profraw
llvm-cov show -format=text -instr-profile=merged.profdata CMakeFiles/main.dir/main.cc.o -object=CMakeFiles/ut-main.dir/test.cc.o .. .
```
The output will look like this:
```
1| |#pragma once
2| |
3| |#include <mymacro.hh>
4| |
5| 0|MY_MACRO()
6| 0|// inline int bar() { return 42; }
7| 0|
8| 0|// Comment section
9| 0|// Comment section
10| 0|// Comment section
11| 0|// Comment section
12| 0|// Comment section
13| 0|// Comment section
14| 0|// Comment section
15| 0|// Comment section
16| 0|
17| 0|int doSomething();
18| 0|
19| 0|class ExampleClass {
20| 0|public:
21| 0| ExampleClass();
22| 0|};
23| 0|
24| 0|inline int foo() { return 42; }
25| |
26| |// Comment section
```
### Expected Output
Only `MY_MACRO()` is marked as not covered.
### Other Observations
1. Uncommenting `bar()` right after `MY_MACRO()` stops the propagation of the not covered region.
2. Defining `MY_MACRO()` locally or using `-I` instead of `-isystem` fixes the issue.
3. Commenting out `foo()` at the end of `main.hh` fixes the issue.
4. Covering `func_from_macro()` fixing the issue.
### Code Listing
#### CMakeLists.txt
```
cmake_minimum_required(VERSION 3.28)
project(CoverageTest VERSION 1.0 LANGUAGES CXX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS_DEBUG} -fprofile-instr-generate -fcoverage-mapping" CACHE STRING "" FORCE)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS_DEBUG} -fprofile-instr-generate -fcoverage-mapping" CACHE STRING "" FORCE)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS_DEBUG} -fprofile-instr-generate -fcoverage-mapping" CACHE STRING "" FORCE)
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS_DEBUG} -fprofile-instr-generate -fcoverage-mapping" CACHE STRING "" FORCE)
set(CMAKE_STATIC_LINKER_FLAGS "${CMAKE_STATIC_LINKER_FLAGS_DEBUG}" CACHE STRING "" FORCE)
find_package(GTest REQUIRED)
enable_testing()
add_library(main STATIC main.cc)
target_include_directories(main SYSTEM PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)
add_executable(ut-main test.cc)
target_link_libraries(ut-main PRIVATE main GTest::gtest GTest::gtest_main)
add_test(NAME ut-main COMMAND ut-main)
```
#### include/mymacro.hh
```cpp
#pragma once
#define MY_MACRO() inline void func_from_macro() {}
```
#### main.hh
```cpp
#pragma once
#include <mymacro.hh>
MY_MACRO()
// inline int bar() { return 42; }
// Comment section
// Comment section
// Comment section
// Comment section
// Comment section
// Comment section
// Comment section
// Comment section
int doSomething();
class ExampleClass {
public:
ExampleClass();
};
inline int foo() { return 42; }
// Comment section
```
#### main.cc
```cpp
#include "main.hh"
int doSomething()
{
ExampleClass c;
return 42;
}
ExampleClass::ExampleClass()
{
// Constructor implementation
}
```
#### test.cc
```cpp
#include <gtest/gtest.h>
#include "main.hh"
TEST(Test, Test) {
doSomething();
}
```
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJzUWEtv6zoO_jXqhojhynkusnAcp7e4fZxJ0zvnrgLFZmLd2lZGkvv49wNJthunaU4wiwNMUSC2RJGfKIr8TKYU35WIUzKYkcH8ilU6E3L6wsp_8Goj0o8poYH7hx9SbHIs4EkzjQWWmvgh8cMb_ool6Iwr2EvxDyYalJZVoiuJRmLo1_9-GN2zF7zjSitPv5vlvEzyKrViMSWTvvl3D2O_fYDio2CJFF6WET8sGC-9JGme7JhGpd3YoTXih28Zlu7p2gMy9Bt7Qx-4AgbqQ2ksoB6GPdMZqD0mfMsxhTeuM7Oqx52cU0utpgNMQx9S3PISlZm4_3t9H0bLR0LHhE7MJFPOdM5LhFfBU9hWZbLeSlGsrRInCmQ0I6O5MxJ4p3VxBZXCFHhpQdQesEv6XncIElFqxksFrBQ6QwkOgjOvuSiBbTVKqBQvdyfNET8cWK0nAdd4SqFbTOYglHO4ztBizPPXopeIV1CZeDNLCiZfvveU0ZaIV5SYAqHjt4wnmbGSCCkx0dZPNCQ0ZGXqHoDlStRaGUjctTt7YzJVx0qZgjfMc0Kj-tjN5rHY6w8w3lFmIhGFiW_juQNvpZjkTDLzrAw2NHHPt6Az5NKFAHeTTGJjj9CJ5xzyeZGWuJcirazWNjpX7AWNKkhEikY905olmdEQgZCg0E2TwSznSvNyRwZz67rArOg1g3QCG8zFW22YemAuHTDj8U3F89TGKzfOFPLDiAAAtPdmw1RWjxUvKZdg1wChQ0KHkKTu_XiVi9iZFTUgm0Rgb1CUs3J3zlD08ycJ5okRI3RG6AySwmD2vNaufe_1HJgvulz0L6vSGrdBeM7elpcpeNArWWE8TQkNvb0UW8neCKXQSzFHja1to--ExYEHN1iiZLo5t1eUbIcgcS-kPgfA3gljMWWaQYFyh9AT7iH12okUt6zKdYvtYHFzoaC3FbJgmgRzje8aerxUWlrdPEcSzI912hS84LkJ9IVNFimXzWOSeAJ6YmPOjgTzjmylewfidcb1hDmkU-dB_HCVIYhK7ysTB3kOuRAvkHMb5lyRIDzK10bFNRlF4P7IKCI02Eu2KxiIMsFahHZF3GBwvK5J6SSIDlJ1ENfy_VNKBu2gT0bRUXpyIsOOCKELQhd1XgVeatgw-ZnNQaKuZAl9SoIZmNzulIy6Stzg-JTmyCUiUNgkCyMwuVj02r9c9PpyUXq5aHC5aP9y0cHlosMTzr7unoA5uFQ8iQJ1ZlOoPfBgVguPT2nonkGSM6UgfmfFPsfIvphqbkVp9wz21SbniYt-M9t1u_k9VHOEhR55fjT_nApOwKT9o422gboV4peBSgcnbgkdHl21b3x_lAw-q1_8vsdEYwqPNje46ccy__iW8Zja7ir3QSH_UlUfLcd53CiUr65It7X1uawrek102ltqDEi-y3RNhU4iUFrsVVPW9mxnlYOwhb9DLRz3qKvu3PKBb4gV5CJhef5hCntLv3q3dr-l0shSo79LPWHL39Hh4EpV6LmiG33uTFTakjVxQNCYtiuwbDQeEMQTCvtG4SvKGtK3vG_L341IZ23nNCLDYu5qTtKds9PHXwKH4WKr_brgJS-qYi3xPxW3TGr8V7x8un18gMBrcnJNNAgdR3X5XaHS0Aheez7chQ83z-FN_GR5hl1F_FChXXQf_hmvo58_14u78ObJkYE-Gc2OJtbzePZ8Q0Zz6G3r2lpX2l1DAXrbhgD0Crbf2zxCIQqjP2J4Wi1vH26cdgqLx2UUOyAdFN9g-H0I4p_x-u724c94eRrK8fzvwPT0R7iM52dhnRD5LchW4eo2Oo_sq0iL7AJrxA8NVV3vWfLCdkjo-MZG9zL-1_PtMp47KSzZJse1YWSfxcsuZmm6zvlGMvlB6NhcfHCIoPmItpKayR3qdc2Y1s23ATe0r17199Mqvocfz7O72wg60fm8XMYPq_XT4_Myitfz26Xd2qL50D6Egu-YVNqAJXRc00loPt0PkeS8fKmBOxCN8I_l7V_hKrbwwfrC1NEg3BktXwbWRswpNuYtjafjh_A-hkZh9Hh_Hz7Mm_ca7jeVy-Stdl-LTlOiXZLs925Jl7e6MdclgG41gIsbA-eRfXZDLgNzhiATP_xCfv8Hqvu56gQ7-D-b8MMzJNGUrO8I4BHd-5bctVTOmrqcpp1F_atw6bbM2nBpQ4PSJqooPecFA392YoOQtPS0g73er9XYcYi9vCdcdGig3W7p2oxCAjfyZvOs2fkvr8uJluHX_QfRzmWNhf31mvtx1kWr-GlF6NgmIxqB-518fg98G0VdzFfpNEgnwYRd4fR6NA4GNJgMBlfZNBiM-v0Jjkb-iG43wXbIJgGykT_uBz4bjLZXfEp9OvRH_vh6cD25HniT8Xg4ZulknARsPBympO9jwXju5flr4Qm5u7Icbkr9MQ1GVznbYK5sR5jSEt8cwzP7G8yv5NT2HzbVTpG-n1sG16rRXOe2ldz0KMhgDv-WwpHJpgFY9wT4FhjYxFO3T20Hse3JZshSlG1nlZVN7mn6cVeVzKeZ1nsbNjYodlxn1cZLREHowmCof3otTVzYvShCF_VmX6f0vwEAAP__p2avjQ">