@@ -29,15 +29,34 @@ optionalt<std::size_t> cover_basic_blockst::continuation_of_block(
29
29
return {};
30
30
}
31
31
32
+ static bool
33
+ same_source_line (const source_locationt &a, const source_locationt &b)
34
+ {
35
+ return a.get_file () == b.get_file () && a.get_line () == b.get_line ();
36
+ }
37
+
32
38
cover_basic_blockst::cover_basic_blockst (const goto_programt &goto_program)
33
39
{
34
40
bool next_is_target = true ;
41
+ const goto_programt::instructiont *preceding_assume = nullptr ;
35
42
std::size_t current_block = 0 ;
36
43
37
44
forall_goto_program_instructions (it, goto_program)
38
45
{
46
+ // For the purposes of coverage blocks, multiple consecutive assume
47
+ // instructions with the same source location are considered to be part of
48
+ // the same block. Assumptions should terminate a block, as subsequent
49
+ // instructions may be unreachable. However check instrumentation passes
50
+ // may insert multiple assertions in the same program location. Therefore
51
+ // these are combined for reasons of readability of the coverage output.
52
+ bool end_of_assume_group =
53
+ preceding_assume &&
54
+ !(it->is_assume () &&
55
+ same_source_line (
56
+ preceding_assume->source_location (), it->source_location ()));
57
+
39
58
// Is it a potential beginning of a block?
40
- if (next_is_target || it->is_target ())
59
+ if (next_is_target || it->is_target () || end_of_assume_group )
41
60
{
42
61
if (auto block_number = continuation_of_block (it, block_map))
43
62
{
@@ -72,13 +91,8 @@ cover_basic_blockst::cover_basic_blockst(const goto_programt &goto_program)
72
91
block_info.source_location = it->source_location ();
73
92
}
74
93
75
- next_is_target =
76
- #if 0
77
- // Disabled for being too messy
78
- it->is_goto() || it->is_function_call() || it->is_assume();
79
- #else
80
- it->is_goto () || it->is_function_call ();
81
- #endif
94
+ next_is_target = it->is_goto () || it->is_function_call ();
95
+ preceding_assume = it->is_assume () ? &*it : nullptr ;
82
96
}
83
97
}
84
98
0 commit comments