Skip to content

Commit 092328c

Browse files
committed
Remove basic_block_covered_lines
The information in basic_block_source_lines is much more accurate for it distinguishes source lines belonging to different files or functions (which may still end up in the same basic block after inlining).
1 parent 8a41865 commit 092328c

File tree

8 files changed

+35
-75
lines changed

8 files changed

+35
-75
lines changed

jbmc/regression/jdiff/java-properties/test.desc

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,6 @@ old.jar --json-ui --show-properties --cover location
55
activate-multi-line-match
66
^EXIT=0$
77
^SIGNAL=0$
8-
"deletedFunctions": \[\n \{\n "name": "java::Test.obsolete:\(\)V",\n "properties": \[\n \{\n "class": "coverage",\n "coveredLines": "18",\n "description": "block 1 \(lines Test.java:java::Test.obsolete:\(\)V:18\)",\n "expression": "false",\n "name": "java::Test.obsolete:\(\)V.coverage.1",\n "sourceLocation": \{\n "bytecodeIndex": "0",\n "file": "Test.java",\n "function": "java::Test.obsolete:\(\)V",\n "line": "18"\n }\n }\n ],\n "sourceLocation": \{\n "file": "Test.java",\n "function": "java::Test.obsolete:\(\)V",\n "line": "18"\n }\n }\n ],\n "modifiedFunctions": \[\n \{\n "name": "java::Test.<init>:\(\)V",\n "properties": \[\n \{\n "class": "coverage",\n "coveredLines": "6",\n "description": "block 2 \(lines Test.java:java::Test.<init>:\(\)V:6\)",\n "expression": "false",\n "name": "java::Test.<init>:\(\)V.coverage.1",\n "sourceLocation": \{\n "bytecodeIndex": "1",\n "file": "Test.java",\n "function": "java::Test.<init>:\(\)V",\n "line": "6"\n }\n },\n \{\n "class": "coverage",\n "coveredLines": "4",\n "description": "block 3 \(lines Test.java:java::Test.<init>:\(\)V:4\)",\n "expression": "false",\n "name": "java::Test.<init>:\(\)V.coverage.2",\n "sourceLocation": \{\n "bytecodeIndex": "3",\n "file": "Test.java",\n "function": "java::Test.<init>:\(\)V",\n "line": "4"\n }\n },\n \{\n "class": "coverage",\n "coveredLines": "4",\n "description": "block 4 \(lines Test.java:java::Test.<init>:\(\)V:4\)",\n "expression": "false",\n "name": "java::Test.<init>:\(\)V.coverage.3",\n "sourceLocation": \{\n "bytecodeIndex": "5",\n "file": "Test.java",\n "function": "java::Test.<init>:\(\)V",\n "line": "4"\n }\n },\n \{\n "class": "coverage",\n "coveredLines": "4",\n "description": "block 5 \(lines Test.java:java::Test.<init>:\(\)V:4\)",\n "expression": "false",\n "name": "java::Test.<init>:\(\)V.coverage.4",\n "sourceLocation": \{\n "bytecodeIndex": "6",\n "file": "Test.java",\n "function": "java::Test.<init>:\(\)V",\n "line": "4"\n }\n },\n \{\n "class": "coverage",\n "coveredLines": "7",\n "description": "block 6 \(lines Test.java:java::Test.<init>:\(\)V:7\)",\n "expression": "false",\n "name": "java::Test.<init>:\(\)V.coverage.5",\n "sourceLocation": \{\n "bytecodeIndex": "7",\n "file": "Test.java",\n "function": "java::Test.<init>:\(\)V",\n "line": "7"\n }\n }\n ],\n "sourceLocation": \{\n "file": "Test.java",\n "function": "java::Test.<init>:\(\)V",\n "line": "6"\n }\n },\n \{\n "name": "java::Test.<clinit>:\(\)V",\n "properties": \[\n \{\n "class": "coverage",\n "coveredLines": "3",\n "description": "block 1 \(lines Test.java:java::Test.<clinit>:\(\)V:3\)",\n "expression": "false",\n "name": "java::Test.<clinit>:\(\)V.coverage.1",\n "sourceLocation": \{\n "bytecodeIndex": "1",\n "file": "Test.java",\n "function": "java::Test.<clinit>:\(\)V",\n "line": "3"\n }\n }\n ],\n "sourceLocation": \{\n "file": "Test.java",\n "function": "java::Test.<clinit>:\(\)V",\n "line": "3"\n }\n }\n ],\n "newFunctions": \[\n \{\n "name": "java::Test.newfun:\(\)V",\n "properties": \[\n \{\n "class": "coverage",\n "coveredLines": "18",\n "description": "block 1 \(lines Test.java:java::Test.newfun:\(\)V:18\)",\n "expression": "false",\n "name": "java::Test.newfun:\(\)V.coverage.1",\n "sourceLocation": \{\n "bytecodeIndex": "0",\n "file": "Test.java",\n "function": "java::Test.newfun:\(\)V",\n "line": "18"\n }\n }\n ],\n "sourceLocation": \{\n "file": "Test.java",\n "function": "java::Test.newfun:\(\)V",\n "line": "18"\n }\n }\n ],\n
8+
"deletedFunctions": \[\n \{\n "name": "java::Test.obsolete:\(\)V",\n "properties": \[\n \{\n "class": "coverage",\n "coveredLines": "Test.java:java::Test.obsolete:\(\)V:18",\n "description": "block 1 \(lines Test.java:java::Test.obsolete:\(\)V:18\)",\n "expression": "false",\n "name": "java::Test.obsolete:\(\)V.coverage.1",\n "sourceLocation": \{\n "bytecodeIndex": "0",\n "file": "Test.java",\n "function": "java::Test.obsolete:\(\)V",\n "line": "18"\n }\n }\n ],\n "sourceLocation": \{\n "file": "Test.java",\n "function": "java::Test.obsolete:\(\)V",\n "line": "18"\n }\n }\n ],\n "modifiedFunctions": \[\n \{\n "name": "java::Test.<init>:\(\)V",\n "properties": \[\n \{\n "class": "coverage",\n "coveredLines": "Test.java:java::Test.<init>:\(\)V:6",\n "description": "block 2 \(lines Test.java:java::Test.<init>:\(\)V:6\)",\n "expression": "false",\n "name": "java::Test.<init>:\(\)V.coverage.1",\n "sourceLocation": \{\n "bytecodeIndex": "1",\n "file": "Test.java",\n "function": "java::Test.<init>:\(\)V",\n "line": "6"\n }\n },\n \{\n "class": "coverage",\n "coveredLines": "Test.java:java::Test.<init>:\(\)V:4",\n "description": "block 3 \(lines Test.java:java::Test.<init>:\(\)V:4\)",\n "expression": "false",\n "name": "java::Test.<init>:\(\)V.coverage.2",\n "sourceLocation": \{\n "bytecodeIndex": "3",\n "file": "Test.java",\n "function": "java::Test.<init>:\(\)V",\n "line": "4"\n }\n },\n \{\n "class": "coverage",\n "coveredLines": "Test.java:java::Test.<init>:\(\)V:4",\n "description": "block 4 \(lines Test.java:java::Test.<init>:\(\)V:4\)",\n "expression": "false",\n "name": "java::Test.<init>:\(\)V.coverage.3",\n "sourceLocation": \{\n "bytecodeIndex": "5",\n "file": "Test.java",\n "function": "java::Test.<init>:\(\)V",\n "line": "4"\n }\n },\n \{\n "class": "coverage",\n "coveredLines": "Test.java:java::Test.<init>:\(\)V:4",\n "description": "block 5 \(lines Test.java:java::Test.<init>:\(\)V:4\)",\n "expression": "false",\n "name": "java::Test.<init>:\(\)V.coverage.4",\n "sourceLocation": \{\n "bytecodeIndex": "6",\n "file": "Test.java",\n "function": "java::Test.<init>:\(\)V",\n "line": "4"\n }\n },\n \{\n "class": "coverage",\n "coveredLines": "Test.java:java::Test.<init>:\(\)V:7",\n "description": "block 6 \(lines Test.java:java::Test.<init>:\(\)V:7\)",\n "expression": "false",\n "name": "java::Test.<init>:\(\)V.coverage.5",\n "sourceLocation": \{\n "bytecodeIndex": "7",\n "file": "Test.java",\n "function": "java::Test.<init>:\(\)V",\n "line": "7"\n }\n }\n ],\n "sourceLocation": \{\n "file": "Test.java",\n "function": "java::Test.<init>:\(\)V",\n "line": "6"\n }\n },\n \{\n "name": "java::Test.<clinit>:\(\)V",\n "properties": \[\n \{\n "class": "coverage",\n "coveredLines": "Test.java:java::Test.<clinit>:\(\)V:3",\n "description": "block 1 \(lines Test.java:java::Test.<clinit>:\(\)V:3\)",\n "expression": "false",\n "name": "java::Test.<clinit>:\(\)V.coverage.1",\n "sourceLocation": \{\n "bytecodeIndex": "1",\n "file": "Test.java",\n "function": "java::Test.<clinit>:\(\)V",\n "line": "3"\n }\n }\n ],\n "sourceLocation": \{\n "file": "Test.java",\n "function": "java::Test.<clinit>:\(\)V",\n "line": "3"\n }\n }\n ],\n "newFunctions": \[\n \{\n "name": "java::Test.newfun:\(\)V",\n "properties": \[\n \{\n "class": "coverage",\n "coveredLines": "Test.java:java::Test.newfun:\(\)V:18",\n "description": "block 1 \(lines Test.java:java::Test.newfun:\(\)V:18\)",\n "expression": "false",\n "name": "java::Test.newfun:\(\)V.coverage.1",\n "sourceLocation": \{\n "bytecodeIndex": "0",\n "file": "Test.java",\n "function": "java::Test.newfun:\(\)V",\n "line": "18"\n }\n }\n ],\n "sourceLocation": \{\n "file": "Test.java",\n "function": "java::Test.newfun:\(\)V",\n "line": "18"\n }\n }\n ],\n
99
--
1010
^warning: ignoring

