linux-test-project / lcov

LCOV
GNU General Public License v2.0
890 stars 237 forks source link

Incomplete Coverage (Virtual destructor & Initializer list) #122

Closed phil-zxx closed 1 week ago

phil-zxx commented 3 years ago

I have 2 examples, where lcov shows missing coverage. It seems this is incorrect as all functions & lines of code are covered. Perhaps I am missing a flag to achieve full coverage? Is there anything I can do to fix this?


Build Steps

# CMakeLists.txt
cmake_minimum_required(VERSION 3.17)
project(code_cov_test)

set(CMAKE_CXX_STANDARD 17)

add_executable(main1 main1.cpp)
add_executable(main2 main2.cpp)
# build-script.bash
cmake -DCMAKE_CXX_FLAGS="-O0 -fprofile-arcs -ftest-coverage" -DCMAKE_BUILD_TYPE=Debug .
make

./main1
./main2

lcov -d . -c -o coverage.info
genhtml coverage.info -o html_site --legend --demangle-cpp

Example 1

#include <iostream>
#include <string>
#include <unordered_map>

int main()
{
   const std::unordered_map<std::string, double> quotes{
       { "a", 0.011},
       { "b", 0.022},
       { "c", 0.033}
   };

   for (const auto& [s, v] : quotes)
     std::cout << "  >> " << s << ": " << v << "\n";

  return 0;
}

which gives image

Example 2

#include <iostream>
#include <memory>

struct Base
{
  virtual void func() const = 0;

  virtual ~Base() = default;
};

struct Derived : public Base
{
  void func() const override
  {
    std::cout << "  >> TEST\n";
  }
};

int main()
{
  const auto obj = std::make_shared<Derived>();
  obj->func();

  return 0;
}

which gives image image

henry2cox commented 3 years ago

The missing lines in your first example appear to be a bug in gcc/gcov that I have noticed as well ☺

The missing function in your second example appears to be the one described in issue #98. (I implemented a workaround in my lcov branch – pull request not integrated yet - see the description of the issue and the workaround.)

A similar filtering hack could be done for your first issue as well (but it hasn’t gotten painful enough for me to need to do it yet).

Hope this helps.

Henry

henry2cox commented 1 week ago

This one has been open with no activity for a very long time. I just checked in a new --filter initializer feature to address this scenario. It seems to work for this specific example, as well as for a bunch more in various of our projects. However: this filter should be considered experimental/potentially flakey - at least until it gets some wider use and testing.

In the meantime: I am closing this issue. If there is still a problem: please feel free to reopen this issue or file a new one (better option is to file new, possibly referring back to this one). Please include an example which illustrates the problem. You probably also need to specify platform, compiler version, etc - as some compilers and some versions do better or worse at initializer instrumentation.

Henry