lcov finds a branch in the following simple constructor.
12 [ - + ]: 26 : Vint::Vint() : m_bytes{nullptr}, m_len{0} {}
This happens in all my constructors with member init lists.
I've narrowed it down a bit by adding whitespace:
12 : : Vint::Vint() : 13 [ - + ]: 26 : m_bytes 14 : 26 : {nullptr}, m_len{0} { }
I think it's the member init list itself rather than the first member (m_bytes), because it doesn't find a branch in the second member (m_len).
=========================
OS: Ubuntu 16.04.1 LTS
lcov: LCOV version 1.12
genhtml: LCOV version 1.12
clang version 3.8.0-2ubuntu4 (tags/RELEASE_380/final)
To reproduce:
~/Vint/cmake$ clang++-3.8 test.cc Vint.cc -std=c++14 --coverage ~/Vint/cmake$ ./a.out ~/Vint/cmake$ gcov -b -color -o ./Vint.gcda ./Vint.gcno ~/Vint/cmake$ mv *.gcov cov/ ~/Vint/cmake$ lcov --capture --directory . --output-file demo.info --test-name demo --rc lcov_branch_coverage=1 ~/Vint/cmake$ genhtml demo.info --output-directory cov/demo --demangle-cpp --rc lcov_branch_coverage=1 --legend --prefix .
test.cc (Vint.cc and Vint.hh in attachment):
#include "Vint.hh" #include <iostream> using std::cout; using std::endl; void output(Vint temp) { cout << temp.val(); cout << " => " << temp.xxd(); cout << " (length " << temp.len() << ")"; cout << endl; } int main(int, char **) { output(Vint{}); output(Vint{0}); output(Vint{127}); // 0x7f output(Vint{128}); // 0x0180 output(Vint{129}); // 0x0181 output(Vint{16383}); // 0x7fff output(Vint{16384}); // 0x018080 output(Vint{16385}); // 0x018081 output(Vint{288312}); // 0x11ccb8 { Vint v{288312}; Vint v2{v}; Vint v3 = v; v2 = v3; cout << "v2 < v: " << std::boolalpha << (v2 < v.val()) << endl; cout << "v3 > v: " << std::boolalpha << (v3 > v.val()) << endl; cout << "v2 == v3: " << std::boolalpha << (v2 == v3) << endl; cout << "v == v3: " << std::boolalpha << (v == v3.val()) << endl; cout << "v2 <= v: " << std::boolalpha << (v2 <= v.val()) << endl; cout << "v3 >= v: " << std::boolalpha << (v3 >= v.val()) << endl; } { Vint v{288312}; Vint v2{123}; Vint v3{4321}; cout << "v2 < v: " << std::boolalpha << (v2 < v.val()) << endl; cout << "v > v3: " << std::boolalpha << (v > v3.val()) << endl; cout << "v2 == v3: " << std::boolalpha << (v2 == v3) << endl; cout << "v == v3: " << std::boolalpha << (v == v3.val()) << endl; cout << "v <= v2: " << std::boolalpha << (v <= v2.val()) << endl; cout << "v3 >= v: " << std::boolalpha << (v3 >= v.val()) << endl; } return 0; }
LCOV doesn't generate branch coverage information itself - it displays the data taken from gcov. I would assume that the unexpected branch coverage data is also present in the .gcov files generated by gcov.
Thanks for the quick reply Peter.
I will redirect this bug report to the Clang folks, whose implementation of gcov I'm using.
Sorry for the noise.