Skip to content

Commit 640cdcc

Browse files
committed
Reimplement via goto-checker
with a dedicated cmdl option and a property that acknowledges pointer-width and object-size.
1 parent be6883a commit 640cdcc

File tree

5 files changed

+34
-8
lines changed

5 files changed

+34
-8
lines changed
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
CORE
22
main.c
3-
3+
--malloc-max-check
44
^EXIT=10$
55
^SIGNAL=0$
6-
^\[main.assertion.\d+\] line \d+ assertion p: FAILURE$
6+
^\[malloc.max_allocation_check.\d+\] line \d+ malloc_size < 2 \^ \(pointer_width - object_size\) in ALLOCATE\(malloc_size, 0 != 0\): FAILURE$
77
^VERIFICATION FAILED$
88
--
99
^warning: ignoring

src/analyses/goto_check.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ class goto_checkt
7272
enable_built_in_assertions=_options.get_bool_option("built-in-assertions");
7373
enable_assumptions=_options.get_bool_option("assumptions");
7474
error_labels=_options.get_list_option("error-label");
75+
enable_malloc_max_check = _options.get_bool_option("malloc-max-check");
7576
}
7677

7778
typedef goto_functionst::goto_functiont goto_functiont;
@@ -238,6 +239,7 @@ class goto_checkt
238239
bool enable_assertions;
239240
bool enable_built_in_assertions;
240241
bool enable_assumptions;
242+
bool enable_malloc_max_check;
241243

242244
typedef optionst::value_listt error_labelst;
243245
error_labelst error_labels;
@@ -1941,6 +1943,30 @@ void goto_checkt::goto_check(
19411943
if(rw_ok_cond.has_value())
19421944
rhs = *rw_ok_cond;
19431945
}
1946+
1947+
if(enable_malloc_max_check && code_assign.rhs().id() == ID_side_effect)
1948+
{
1949+
const auto &rhs_side_effect = to_side_effect_expr(code_assign.rhs());
1950+
if(rhs_side_effect.get_statement() == ID_allocate)
1951+
{
1952+
const auto &alloc_size_type = rhs_side_effect.op0().type();
1953+
const auto pointer_bits =
1954+
from_integer(config.ansi_c.pointer_width, alloc_size_type);
1955+
const auto object_bits =
1956+
from_integer(config.bv_encoding.object_bits, alloc_size_type);
1957+
const auto max_alloc_size =
1958+
binary_exprt{from_integer(2, alloc_size_type),
1959+
ID_power,
1960+
minus_exprt{pointer_bits, object_bits}};
1961+
add_guarded_property(
1962+
binary_relation_exprt{rhs_side_effect.op0(), ID_lt, max_alloc_size},
1963+
"malloc_size < 2 ^ (pointer_width - object_size)",
1964+
"max allocation check",
1965+
i.code.source_location(),
1966+
code_assign.rhs(),
1967+
guardt{true_exprt{}, guard_manager});
1968+
}
1969+
}
19441970
}
19451971
else if(i.is_function_call())
19461972
{

src/analyses/goto_check.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@ void goto_check(
3838
"(div-by-zero-check)(enum-range-check)(signed-overflow-check)(unsigned-" \
3939
"overflow-check)" \
4040
"(pointer-overflow-check)(conversion-check)(undefined-shift-check)" \
41-
"(float-overflow-check)(nan-check)(no-built-in-assertions)"
41+
"(float-overflow-check)(nan-check)(no-built-in-assertions)" \
42+
"(malloc-max-check)"
4243

4344
// clang-format off
4445
#define HELP_GOTO_CHECK \
@@ -55,6 +56,7 @@ void goto_check(
5556
" --nan-check check floating-point for NaN\n" \
5657
" --no-built-in-assertions ignore assertions in built-in library\n" \
5758
" --enum-range-check checks that all enum type expressions have values in the enum range\n" /* NOLINT(whitespace/line_length) */ \
59+
" --malloc-max-check check that CBMC can represent the allocated object of requested size" /* NOLINT(whitespace/line_length) */ \
5860
// clang-format on
5961

6062
#define PARSE_OPTIONS_GOTO_CHECK(cmdline, options) \
@@ -70,6 +72,7 @@ void goto_check(
7072
options.set_option("undefined-shift-check", cmdline.isset("undefined-shift-check")); /* NOLINT(whitespace/line_length) */ \
7173
options.set_option("float-overflow-check", cmdline.isset("float-overflow-check")); /* NOLINT(whitespace/line_length) */ \
7274
options.set_option("nan-check", cmdline.isset("nan-check")); \
73-
options.set_option("built-in-assertions", !cmdline.isset("no-built-in-assertions")) /* NOLINT(whitespace/line_length) */
75+
options.set_option("built-in-assertions", !cmdline.isset("no-built-in-assertions")); /* NOLINT(whitespace/line_length) */ \
76+
options.set_option("malloc-max-check", cmdline.isset("malloc-max-check"))
7477

7578
#endif // CPROVER_ANALYSES_GOTO_CHECK_H

src/ansi-c/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ endforeach()
1313

1414
add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/cprover_library.inc"
1515
COMMAND converter < ${converter_input_path} > "${CMAKE_CURRENT_BINARY_DIR}/cprover_library.inc"
16-
DEPENDS converter ${converter_input_path}
16+
DEPENDS converter
1717
)
1818

1919
add_executable(file_converter file_converter.cpp)

src/ansi-c/library/stdlib.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -115,9 +115,6 @@ inline void *malloc(__CPROVER_size_t malloc_size)
115115
// realistically, malloc may return NULL,
116116
// and __CPROVER_allocate doesn't, but no one cares
117117
__CPROVER_HIDE:;
118-
// 8 is the default object bits for ANSI-C and C++
119-
if (malloc_size >= ((__CPROVER_size_t)1<<(64-8)))
120-
return (void*)0;
121118
void *malloc_res;
122119
malloc_res = __CPROVER_allocate(malloc_size, 0);
123120

0 commit comments

Comments
 (0)