Skip to content

Commit 2307b37

Browse files
committed
source_linest: use platform-independent mp_integer
An input binary could have been produced on a platform that has a larger size_t width than the one used during analysis. This requires making format_number_range not use bounded integer type, which is an improvement for using mp_integer enables use with all kinds of input ranges rather than hard-coding "unsigned" as the type.
1 parent 691f5e8 commit 2307b37

File tree

5 files changed

+39
-38
lines changed

5 files changed

+39
-38
lines changed

src/goto-instrument/source_lines.cpp

+3-4
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ Author: Mark R. Tuttle
1414
#include <util/format_number_range.h>
1515
#include <util/range.h>
1616
#include <util/source_location.h>
17-
#include <util/string2int.h>
1817
#include <util/string_utils.h>
1918

2019
#include <sstream>
@@ -30,7 +29,7 @@ void source_linest::insert(const source_locationt &loc)
3029

3130
if(loc.get_line().empty())
3231
return;
33-
std::size_t line = safe_string2size_t(id2string(loc.get_line()));
32+
mp_integer line = string2integer(id2string(loc.get_line()));
3433

3534
block_lines[file][func].insert(line);
3635
}
@@ -44,7 +43,7 @@ std::string source_linest::to_string() const
4443
std::stringstream ss;
4544
const auto map = make_range(file_entry.second)
4645
.map([&](const function_linest::value_type &pair) {
47-
std::vector<unsigned> line_numbers(
46+
std::vector<mp_integer> line_numbers(
4847
pair.second.begin(), pair.second.end());
4948
return file_entry.first + ':' + pair.first + ':' +
5049
format_number_range(line_numbers);
@@ -65,7 +64,7 @@ irept source_linest::to_irep() const
6564
irept file_result;
6665
for(const auto &lines_entry : file_entry.second)
6766
{
68-
std::vector<unsigned> line_numbers(
67+
std::vector<mp_integer> line_numbers(
6968
lines_entry.second.begin(), lines_entry.second.end());
7069
file_result.set(lines_entry.first, format_number_range(line_numbers));
7170
}

src/goto-instrument/source_lines.h

+5-4
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ Author: Mark R. Tuttle
2121
#define CPROVER_GOTO_INSTRUMENT_SOURCE_LINES_H
2222

2323
#include <util/irep.h>
24+
#include <util/mp_arith.h>
2425

2526
#include <map>
2627
#include <set>
@@ -45,10 +46,10 @@ class source_linest
4546
/// Construct a string representing the set of lines
4647
///
4748
/// \return The set of lines represented as string of the form
48-
/// set1;set2;set3 where each seti is a string of the form
49+
/// set1;set2;set3 where each set is a string of the form
4950
/// file:function:n1,n2,n3,n4 where n1, n2, n3, n4 are line
50-
/// numbers from the given function in the given file listed in
51-
/// ascending order.
51+
/// numbers (or ranges thereof) from the given function in the given file
52+
/// listed in ascending order.
5253
std::string to_string() const;
5354

5455
/// Construct an irept representing the set of lines
@@ -60,7 +61,7 @@ class source_linest
6061

6162
private:
6263
/// A set of lines from a single function
63-
typedef std::set<std::size_t> linest;
64+
using linest = std::set<mp_integer>;
6465
/// A set of lines from multiple function
6566
using function_linest = std::map<std::string, linest>;
6667
/// A set of lines from multiple files

src/util/format_number_range.cpp

+13-14
Original file line numberDiff line numberDiff line change
@@ -22,21 +22,20 @@ Author: Daniel Kroening, [email protected]
2222
/// create shorter representation for output
2323
/// \param input_numbers: vector of numbers
2424
/// \return string of compressed number range representation
25-
std::string format_number_range(const std::vector<unsigned> &input_numbers)
25+
std::string format_number_range(const std::vector<mp_integer> &input_numbers)
2626
{
2727
PRECONDITION(!input_numbers.empty());
2828

29-
std::vector<unsigned> numbers(input_numbers);
29+
std::vector<mp_integer> numbers(input_numbers);
3030
std::sort(numbers.begin(), numbers.end());
31-
unsigned end_number=numbers.back();
32-
if(numbers.front()==end_number)
33-
return std::to_string(end_number); // only single number
31+
if(numbers.front() == numbers.back())
32+
return integer2string(numbers.back()); // only single number
3433

3534
std::stringstream number_range;
3635

3736
auto start_number = numbers.front();
3837

39-
for(std::vector<unsigned>::const_iterator it = numbers.begin();
38+
for(std::vector<mp_integer>::const_iterator it = numbers.begin();
4039
it != numbers.end();
4140
++it)
4241
{
@@ -75,14 +74,14 @@ std::string format_number_range(const std::vector<unsigned> &input_numbers)
7574
/// Appends \p number resp. numbers \p begin_range ... \p number to \p numbers
7675
static void append_numbers(
7776
const std::string &number_range,
78-
std::vector<unsigned> &numbers,
77+
std::vector<mp_integer> &numbers,
7978
bool last_number_is_set,
8079
bool is_range)
8180
{
8281
if(!last_number_is_set && is_range)
8382
{
8483
throw deserialization_exceptiont(
85-
"unterminated number range '" + std::to_string(*(++numbers.rbegin())) +
84+
"unterminated number range '" + integer2string(*(++numbers.rbegin())) +
8685
"-'");
8786
}
8887

@@ -94,27 +93,27 @@ static void append_numbers(
9493

9594
if(is_range)
9695
{
97-
unsigned end_range = numbers.back();
96+
mp_integer end_range = numbers.back();
9897
numbers.pop_back();
99-
unsigned begin_range = numbers.back();
98+
mp_integer begin_range = numbers.back();
10099
numbers.pop_back();
101100
if(begin_range > end_range)
102101
{
103102
throw deserialization_exceptiont(
104103
"lower bound must not be larger than upper bound '" +
105-
std::to_string(begin_range) + "-" + std::to_string(end_range) + "'");
104+
integer2string(begin_range) + "-" + integer2string(end_range) + "'");
106105
}
107-
for(unsigned i = begin_range; i < end_range; ++i)
106+
for(mp_integer i = begin_range; i < end_range; ++i)
108107
numbers.push_back(i);
109108
// add upper bound separately to avoid
110109
// potential overflow issues in the loop above
111110
numbers.push_back(end_range);
112111
}
113112
}
114113

115-
std::vector<unsigned> parse_number_range(const std::string &number_range)
114+
std::vector<mp_integer> parse_number_range(const std::string &number_range)
116115
{
117-
std::vector<unsigned> numbers(1, 0);
116+
std::vector<mp_integer> numbers(1, 0);
118117
bool last_number_is_set = false;
119118
bool is_range = false;
120119

src/util/format_number_range.h

+4-2
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,15 @@ Author: Daniel Kroening, [email protected]
1212
#ifndef CPROVER_UTIL_FORMAT_NUMBER_RANGE_H
1313
#define CPROVER_UTIL_FORMAT_NUMBER_RANGE_H
1414

15+
#include "mp_arith.h"
16+
1517
#include <string>
1618
#include <vector>
1719

18-
std::string format_number_range(const std::vector<unsigned> &);
20+
std::string format_number_range(const std::vector<mp_integer> &);
1921

2022
/// Parse a compressed range into a vector of numbers,
2123
/// e.g. "2,4-6" -> [2,4,5,6]
22-
std::vector<unsigned> parse_number_range(const std::string &);
24+
std::vector<mp_integer> parse_number_range(const std::string &);
2325

2426
#endif // CPROVER_UTIL_FORMAT_NUMBER_RANGE_H

unit/util/format_number_range.cpp

+14-14
Original file line numberDiff line numberDiff line change
@@ -15,51 +15,51 @@ TEST_CASE(
1515
"Format a range of unsigned numbers",
1616
"[core][util][format_number_range]")
1717
{
18-
const std::vector<unsigned> singleton = {1u};
18+
const std::vector<mp_integer> singleton = {1};
1919
REQUIRE(format_number_range(singleton) == "1");
2020

21-
const std::vector<unsigned> r1 = {0u, 42u};
21+
const std::vector<mp_integer> r1 = {0, 42};
2222
REQUIRE(format_number_range(r1) == "0,42");
2323

24-
const std::vector<unsigned> r2 = {0u, 1u};
24+
const std::vector<mp_integer> r2 = {0, 1};
2525
REQUIRE(format_number_range(r2) == "0,1");
2626

27-
const std::vector<unsigned> r3 = {1u, 2u, 3u};
27+
const std::vector<mp_integer> r3 = {1, 2, 3};
2828
REQUIRE(format_number_range(r3) == "1-3");
2929

30-
const std::vector<unsigned> r4 = {1u, 3u, 4u, 5u};
30+
const std::vector<mp_integer> r4 = {1, 3, 4, 5};
3131
REQUIRE(format_number_range(r4) == "1,3-5");
3232

33-
const std::vector<unsigned> r5 = {1u, 10u, 11u, 12u, 42u};
33+
const std::vector<mp_integer> r5 = {1, 10, 11, 12, 42};
3434
REQUIRE(format_number_range(r5) == "1,10-12,42");
3535

36-
const std::vector<unsigned> r6 = {1u, 10u, 11u, 12u, 42u, 43u, 44u};
36+
const std::vector<mp_integer> r6 = {1, 10, 11, 12, 42, 43, 44};
3737
REQUIRE(format_number_range(r6) == "1,10-12,42-44");
3838
}
3939

4040
TEST_CASE(
4141
"Parse a range of unsigned numbers",
4242
"[core][util][format_number_range]")
4343
{
44-
const std::vector<unsigned> singleton = {1u};
44+
const std::vector<mp_integer> singleton = {1};
4545
REQUIRE(parse_number_range("1") == singleton);
4646

47-
const std::vector<unsigned> r1 = {0u, 42u};
47+
const std::vector<mp_integer> r1 = {0, 42};
4848
REQUIRE(parse_number_range("0,42") == r1);
4949

50-
const std::vector<unsigned> r2 = {0u, 1u};
50+
const std::vector<mp_integer> r2 = {0, 1};
5151
REQUIRE(parse_number_range("0,1") == r2);
5252

53-
const std::vector<unsigned> r3 = {1u, 2u, 3u};
53+
const std::vector<mp_integer> r3 = {1, 2, 3};
5454
REQUIRE(parse_number_range("1-3") == r3);
5555

56-
const std::vector<unsigned> r4 = {1u, 3u, 4u, 5u};
56+
const std::vector<mp_integer> r4 = {1, 3, 4, 5};
5757
REQUIRE(parse_number_range("1,3-5") == r4);
5858

59-
const std::vector<unsigned> r5 = {1u, 10u, 11u, 12u, 42u};
59+
const std::vector<mp_integer> r5 = {1, 10, 11, 12, 42};
6060
REQUIRE(parse_number_range("1,10-12,42") == r5);
6161

62-
const std::vector<unsigned> r6 = {1u, 10u, 11u, 12u, 42u, 43u, 44u};
62+
const std::vector<mp_integer> r6 = {1, 10, 11, 12, 42, 43, 44};
6363
REQUIRE(parse_number_range("1,10-12,42-44") == r6);
6464

6565
REQUIRE_THROWS_AS(parse_number_range(""), deserialization_exceptiont);

0 commit comments

Comments
 (0)