jbmc/unit/java_bytecode/java_virtual_functions/virtual_functions.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -159,12 +159,12 @@ SCENARIO(
159159
// instruction with a new bytecode index begins with ASSERT
160160
REQUIRE(it->type() == goto_program_instruction_typet::ASSERT);
161161
// the assertion corresponds to a line coverage goal
162-
REQUIRE_FALSE(loc.get_basic_block_covered_lines().empty());
162+
REQUIRE_FALSE(loc.get_basic_block_source_lines().empty());
163163
}
164164
else
165165
{
166166
// there is no line coverage goal in the middle of a block
167-
REQUIRE(loc.get_basic_block_covered_lines().empty());
167+
REQUIRE(loc.get_basic_block_source_lines().empty());
168168
}
169169

170170
++it;

src/goto-instrument/cover_basic_blocks.cpp

+14-44
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,7 @@ Author: Peter Schrammel
1111

1212
#include "cover_basic_blocks.h"
1313

14-
#include <util/format_number_range.h>
1514
#include <util/message.h>
16-
#include <util/string2int.h>
1715

1816
optionalt<std::size_t> cover_basic_blockst::continuation_of_block(
1917
const goto_programt::const_targett &instruction,
@@ -80,12 +78,6 @@ cover_basic_blockst::cover_basic_blockst(const goto_programt &goto_program)
8078
it->is_goto() || it->is_function_call();
8179
#endif
8280
}
83-
84-
for(auto &block_info : block_infos)
85-
{
86-
update_covered_lines(block_info);
87-
update_source_lines(block_info);
88-
}
8981
}
9082

