| Issue |
208237
|
| Summary |
[llvm-cov] Wrong `show` output if a macro defined in a system header defines an inline function
|
| Labels |
new issue
|
| Assignees |
|
| Reporter |
kanje
|
### 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="" 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();
}
```
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs