Skip to content

Latest commit

 

History

History
93 lines (72 loc) · 4.47 KB

separate_cov.rst

File metadata and controls

93 lines (72 loc) · 4.47 KB

Separated coverage on generics

As described in section :ref:`generics_cov`, a single coverage analysis of any source construct is performed by default, consolidating all code copies generated by this construct. For subprograms, this means consolidation over all inlined copies. For generic units, consolidation over all instances.

A finer-grained analysis is possible, where distinct copies of the code coming from a given source construct are identified according to some criterion, and a separate coverage assessment is made for each of these copies.

In this case, coverage violations carry an additional indication of which code copy the violation is reported for, available in all but the non-extended xcov and html output formats. The non-extended xcov and html formats simply convey partial coverage achievement on a line as soon one violation get reported for an obligation on that line, regardless of which copy the violation originates from.

|gcv| supports different modes for such analyses, detailed in the following subsections.

Separation by instance (:cmd-option:`-S instance`)

In this mode, two code regions coming from the same source construct will undergo separate coverage analyses if they come from different generic instances, identified by the instanciation source location.

For our Vops example, selecting an output format where the violations detailed are exposed, this translates as:

gnatcov coverage -Pvops.gpr --annotate=report -S instance [...]
...
vops.adb:5:11: statement not executed (from v8.ads:2:1)
vops.adb:6:10: statement not executed (from v8.ads:2:1)
vops.adb:12:11: statement not executed (from v5.ads:2:1)
vops.adb:13:10: statement not executed (from v5.ads:2:1)

We do observe violations on the Vops generic body, fully covered without :cmd-option:`-S instance`. This is the outcome of an analysis conducted on the two generic instances separately, each designated by a (from <instantiation source location>) indication.

|gcv| needs to see the coverage obligations corresponding to each instance in this mode. This is achieved transparently by the use of a project file in the example command lines we quoted and needs particular care when the Library Information files are provided manually with :cmd-option:`--scos` instead.

Indeed, even if we aim at getting coverage results for the vops.adb source, passing :cmd-option:`--scos=vops.ali` alone isn't enough when per instance separate analysis is desired. Separate coverage analysis for the instances entails coverage obligations for the instances, and this requires the units where the instantiations occur to be declared of interest as well. In our example, this means passing :cmd-option:`--scos=v5.ali` and :cmd-option:`--scos=v8.ali` in addition.

Separation by instance relies on specific compiler support available in the GNAT Pro toolchain since the 7.2 release. For older toolchains, another mode is available which reports separate coverage statuses for copies associated with distinct symbols of the executable file. As we will describe, this provides a good approximation of per-instance analysis in absence of inlining, and becomes inaccurate when inlining comes into play.

Separation by routine (:cmd-option:`-S routine`, obsolete)

In this mode, two code regions coming from the same source construct will undergo separate coverage analyses if they occur in different symbols of the executable file. This scheme is obsolete, unreliable in presence of inlining.

When a given subprogram is inlined in two different calling routines, each inlined copy thus undergoes a separate coverage assessment. In the absence of inlining, this will also ensure that different instances of the same generic unit will have separated coverage analyses, since the compiler generates different symbol names for different program units. For our Vops example, this would be:

gnatcov coverage -Pvops.gpr --annotate=report -S routine [...]
...
vops.adb:5:11: statement not executed (from v8__inc)
vops.adb:6:10: statement not executed (from v8__inc)
vops.adb:12:11: statement not executed (from v5__mult)
vops.adb:13:10: statement not executed (from v5__mult)

On the other hand, if two distinct instances of a generic subprogram are inlined within a single calling routine, they will undergo a single coverage analysis since they now occur in the same symbol.