9183
std::size_t cover_basic_blockst::block_of(goto_programt::const_targett t) const
@@ -109,6 +101,13 @@ cover_basic_blockst::source_location_of(const std::size_t block_nr) const
109101
return block_infos[block_nr].source_location;
110102
}
111103

104+
const source_linest &
105+
cover_basic_blockst::source_lines_of(const std::size_t block_nr) const
106+
{
107+
INVARIANT(block_nr < block_infos.size(), "block number out of range");
108+
return block_infos[block_nr].source_lines;
109+
}
110+
112111
void cover_basic_blockst::report_block_anomalies(
113112
const irep_idt &function_id,
114113
const goto_programt &goto_program,
@@ -158,7 +157,6 @@ void cover_basic_blockst::add_block_lines(
158157
const irep_idt &line = location.get_line();
159158
if(!line.empty())
160159
{
161-
block.lines.insert(unsafe_string2unsigned(id2string(line)));
162160
block.source_lines.insert(location);
163161
}
164162
};
@@ -167,35 +165,9 @@ void cover_basic_blockst::add_block_lines(
167165
[&](const exprt &expr) { add_location(expr.source_location()); });
168166
}
169167

170-
void cover_basic_blockst::update_covered_lines(block_infot &block_info)
171-
{
172-
if(block_info.source_location.is_nil())
173-
return;
174-
175-
const auto &cover_set = block_info.lines;
176-
INVARIANT(!cover_set.empty(), "covered lines set must not be empty");
177-
std::vector<unsigned> line_list(cover_set.begin(), cover_set.end());
178-
179-
std::string covered_lines = format_number_range(line_list);
180-
block_info.source_location.set_basic_block_covered_lines(covered_lines);
181-
}
182-
183-
void cover_basic_blockst::update_source_lines(block_infot &block_info)
184-
{
185-
if(block_info.source_location.is_nil())
186-
return;
187-
188-
const auto &source_lines = block_info.source_lines;
189-
std::string str = source_lines.to_string();
190-
INVARIANT(!str.empty(), "source lines set must not be empty");
191-
block_info.source_location.set_basic_block_source_lines(str);
192-
}
193-
194168
cover_basic_blocks_javat::cover_basic_blocks_javat(
195169
const goto_programt &_goto_program)
196170
{
197-
std::set<std::size_t> source_lines_requiring_update;
198-
199171
forall_goto_program_instructions(it, _goto_program)
200172
{
201173
const auto &location = it->source_location();
@@ -205,22 +177,13 @@ cover_basic_blocks_javat::cover_basic_blocks_javat(
205177
{
206178
block_infos.push_back(it);
207179
block_locations.push_back(location);
208-
block_locations.back().set_basic_block_covered_lines(location.get_line());
209180
block_source_lines.emplace_back(location);
210-
source_lines_requiring_update.insert(entry.first->second);
211181
}
212182
else
213183
{
214184
block_source_lines[entry.first->second].insert(location);
215-
source_lines_requiring_update.insert(entry.first->second);
216185
}
217186
}
218-
219-
for(std::size_t i : source_lines_requiring_update)
220-
{
221-
block_locations.at(i).set_basic_block_source_lines(
222-
block_source_lines.at(i).to_string());
223-
}
224187
}
225188

226189
std::size_t
@@ -246,6 +209,13 @@ cover_basic_blocks_javat::source_location_of(const std::size_t block_nr) const
246209
return block_locations[block_nr];
247210
}
248211

