Skip to content

Commit 7d8a6f7

Browse files
Merge pull request #5447 from thomasspriggs/tas/object_bits_parsing_refactor
Refactoring of the parsing of the `--object-bits` command line argument
2 parents af5bc99 + 8efa7cc commit 7d8a6f7

File tree

8 files changed

+81
-22
lines changed

8 files changed

+81
-22
lines changed
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
CORE
2+
test.c
3+
--object-bits foobar
4+
Value of "foobar" given for object-bits is not a valid unsigned integer.
5+
object-bits must be positive and less than the pointer width
6+
^EXIT=1$
7+
^SIGNAL=0$
8+
--
9+
--
10+
Test parsing of an invalid non numeric object-bits setting.
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
2+
#include <assert.h>
3+
#include <stdlib.h>
4+
5+
int main(int argc, char **argv)
6+
{
7+
void *p = malloc(1);
8+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
CORE
2+
test.c
3+
--object-bits 65
4+
Value of "65" given for object-bits is out of range.
5+
object-bits must be positive and less than the pointer width
6+
^EXIT=1$
7+
^SIGNAL=0$
8+
--
9+
--
10+
Test parsing of a too large object-bits setting.
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CORE
2+
test.c
3+
--object-bits 8
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
--
7+
--
8+
Test parsing of a valid object-bits setting.
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
CORE
2+
test.c
3+
--object-bits 0
4+
Value of "0" given for object-bits is out of range.
5+
object-bits must be positive and less than the pointer width
6+
^EXIT=1$
7+
^SIGNAL=0$
8+
--
9+
--
10+
Test parsing of a too small object-bits setting.

src/util/config.cpp

Lines changed: 32 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -765,16 +765,42 @@ void configt::set_arch(const irep_idt &arch)
765765
}
766766
}
767767

768+
/// \brief Parses the `object_bits` argument from the command line arguments.
769+
/// \param argument The command line argument to parse the `object_bits` from.
770+
/// \param pointer_width The width of a pointer in bits. This is used to check
771+
/// the value of object_bits is within the valid range.
772+
/// \return A `bv_encodingt` on successful parsing. In the case where an invalid
773+
/// argument is specified, an `invalid_command_line_argument_exceptiont` will
774+
/// be thrown.
775+
configt::bv_encodingt parse_object_bits_encoding(
776+
const std::string &argument,
777+
const std::size_t pointer_width)
778+
{
779+
const auto throw_for_reason = [&](const std::string &reason) {
780+
throw invalid_command_line_argument_exceptiont(
781+
"Value of \"" + argument + "\" given for object-bits is " + reason +
782+
". object-bits must be positive and less than the pointer width (" +
783+
std::to_string(pointer_width) + ") ",
784+
"--object_bits");
785+
};
786+
const auto object_bits = string2optional<unsigned int>(argument);
787+
if(!object_bits)
788+
throw_for_reason("not a valid unsigned integer");
789+
if(*object_bits == 0 || *object_bits >= pointer_width)
790+
throw_for_reason("out of range");
791+
792+
configt::bv_encodingt bv_encoding;
793+
bv_encoding.object_bits = *object_bits;
794+
bv_encoding.is_object_bits_default = false;
795+
return bv_encoding;
796+
}
797+
768798
bool configt::set(const cmdlinet &cmdline)
769799
{
770800
// defaults -- we match the architecture we have ourselves
771801

772802
cpp.cpp_standard=cppt::default_cpp_standard();
773803

774-
bv_encoding.object_bits=bv_encoding.default_object_bits;
775-
// This will allow us to override by language defaults later.
776-
bv_encoding.is_object_bits_default=true;
777-
778804
ansi_c.single_precision_constant=false;
779805
ansi_c.for_has_scope=true; // C99 or later
780806
ansi_c.ts_18661_3_Floatn_types=false;
@@ -1078,19 +1104,8 @@ bool configt::set(const cmdlinet &cmdline)
10781104

10791105
if(cmdline.isset("object-bits"))
10801106
{
1081-
bv_encoding.object_bits=
1082-
unsafe_string2unsigned(cmdline.get_value("object-bits"));
1083-
1084-
if(!(0<bv_encoding.object_bits &&
1085-
bv_encoding.object_bits<ansi_c.pointer_width))
1086-
{
1087-
throw invalid_command_line_argument_exceptiont(
1088-
"object-bits must be positive and less than the pointer width (" +
1089-
std::to_string(ansi_c.pointer_width) + ") ",
1090-
"--object_bits");
1091-
}
1092-
1093-
bv_encoding.is_object_bits_default = false;
1107+
bv_encoding = parse_object_bits_encoding(
1108+
cmdline.get_value("object-bits"), ansi_c.pointer_width);
10941109
}
10951110

10961111
if(cmdline.isset("malloc-fail-assert") && cmdline.isset("malloc-fail-null"))

src/util/config.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -173,10 +173,8 @@ class configt
173173
struct bv_encodingt
174174
{
175175
// number of bits to encode heap object addresses
176-
std::size_t object_bits;
177-
bool is_object_bits_default;
178-
179-
static const std::size_t default_object_bits=8;
176+
std::size_t object_bits = 8;
177+
bool is_object_bits_default = true;
180178
} bv_encoding;
181179

182180
// this is the function to start executing

src/util/string2int.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ auto wrap_string_conversion(do_conversiont do_conversion)
107107
/// (unsigned) long long
108108
/// does not accept negative inputs when the result type is unsigned
109109
template <typename T>
110-
optionalt<T> string2optional(const std::string &str, int base)
110+
optionalt<T> string2optional(const std::string &str, int base = 10)
111111
{
112112
return wrap_string_conversion([&]() {
113113
return narrow_or_throw_out_of_range<T>(string2optional_base<T>(str, base));

0 commit comments

Comments
 (0)