Invalid coverage results from Clang's Source-based Code Coverage

I'm trying to get a reliable code coverage through Clang's
Source-based Code Coverage and am heading some false negatives on
virtual inheriting classes. In particular the inheriting class'
constructor is displayed as NOT covered.

Given this code:

#include <iostream>
class Foo
{
public:
    Foo()
    {
        std::cout << "in Foo()" << std::endl;
    }
};

class Bar : virtual public Foo
{
public:
   Bar()
   {
        std::cout << "in Bar()" << std::endl; // supposedly not covered
   };
};

int main (int argc, char* argv)
{
    Bar b;
}

The output is, obviously:

in Foo()
in Bar()

but the Bar's constructor is reported as uncovered.

I'm folliwng the steps described on the above page ie.
1. clang++ -fprofile-instr-generate -fcoverage-mapping main.cpp
2. running the binary
3. llvm-profdata merge default.profraw -o default.profdata
4. llvm-cov-4.0 show a.out --instr-profile default.profdata

Tried clang 4.0 and 5.0 (compiled from trunk) with same effect.

Could anyone help me with this issue?
Is there a way to workaround this issue?
How can I debug it to see what's causing it?

regards,
Michał Pszona

I'm trying to get a reliable code coverage through Clang's
Source-based Code Coverage and am heading some false negatives on
virtual inheriting classes. In particular the inheriting class'
constructor is displayed as NOT covered.

Given this code:

#include <iostream>
class Foo
{
public:
    Foo()
    {
        std::cout << "in Foo()" << std::endl;
    }
};

class Bar : virtual public Foo
{
public:
   Bar()
   {
        std::cout << "in Bar()" << std::endl; // supposedly not covered
   };
};

int main (int argc, char* argv)
{
    Bar b;
}

The output is, obviously:

in Foo()
in Bar()

but the Bar's constructor is reported as uncovered.

I'm folliwng the steps described on the above page ie.
1. clang++ -fprofile-instr-generate -fcoverage-mapping main.cpp
2. running the binary
3. llvm-profdata merge default.profraw -o default.profdata
4. llvm-cov-4.0 show a.out --instr-profile default.profdata

Tried clang 4.0 and 5.0 (compiled from trunk) with same effect.

Could anyone help me with this issue?
Is there a way to workaround this issue?
How can I debug it to see what's causing it?

Hi, this looks like a bug in the source-based PGO, which is used to get the
coverage. The problem is that we only collect PGO data for the base
constructors on platforms whose ABI supports constructor variants, which
usually isn't a problem since complete constructors invoke them. However,
in the code sample that you provided, clang will emit a C1 complete object
constructor for Bar that doesn't invoke the C2 base constructor for Bar.
This means that our assumptions about constructors are incorrect and should
be fixed.

I don't think there's a workaround for this issue unfortunately.

I have filed the following bug to track this issue:
http://bugs.llvm.org/show_bug.cgi?id=31992 .

Thanks a lot Alex!
regards,
Michał Pszona