212+
const source_linest &
213+
cover_basic_blocks_javat::source_lines_of(const std::size_t block_nr) const
214+
{
215+
PRECONDITION(block_nr < block_locations.size());
216+
return block_source_lines[block_nr];
217+
}
218+
249219
void cover_basic_blocks_javat::output(std::ostream &out) const
250220
{
251221
for(std::size_t i = 0; i < block_locations.size(); ++i)

src/goto-instrument/cover_basic_blocks.h

+12-11
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ class cover_blocks_baset
4343
virtual const source_locationt &
4444
source_location_of(std::size_t block_nr) const = 0;
4545

46+
/// \param block_nr: a block number
47+
/// \return the source lines of the given block
48+
virtual const source_linest &source_lines_of(std::size_t block_nr) const = 0;
49+
4650
/// Outputs the list of blocks
4751
virtual void output(std::ostream &out) const = 0;
4852

@@ -84,6 +88,10 @@ class cover_basic_blockst final : public cover_blocks_baset
8488
const source_locationt &
8589
source_location_of(std::size_t block_nr) const override;
8690

91+
/// \param block_nr: a block number
92+
/// \return the source lines of the given block
93+
const source_linest &source_lines_of(std::size_t block_nr) const override;
94+
8795
/// Output warnings about ignored blocks
8896
/// \param function_id: name of \p goto_program
8997
/// \param goto_program: The goto program
@@ -109,9 +117,6 @@ class cover_basic_blockst final : public cover_blocks_baset
109117
/// the line number ranges to them)
110118
source_locationt source_location;
111119

112-
/// the set of lines belonging to this block
113-
std::unordered_set<std::size_t> lines;
114-
115120
/// the set of source code lines belonging to this block
116121
source_linest source_lines;
117122
};
@@ -126,14 +131,6 @@ class cover_basic_blockst final : public cover_blocks_baset
126131
cover_basic_blockst::block_infot &block,
127132
const goto_programt::instructiont &instruction);
128133

