Skip to content

Commit d5cab1c

Browse files
committed
Fix basic block coverage with unsatisfiable ASSUME statements
Insert coverage assertions at the end of basic blocks instead of the beginning to ensure blocks are only marked as covered when all instructions, including ASSUME statements, can be executed. Fixes: #826
1 parent 4fe3ade commit d5cab1c

File tree

3 files changed

+12
-5
lines changed

3 files changed

+12
-5
lines changed

src/goto-instrument/cover_basic_blocks.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ cover_basic_blockst::cover_basic_blockst(const goto_programt &goto_program)
6363
else
6464
{
6565
block_infos.emplace_back();
66+
// representative_inst will be updated to the last instruction
6667
block_infos.back().representative_inst = it;
6768
block_infos.back().source_location = source_locationt::nil();
6869
current_block = block_infos.size() - 1;
@@ -77,15 +78,17 @@ cover_basic_blockst::cover_basic_blockst(const goto_programt &goto_program)
7778

7879
add_block_lines(block_info, *it);
7980

80-
// set representative program location to instrument
81+
// Update representative instruction to always be the last instruction
82+
block_info.representative_inst = it;
83+
84+
// set source location for reporting (from first instruction with valid location)
8185
if(
8286
!it->source_location().is_nil() &&
8387
!it->source_location().get_file().empty() &&
8488
!it->source_location().get_line().empty() &&
8589
!it->source_location().is_built_in() &&
8690
block_info.source_location.is_nil())
8791
{
88-
block_info.representative_inst = it; // update
8992
block_info.source_location = it->source_location();
9093
}
9194

src/goto-instrument/cover_basic_blocks.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ class cover_basic_blockst final : public cover_blocks_baset
7474

7575
/// \param block_nr: a block number
7676
/// \return the instruction selected for
77-
/// instrumentation representative of the given block
77+
/// instrumentation representative of the given block (last instruction)
7878
std::optional<goto_programt::const_targett>
7979
instruction_of(std::size_t block_nr) const override;
8080

@@ -109,7 +109,7 @@ class cover_basic_blockst final : public cover_blocks_baset
109109

110110
struct block_infot
111111
{
112-
/// the program location to instrument for this block
112+
/// the program location to instrument for this block (last instruction)
113113
std::optional<goto_programt::const_targett> representative_inst;
114114

115115
/// the source location representative for this block

src/goto-instrument/cover_instrument_location.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,12 @@ void cover_location_instrumentert::instrument(
2525
i_it->turn_into_skip();
2626

2727
const std::size_t block_nr = basic_blocks.block_of(i_it);
28+
29+
// The representative instruction is the last instruction in the block,
30+
// ensuring all instructions (including any ASSUME statements) can be executed.
2831
const auto representative_instruction = basic_blocks.instruction_of(block_nr);
29-
// we only instrument the selected instruction
32+
33+
// we only instrument the selected instruction (last in block)
3034
if(representative_instruction && *representative_instruction == i_it)
3135
{
3236
const std::string b = std::to_string(block_nr + 1); // start with 1

0 commit comments

Comments
 (0)