Decision Coverage Instrumentation
Decision coverage instrumentation includes function coverage. Additionally, all conditional and unconditional branches and control transfers are instrumented, leading to the use of different counter types.
In the following overview, INCREMENT_JUMP_COUNTER
means that the counter of an explicit control transfer is incremented.
INCREMENT_DECISION_COUNTER(expression)
means that if the expression evaluates to true the corresponding true counter is incremented. If the expression evaluates to false, the corresponding false counter is incremented.
- If Statement
-
if (INCREMENT_DECISION_COUNTER(expression)) ...
- If Statement with Declaration
-
if (int i = expr)...
is logically instrumented as{INCREMENT_FALSE_COUNTER; if (int i = expr){\ DECREMENT_FALSE_COUNTER; INCREMENT_TRUE_COUNTER; ...}
- Else
-
else
does not have a counter, but it is recorded and reported. - While Loop
-
while (INCREMENT_DECISION_COUNTER(expression)) original while-body
- For Loop
-
for (expr1; INCREMENT_DECISION_COUNTER(expression); expr2) original for-body
- Do-While-Loop
-
do original do-body while (INCREMENT_DECISION_COUNTER(expression));
- Special Loop Variants
- The following loops (schematically)
for (var : set) {...} /* in C++11 */ for each (var in set] {...} /* VC++ extension */ foreach (var in set) {...} /* C# */ while (int i = expr) {...} /* C++ */ for (...;int i = expr;...) {...} /* C++ */
are instrumented asloop_header_unchanged { INCREMENT_JUMP_COUNTER; {...}}
For these kind of probes there is one counter telling how many times the loop body has been entered. - Continue Statement
-
{INCREMENT_JUMP_COUNTER; continue;}
Remark: In Java this can also becontinue label;
. - Break Statement
-
{INCREMENT_JUMP_COUNTER; break;}
Remark: In Java this can also bebreak label;
. - Goto Statement
-
{INCREMENT_JUMP_COUNTER; goto label;}
- Label
-
label:
Labels do not have a counter, but they are recorded and displayed in the Execution Profile Listing. If the label was reached by a jump, it is marked with a "+" sign. - Return Statement
-
{INCREMENT_JUMP_COUNTER; return [expression_if_any];}
- Switch Statement
-
switch(expression)
There is no counter inserted, butswitch
is recorded and reported. - Case Label (and Default)
-
goto over; /* for fall through */ case expression: INCREMENT_JUMP_COUNTER; over:
With that construction, the corresponding counter is only incremented if the implicit decisionswitch-expression == case-value
is true. A default label is treated the same way, and also a missing default branch is instrumented and has to be tested. - Ternary Operator
-
INCREMENT_DECISION_COUNTER(expr1) ? expr2 : expr3
- Try Statement
-
try { /* in C++ */ INCREMENT_START_COUNTER; {original body} } __try { /* supported in some C environments */ INCREMENT_START_COUNTER; {original body} }
- Throw Statement
-
{INCREMENT_JUMP_COUNTER; throw expression;} {INCREMENT_JUMP_COUNTER; __leave;} /* supported in some C environments */
- Catch Statement
-
catch (declaration) { /* in C++ */ INCREMENT_JUMP_COUNTER; {original body} } __except (filter_expression) {/*some C environments*/ INCREMENT_JUMP_COUNTER; {original body} } __finally { /* some C environments */ INCREMENT_JUMP_COUNTER; {original body} }
- Function end brace
- For void functions with reachable end, the function end is instrumented as
... /* function body */ INCREMENT_JUMP_COUNTER; }
The question if the end is reachable is answered by a simple heuristic approach. In case of doubt, it is instrumented. - Lambda Function in Global Scope
-
A lambda function in global scope (or at "file-level", i.e. outside of functions), e.g. like
... auto n = [](int i){return i + 1;}; ...
is instrumented like a normal function. As the function name in an execution profile listing there is "FUNCTION lambda-[]()". - Lambda Function Inside a Function
-
A lambda function inside a function, e.g. like
a = b + [c]{if (c > 5) return 5; else return 6;}() + d;
is also instrumented. However nested lambda functions are not instrumented. In an execution profile listing there is a marking “lambda-[]()” at the beginning of a function-internal lambda, and its end is marked with “}”. The execution hits of a function-internal lambda function are counted to its enclosing function. - User Defined Counter
-
If the pragma
CTC COUNT
is used to add a counter, it is instrumented asINCREMENT_JUMP_COUNTER; #pragma CTC COUNT token_sequence