129-
/// create list of covered lines as CSV string and set as property of source
130-
/// location of basic block, compress to ranges if applicable
131-
static void update_covered_lines(block_infot &block_info);
132-
133-
/// create a string representing source lines and set as a property of source
134-
/// location of basic block
135-
static void update_source_lines(block_infot &block_info);
136-
137134
/// If this block is a continuation of a previous block through unconditional
138135
/// forward gotos, return this blocks number.
139136
static optionalt<std::size_t> continuation_of_block(
@@ -170,6 +167,10 @@ class cover_basic_blocks_javat final : public cover_blocks_baset
170167
const source_locationt &
171168
source_location_of(std::size_t block_number) const override;
172169

170+
/// \param block_number: a block number
171+
/// \return the source lines of the given block
172+
const source_linest &source_lines_of(std::size_t block_number) const override;
173+
173174
/// Outputs the list of blocks
174175
void output(std::ostream &out) const override;
175176
};

src/goto-instrument/cover_instrument_location.cpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,15 @@ void cover_location_instrumentert::instrument(
3131
{
3232
const std::string b = std::to_string(block_nr + 1); // start with 1
3333
const std::string id = id2string(function_id) + "#" + b;
34-
const auto source_location = basic_blocks.source_location_of(block_nr);
34+
auto source_location = basic_blocks.source_location_of(block_nr);
3535

3636
// filter goals
3737
if(goal_filters(source_location))
3838
{
39-
const std::string source_lines =
40-
id2string(source_location.get_basic_block_source_lines());
39+
const auto &source_lines = basic_blocks.source_lines_of(block_nr);
4140
const std::string comment =
42-
"block " + b + " (lines " + source_lines + ")";
41+
"block " + b + " (lines " + source_lines.to_string() + ")";
42+
source_location.set_basic_block_source_lines(source_lines.to_string());
4343
goto_program.insert_before_swap(i_it);
4444
*i_it = make_assertion(false_exprt(), source_location);
4545
initialize_source_location(i_it, comment, function_id);

src/goto-programs/show_properties.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -133,9 +133,9 @@ void convert_properties_json(
133133
{"expression",
134134
json_stringt(from_expr(ns, identifier, ins.get_condition()))}};
135135

136-
if(!source_location.get_basic_block_covered_lines().empty())
136+
if(!source_location.get_basic_block_source_lines().empty())
137137
json_property["coveredLines"] =
138-
json_stringt(source_location.get_basic_block_covered_lines());
138+
json_stringt(source_location.get_basic_block_source_lines());
139139

140140
json_properties.push_back(std::move(json_property));
141141
}

src/util/irep_ids.def

-1
Original file line numberDiff line numberDiff line change
@@ -642,7 +642,6 @@ IREP_ID_ONE(cprover_string_to_lower_case_func)
642642
IREP_ID_ONE(cprover_string_to_upper_case_func)
643643
IREP_ID_ONE(cprover_string_trim_func)
644644
IREP_ID_ONE(skip_initialize)
645-
IREP_ID_ONE(basic_block_covered_lines)
646645
IREP_ID_ONE(basic_block_source_lines)
647646
IREP_ID_ONE(is_nondet_nullable)
648647
IREP_ID_ONE(array_replace)

src/util/source_location.h

-10
Original file line numberDiff line numberDiff line change
@@ -82,11 +82,6 @@ class source_locationt:public irept
8282
return get(ID_java_bytecode_index);
8383
}
8484

85-
const irep_idt &get_basic_block_covered_lines() const
86-
{
87-
return get(ID_basic_block_covered_lines);
88-
}
89-
9085
const irep_idt &get_basic_block_source_lines() const
9186
{
9287
return get(ID_basic_block_source_lines);
@@ -153,11 +148,6 @@ class source_locationt:public irept
153148
set(ID_java_bytecode_index, index);
154149
}
155150

156-
void set_basic_block_covered_lines(const irep_idt &covered_lines)
157-
{
158-
return set(ID_basic_block_covered_lines, covered_lines);
159-
}
160-
161151
void set_basic_block_source_lines(const irep_idt &source_lines)
162152
{
163153
return set(ID_basic_block_source_lines, source_lines);

0 commit comments

Comments
 (0)