lcov icon indicating copy to clipboard operation
lcov copied to clipboard

Allow lcov exclusion markers inside macros

Open pwithnall opened this issue 7 years ago • 8 comments

In GLib, there are a couple of macros which are used to implement preconditions on user functions, called g_return_if_fail(), g_return_val_if_fail(), g_return_if_reached(), etc. These expand out to an ‘if’ statement with one branch which is expected to always be taken, and the other branch which is expected to never be taken, and which shouldn’t be tested for in test cases because testing the preconditions for every user function would be a waste of time.

It would be nice if lcov supported using LCOV_EXCL_* inside the macro definitions so that the second branch was ignored in every instance of the macros without having to annotate them all separately.

(This was originally reported as https://sourceforge.net/p/ltp/feature-requests/8/.)

pwithnall avatar Oct 05 '18 17:10 pwithnall

I don't think this is possible. Not only would lcov have to expand those macros in order to understand whether a line/branch should be excluded, comments are also removed by the preprocessor. So there's no way to put this info into a macro.

The better alternative might be to configure the exclusion markers to also match these macro names. The lcovrc man page suggests something like this should work:

lcov_excl_br_line = LCOV_EXCL_BR_LINE|g_return_if_fail|g_return_val_if_fail

(and so on for all the macro names)

latk avatar Oct 05 '18 17:10 latk

I’ll give that a go, thanks. The downside of that is that every project which uses those macros from GLib (which is a lot of projects) will have to learn about and copy the same lcovrc configuration when they do code coverage, which seems highly redundant. I don’t think any project would ever reasonably want to have coverage of the branches in those macros — they’re essentially equivalent to assert().

pwithnall avatar Oct 05 '18 21:10 pwithnall

What about using the _Pragma() C99 / C++11 preprocessor command for this? For example, lcov could support detectings things like

#pragma LCOV EXCL_START

in addition to comments. Unlike with comments, the preprocessor preserves these in the output (but yes, it would still need to look into the preprocessor output for these, which I'm not sure it is doing already). The macro could then look like this:

#define g_return_if_fail(expr) \
    _Pragma("LCOV EXCL_START") \
    do { if(!(expr)) ... } while(0) \
    _Pragma("LCOV EXCL_STOP")

Of course, this will make GCC complain on -Wall, so with the warning suppressed it becomes a bit hairy:

#define g_return_if_fail(expr) \
    _Pragma("GCC diagnostic push") \ 
    _Pragma("GCC diagnostic ignored \"-Wunknown-pragmas\"") \
    _Pragma("LCOV EXCL_START") \
    do { if(!(expr)) ... } while(0) \
    _Pragma("LCOV EXCL_STOP") \
    _Pragma("GCC diagnostic pop")

Opinions? :)

mosra avatar Nov 23 '18 11:11 mosra

LCOV does not look at preprocessed code output, only at the original source code files associated with each coverage data file (.gcda). I don't see a feasible way to implement this feature in LCOV.

Maybe this could be added to GCC? Adding @marxin to the discussion: Is the ability to mark code as to be excluded from code coverage measurements something that could be implemented in GCC?

oberpar avatar Mar 01 '19 15:03 oberpar

Maybe this could be added to GCC? Adding @marxin to the discussion: Is the ability to mark code as to be excluded from code coverage measurements something that could be implemented in GCC?

One can use no_instrument_function function attribute for the else branch in a macro. That should skip instrumentation. That's what I can offer.

marxin avatar Mar 04 '19 08:03 marxin

Any progress on this issue?

feliwir avatar Oct 31 '19 10:10 feliwir

Still no progress?

B-HWD avatar Apr 13 '21 21:04 B-HWD

Just noticing/revisiting this issue.

I believe that @latk 's comment above is the best approach given that neither gcc nor llvm are likely to make the required enhancements to support the feature, and that lcov/geninfo/genhtml are rather simple tools and are not likely to become full-fledged compilers.

@pwithnall is also correct: all projects that want to use this feature will have to learn about it :-( If this is a serious problem - then we could either add the required exclusion regexps to the lcovrc shipped with lcov releases (either in a commented out section or as is) - or a (brief) discussion of this issue could be added to the man page.

Now that we allow multiple RC files (see the --config-file option in the man page): we could add all of these typical/recommended exclusions to another RC file that we also include with the release - and add a corresponding discussion to the man pages.

What do people think?

Henry

henry2cox avatar May 17 '23 11:05 henry2cox