Dear all,

I would like to instrument uninstantiated C++ function templates. When compiling the program below with the -ftest-coverage and -fprofile- arcs flags, I get according .gcno and .gcda files to run gcov and get a coverage report.

In this report, the line marked with XXX will be marked with "00000" executions. Function g, however, is not instantiated, so the line with YYY will not be reported with any counter by gcov, i.e. it is considered "not executable", similar to comments.

I would like to be able to change this behaviour so non-instantiated code templates are considered as blocks (I think this is the term used by GCC/GCov). This would help me greatly to uncover unused/untested codes in a header/template-only library.

First of all: Is this feasible with the GCC infrastructure?

For this to work, one would probably need access to the internal representation of the program. It is my understanding that there are at least two distinct representations of a C++ program: (1) The AST that only contains the parse tree, before any template instantiation and (2) the intermediate language representation (GIMPLE?) that will contain a representation of the instantiated templates. On which level is coverage instrumentation added right now?

Second: Where would I start looking?

So far, I have discovered gcov*.{h,c} in the gcc directory. However, I have not yet found where the .gcno files are written out in the compiler.

Third: How hard would it be and how would I proceed?

Naively, my first guess at an approach would be: Locate where the .gcno file is written out. After writing out all real blocks, identify all uninitialized template functions, or member functions that are members of templates, etc. etc. Add a "block" to the .gcno file for each such function.

Since the blocks are not connected to the rest of the block graph, they cannot be accessed by the program, there will be no reference to them from the .gcda file and gcov will always report them as not accessed.

Or is there maybe a simpler/better way?

Thanks,
Manuel


template <typename T>
T f(T x)
{
  if (i % 2 == 0)
    return x * 2;  // XXX
  else
    return x * 3;
}

// This function template is never instantiated.
template <typename T>
T g(T x)
{
  return x * 3;  // YYY
}

int main(int argc, char ** argv)
{
  int i = f(1);
  return 0;
}

Reply via email to