Skip to content

Refactoring of the parsing of the --object-bits command line argument #5447

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions regression/cbmc/object-bits-parsing/non_numeric.desc
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
CORE
test.c
--object-bits foobar
Value of "foobar" given for object-bits is not a valid unsigned integer.
object-bits must be positive and less than the pointer width
^EXIT=1$
^SIGNAL=0$
--
--
Test parsing of an invalid non numeric object-bits setting.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a must-not-match, not a comment (similarly others)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

8 changes: 8 additions & 0 deletions regression/cbmc/object-bits-parsing/test.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@

#include <assert.h>
#include <stdlib.h>

int main(int argc, char **argv)
{
void *p = malloc(1);
}
10 changes: 10 additions & 0 deletions regression/cbmc/object-bits-parsing/too_large.desc
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
CORE
test.c
--object-bits 65
Value of "65" given for object-bits is out of range.
object-bits must be positive and less than the pointer width
^EXIT=1$
^SIGNAL=0$
--
--
Test parsing of a too large object-bits setting.
8 changes: 8 additions & 0 deletions regression/cbmc/object-bits-parsing/valid.desc
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
CORE
test.c
--object-bits 8
^EXIT=0$
^SIGNAL=0$
--
--
Test parsing of a valid object-bits setting.
10 changes: 10 additions & 0 deletions regression/cbmc/object-bits-parsing/zero.desc
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
CORE
test.c
--object-bits 0
Value of "0" given for object-bits is out of range.
object-bits must be positive and less than the pointer width
^EXIT=1$
^SIGNAL=0$
--
--
Test parsing of a too small object-bits setting.
49 changes: 32 additions & 17 deletions src/util/config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -765,16 +765,42 @@ void configt::set_arch(const irep_idt &arch)
}
}

/// \brief Parses the `object_bits` argument from the command line arguments.
/// \param argument The command line argument to parse the `object_bits` from.
/// \param pointer_width The width of a pointer in bits. This is used to check
/// the value of object_bits is within the valid range.
/// \return A `bv_encodingt` on successful parsing. In the case where an invalid
/// argument is specified, an `invalid_command_line_argument_exceptiont` will
/// be thrown.
configt::bv_encodingt parse_object_bits_encoding(
const std::string &argument,
const std::size_t pointer_width)
{
const auto throw_for_reason = [&](const std::string &reason) {
throw invalid_command_line_argument_exceptiont(
"Value of \"" + argument + "\" given for object-bits is " + reason +
". object-bits must be positive and less than the pointer width (" +
std::to_string(pointer_width) + ") ",
"--object_bits");
};
const auto object_bits = string2optional<unsigned int>(argument);
if(!object_bits)
throw_for_reason("not a valid unsigned integer");
if(*object_bits == 0 || *object_bits >= pointer_width)
throw_for_reason("out of range");

configt::bv_encodingt bv_encoding;
bv_encoding.object_bits = *object_bits;
bv_encoding.is_object_bits_default = false;
return bv_encoding;
}

bool configt::set(const cmdlinet &cmdline)
{
// defaults -- we match the architecture we have ourselves

cpp.cpp_standard=cppt::default_cpp_standard();

bv_encoding.object_bits=bv_encoding.default_object_bits;
// This will allow us to override by language defaults later.
bv_encoding.is_object_bits_default=true;

ansi_c.single_precision_constant=false;
ansi_c.for_has_scope=true; // C99 or later
ansi_c.ts_18661_3_Floatn_types=false;
Expand Down Expand Up @@ -1078,19 +1104,8 @@ bool configt::set(const cmdlinet &cmdline)

if(cmdline.isset("object-bits"))
{
bv_encoding.object_bits=
unsafe_string2unsigned(cmdline.get_value("object-bits"));

if(!(0<bv_encoding.object_bits &&
bv_encoding.object_bits<ansi_c.pointer_width))
{
throw invalid_command_line_argument_exceptiont(
"object-bits must be positive and less than the pointer width (" +
std::to_string(ansi_c.pointer_width) + ") ",
"--object_bits");
}

bv_encoding.is_object_bits_default = false;
bv_encoding = parse_object_bits_encoding(
cmdline.get_value("object-bits"), ansi_c.pointer_width);
}

if(cmdline.isset("malloc-fail-assert") && cmdline.isset("malloc-fail-null"))
Expand Down
6 changes: 2 additions & 4 deletions src/util/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -173,10 +173,8 @@ class configt
struct bv_encodingt
{
// number of bits to encode heap object addresses
std::size_t object_bits;
bool is_object_bits_default;

static const std::size_t default_object_bits=8;
std::size_t object_bits = 8;
bool is_object_bits_default = true;
} bv_encoding;

// this is the function to start executing
Expand Down
2 changes: 1 addition & 1 deletion src/util/string2int.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ auto wrap_string_conversion(do_conversiont do_conversion)
/// (unsigned) long long
/// does not accept negative inputs when the result type is unsigned
template <typename T>
optionalt<T> string2optional(const std::string &str, int base)
optionalt<T> string2optional(const std::string &str, int base = 10)
{
return wrap_string_conversion([&]() {
return narrow_or_throw_out_of_range<T>(string2optional_base<T>(str, base));
Expand Down