GCOV instrumentation for non-instantiated code (e.g. template functions)

Dear all,

(first of all: Sorry if there is any confusion because I am not using the right C++/compiler lingo, I'm more of a C++ "consumer" than a language lawyer/expert. I'm interested in any hints or corrections so I can learn, though).

I have done some work on the GCOV instrumentation that allows uninstantiated code (e.g. template functions, in-class defined member methods) to appear in GCOV output.

I have contacted Nick Lewicky (since he is the author of the GCOV cod ein Clang, so thanks to him!) and he gave my some guidance. Attached is my resulting patch to current trunk of Clang/LLVM. The code contains some debug output right now that needs to be removed before any possible future inclusion.

I would like to get some feedback on this:

- Do you think it is useful (I hope I can convince you below ;), i.e. would you consider it for inclusion into Clang/LLVM?
- Is my approach correct? Can it be improved upon?
- Are there other large issues to work on?
- Are there smaller issues to work on?

Also there are some questions:

- How can I check whether a member function was defined out-of-class? Currently, incorrect GCNO is generated here.
- Am I missing functions classes that no code is generated for, and: Is there a better way to look for them?
- Can you think of a good way to write tests for this or: How can I write tests for this using any existing Clang test system.
- Can you think of some systematic scheme of functions to generate "dead nodes" for?

Below is a quick description of my motivation and what the patch contains. The patch itself is attached, together with the output of compiling with -ftest-coverage -fprofile-arcs -o gcov_cases2, running the program and then calling gcov on them. The files ending on g++ are the output when compiling with g++, the files ending with clang++ are the output when compiling with patched clang++.

There are two example programs, one where the functions are called (gcov_cases.cpp) and one where no function is called (gcov_cases2.cpp).

Cheers!
Manuel

Motivation -- Why is this useful?

clang.diff (9.53 KB)

gcov_cases.cpp.gcov.clang++ (6.12 KB)

gcov_cases.cpp.gcov.clang++ (6.12 KB)

gcov_cases2.cpp.gcov.clang++ (6.16 KB)

gcov_cases2.cpp.gcov.g++ (6.16 KB)

gcov_cases2.cpp (2.75 KB)

gcov_cases.cpp (2.74 KB)

Dear all,

(first of all: Sorry if there is any confusion because I am not using the right C++/compiler lingo, I'm more of a C++ "consumer" than a language lawyer/expert. I'm interested in any hints or corrections so I can learn, though).

I have done some work on the GCOV instrumentation that allows uninstantiated code (e.g. template functions, in-class defined member methods) to appear in GCOV output.

Just as an aside: is it possible you're conflating "in-class defined
member methods" with "inline functions"? Basically any member function
defined within the class definition is implicitly marked 'inline'. If
there's no call to that function within the current TU, there's no
need to emit that definition (since other TUs will follow this same
rule, since they all have access to the definition & have to rely on
the linker to remove the duplicates anyway).

Knowing this you might be able to generalize your solution to
"templates and inline functions". You /might/ also find that
namespace-scope static (or anonymous namespace) functions don't get
code coverage either - I doubt Clang emits those if there are no calls
to them (though there's a warning for that, since it can be checked at
compile-time - so you probably just want to turn that on).

- David