Skip to content

Commit 3fec6e1

Browse files
Merge pull request #5635 from thomasspriggs/tas/expression_coverage
Make location coverage reported include all lines of a multi-line statement
2 parents 10fc2b9 + b156c8f commit 3fec6e1

File tree

7 files changed

+98
-10
lines changed

7 files changed

+98
-10
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
2+
*
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#include <stdlib.h>
2+
3+
int foo(int x, int y)
4+
{
5+
return x;
6+
}
7+
8+
int main()
9+
{
10+
int *ptr = malloc(sizeof(*ptr));
11+
12+
// clang-format off
13+
foo(1,
14+
*ptr);
15+
// clang-format on
16+
17+
if(0)
18+
{
19+
*ptr = 0;
20+
}
21+
22+
return 0;
23+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#include <stdlib.h>
2+
3+
int foo(int x, int y)
4+
{
5+
return x;
6+
}
7+
8+
int main()
9+
{
10+
int *ptr = malloc(sizeof(*ptr));
11+
12+
// clang-format off
13+
foo(
14+
1,
15+
#include "dereference.h"
16+
ptr);
17+
// clang-format on
18+
19+
if(0)
20+
{
21+
*ptr = 0;
22+
}
23+
24+
return 0;
25+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
CORE
2+
multi-file.c
3+
--cover location
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
^\[main.coverage.2\] file multi-file.c line 10 function main block 2 \(lines [\w\- /\.\\:]*dereference.h:main:2; multi-file.c:main:10,13,14,16\): SATISFIED
7+
--
8+
^warning: ignoring
9+
--
10+
Test that the lines covered by location coverage in the output include all lines
11+
of a multi-line statement where some of the lines are in an included file.
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
CORE
2+
example.c
3+
--cover location
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
^\[main.coverage.2\] file example.c line 10 function main block 2 \(lines example.c:main:10,13,14\): SATISFIED$
7+
--
8+
^warning: ignoring
9+
--
10+
Test that the lines covered by location coverage in the output include all lines
11+
of a multi-line statement.

src/goto-instrument/cover_basic_blocks.cpp

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,12 @@ optionalt<std::size_t> cover_basic_blockst::continuation_of_block(
2929
return {};
3030
}
3131

32-
cover_basic_blockst::cover_basic_blockst(const goto_programt &_goto_program)
32+
cover_basic_blockst::cover_basic_blockst(const goto_programt &goto_program)
3333
{
3434
bool next_is_target = true;
3535
std::size_t current_block = 0;
3636

37-
forall_goto_program_instructions(it, _goto_program)
37+
forall_goto_program_instructions(it, goto_program)
3838
{
3939
// Is it a potential beginning of a block?
4040
if(next_is_target || it->is_target())
@@ -58,13 +58,7 @@ cover_basic_blockst::cover_basic_blockst(const goto_programt &_goto_program)
5858

5959
block_map[it] = current_block;
6060

61-
// update lines belonging to block
62-
const irep_idt &line = it->source_location.get_line();
63-
if(!line.empty())
64-
{
65-
block_info.lines.insert(unsafe_string2unsigned(id2string(line)));
66-
block_info.source_lines.insert(it->source_location);
67-
}
61+
add_block_lines(block_info, *it);
6862

6963
// set representative program location to instrument
7064
if(
@@ -155,6 +149,23 @@ void cover_basic_blockst::output(std::ostream &out) const
155149
<< '\n';
156150
}
157151

152+
void cover_basic_blockst::add_block_lines(
153+
cover_basic_blockst::block_infot &block,
154+
const goto_programt::instructiont &instruction)
155+
{
156+
const auto &add_location = [&](const source_locationt &location) {
157+
const irep_idt &line = location.get_line();
158+
if(!line.empty())
159+
{
160+
block.lines.insert(unsafe_string2unsigned(id2string(line)));
161+
block.source_lines.insert(location);
162+
}
163+
};
164+
add_location(instruction.source_location);
165+
instruction.code.visit_pre(
166+
[&](const exprt &expr) { add_location(expr.source_location()); });
167+
}
168+
158169
void cover_basic_blockst::update_covered_lines(block_infot &block_info)
159170
{
160171
if(block_info.source_location.is_nil())

src/goto-instrument/cover_basic_blocks.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ class cover_blocks_baset
6363
class cover_basic_blockst final : public cover_blocks_baset
6464
{
6565
public:
66-
explicit cover_basic_blockst(const goto_programt &_goto_program);
66+
explicit cover_basic_blockst(const goto_programt &goto_program);
6767

6868
/// \param t: a goto instruction
6969
/// \return the block number of the block
@@ -119,6 +119,11 @@ class cover_basic_blockst final : public cover_blocks_baset
119119
/// map block numbers to block information
120120
std::vector<block_infot> block_infos;
121121

122+
/// Adds the lines which \param instruction spans to \param block.
123+
static void add_block_lines(
124+
cover_basic_blockst::block_infot &block,
125+
const goto_programt::instructiont &instruction);
126+
122127
/// create list of covered lines as CSV string and set as property of source
123128
/// location of basic block, compress to ranges if applicable
124129
static void update_covered_lines(block_infot &block_info);

0 commit comments

Comments
 (0)