Skip to content

Commit 2c7decc

Browse files
Merge pull request #5500 from hannes-steffenhagen-diffblue/fix/malloc-checks
Fix bug that prevented --malloc-may-fail from working
2 parents aa5a40a + aea6b8e commit 2c7decc

File tree

15 files changed

+133
-18
lines changed

15 files changed

+133
-18
lines changed

jbmc/src/jbmc/jbmc_parse_options.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -726,6 +726,10 @@ int jbmc_parse_optionst::get_goto_program(
726726

727727
goto_modelt &goto_model = dynamic_cast<goto_modelt &>(*goto_model_ptr);
728728

729+
// if we added the ansi-c library models here this should also call
730+
// add_malloc_may_fail_variable_initializations(goto_model);
731+
// here
732+
729733
if(cmdline.isset("validate-goto-model"))
730734
{
731735
goto_model.validate();

regression/goto-analyzer/constant_propagation_01/test.desc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ main.c
33
--constants --simplify out.gb
44
^EXIT=0$
55
^SIGNAL=0$
6-
^Simplified: assert: 1, assume: 0, goto: 1, assigns: 8, function calls: 0$
7-
^Unmodified: assert: 0, assume: 0, goto: 0, assigns: 18, function calls: 2$
6+
^Simplified: assert: 1, assume: 0, goto: 1, assigns: 7, function calls: 0$
7+
^Unmodified: assert: 0, assume: 0, goto: 0, assigns: 17, function calls: 2$
88
--
99
^warning: ignoring

regression/goto-analyzer/constant_propagation_02/test.desc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ main.c
33
--constants --simplify out.gb
44
^EXIT=0$
55
^SIGNAL=0$
6-
^Simplified: assert: 1, assume: 0, goto: 1, assigns: 9, function calls: 0$
7-
^Unmodified: assert: 0, assume: 0, goto: 0, assigns: 17, function calls: 2$
6+
^Simplified: assert: 1, assume: 0, goto: 1, assigns: 8, function calls: 0$
7+
^Unmodified: assert: 0, assume: 0, goto: 0, assigns: 16, function calls: 2$
88
--
99
^warning: ignoring

regression/goto-analyzer/constant_propagation_03/test.desc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ main.c
33
--constants --simplify out.gb
44
^EXIT=0$
55
^SIGNAL=0$
6-
^Simplified: assert: 1, assume: 0, goto: 1, assigns: 9, function calls: 0$
7-
^Unmodified: assert: 0, assume: 0, goto: 0, assigns: 17, function calls: 2$
6+
^Simplified: assert: 1, assume: 0, goto: 1, assigns: 8, function calls: 0$
7+
^Unmodified: assert: 0, assume: 0, goto: 0, assigns: 16, function calls: 2$
88
--
99
^warning: ignoring

regression/goto-analyzer/constant_propagation_04/test.desc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ main.c
33
--constants --simplify out.gb
44
^EXIT=0$
55
^SIGNAL=0$
6-
^Simplified: assert: 1, assume: 0, goto: 1, assigns: 9, function calls: 0$
7-
^Unmodified: assert: 0, assume: 0, goto: 0, assigns: 17, function calls: 2$
6+
^Simplified: assert: 1, assume: 0, goto: 1, assigns: 8, function calls: 0$
7+
^Unmodified: assert: 0, assume: 0, goto: 0, assigns: 16, function calls: 2$
88
--
99
^warning: ignoring

regression/goto-analyzer/constant_propagation_07/test.desc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ main.c
33
--constants --simplify out.gb
44
^EXIT=0$
55
^SIGNAL=0$
6-
^Simplified: assert: 1, assume: 0, goto: 3, assigns: 14, function calls: 0$
7-
^Unmodified: assert: 0, assume: 0, goto: 1, assigns: 15, function calls: 2$
6+
^Simplified: assert: 1, assume: 0, goto: 3, assigns: 13, function calls: 0$
7+
^Unmodified: assert: 0, assume: 0, goto: 1, assigns: 14, function calls: 2$
88
--
99
^warning: ignoring

regression/goto-analyzer/constant_propagation_12/test.desc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ main.c
33
--constants --simplify out.gb
44
^EXIT=0$
55
^SIGNAL=0$
6-
^Simplified: assert: 1, assume: 0, goto: 1, assigns: 8, function calls: 0$
7-
^Unmodified: assert: 0, assume: 0, goto: 1, assigns: 16, function calls: 2$
6+
^Simplified: assert: 1, assume: 0, goto: 1, assigns: 7, function calls: 0$
7+
^Unmodified: assert: 0, assume: 0, goto: 1, assigns: 15, function calls: 2$
88
--
99
^warning: ignoring
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#include <assert.h>
2+
#include <stdlib.h>
3+
4+
int main(void)
5+
{
6+
int *array = calloc(10, sizeof(int));
7+
assert(array != NULL);
8+
free(array);
9+
return 0;
10+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
CORE
2+
test.c
3+
--malloc-may-fail --malloc-fail-null
4+
^EXIT=10$
5+
^SIGNAL=0$
6+
\[main.assertion.1\] line 7 assertion array != .*: FAILURE
7+
--
8+
--
9+
Compiling a file with goto-cc should not affect how --malloc-may-fail behaves
10+
Regex in the assertion because on travis for some reason the preprocessor seems to run
11+
before cbmc.

src/ansi-c/ansi_c_internal_additions.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -186,17 +186,15 @@ void ansi_c_internal_additions(std::string &code)
186186
CPROVER_PREFIX "size_t size, " CPROVER_PREFIX "bool zero);\n"
187187
"const void *" CPROVER_PREFIX "alloca_object = 0;\n"
188188

189-
"int " CPROVER_PREFIX "malloc_failure_mode="+
190-
std::to_string(config.ansi_c.malloc_failure_mode)+";\n"
189+
"extern int " CPROVER_PREFIX "malloc_failure_mode;\n"
191190
"int " CPROVER_PREFIX "malloc_failure_mode_return_null="+
192191
std::to_string(config.ansi_c.malloc_failure_mode_return_null)+";\n"
193192
"int " CPROVER_PREFIX "malloc_failure_mode_assert_then_assume="+
194193
std::to_string(config.ansi_c.malloc_failure_mode_assert_then_assume)+";\n"
195194
CPROVER_PREFIX "size_t " CPROVER_PREFIX "max_malloc_size="+
196195
integer2string(max_malloc_size(config.ansi_c.pointer_width, config
197196
.bv_encoding.object_bits))+";\n"
198-
CPROVER_PREFIX "bool " CPROVER_PREFIX "malloc_may_fail = " +
199-
std::to_string(config.ansi_c.malloc_may_fail) + ";\n"
197+
"extern " CPROVER_PREFIX "bool " CPROVER_PREFIX "malloc_may_fail;\n"
200198

201199
// this is ANSI-C
202200
"extern " CPROVER_PREFIX "thread_local const char __func__["

src/cbmc/cbmc_parse_options.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ Author: Daniel Kroening, [email protected]
4848
#include <goto-checker/stop_on_fail_verifier.h>
4949
#include <goto-checker/stop_on_fail_verifier_with_fault_localization.h>
5050

51+
#include <goto-programs/add_malloc_may_fail_variable_initializations.h>
5152
#include <goto-programs/adjust_float_expressions.h>
5253
#include <goto-programs/initialize_goto_model.h>
5354
#include <goto-programs/instrument_preconditions.h>
@@ -890,6 +891,8 @@ bool cbmc_parse_optionst::process_goto_program(
890891
link_to_library(
891892
goto_model, log.get_message_handler(), cprover_c_library_factory);
892893

894+
add_malloc_may_fail_variable_initializations(goto_model);
895+
893896
if(options.get_bool_option("string-abstraction"))
894897
string_instrumentation(goto_model, log.get_message_handler());
895898

src/goto-analyzer/goto_analyzer_parse_options.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ Author: Daniel Kroening, [email protected]
2626

2727
#include <jsil/jsil_language.h>
2828

29+
#include <goto-programs/add_malloc_may_fail_variable_initializations.h>
2930
#include <goto-programs/adjust_float_expressions.h>
3031
#include <goto-programs/goto_convert_functions.h>
3132
#include <goto-programs/goto_inline.h>
@@ -814,7 +815,12 @@ bool goto_analyzer_parse_optionst::process_goto_program(
814815
link_to_library(
815816
goto_model, ui_message_handler, cprover_cpp_library_factory);
816817
link_to_library(goto_model, ui_message_handler, cprover_c_library_factory);
817-
#endif
818+
819+
// these are commented out as well because without the library
820+
// this initialization code doesn’t make any sense
821+
add_malloc_may_fail_variable_initializations(goto_model);
822+
823+
#endif
818824

819825
// remove function pointers
820826
log.status() << "Removing function pointers and virtual functions"

src/goto-programs/Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
SRC = adjust_float_expressions.cpp \
1+
SRC = add_malloc_may_fail_variable_initializations.cpp \
2+
adjust_float_expressions.cpp \
23
builtin_functions.cpp \
34
class_hierarchy.cpp \
45
class_identifier.cpp \
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/// \file
2+
/// \author Diffblue Ltd.
3+
4+
#include "add_malloc_may_fail_variable_initializations.h"
5+
6+
#include "goto_model.h"
7+
8+
#include <util/arith_tools.h>
9+
#include <util/config.h>
10+
#include <util/irep.h>
11+
12+
template <typename T>
13+
code_assignt make_integer_assignment(
14+
const symbol_table_baset &symbol_table,
15+
const irep_idt &symbol_name,
16+
T &&value)
17+
{
18+
const auto &symbol = symbol_table.lookup_ref(symbol_name).symbol_expr();
19+
return code_assignt{symbol, from_integer(value, symbol.type())};
20+
}
21+
22+
void add_malloc_may_fail_variable_initializations(goto_modelt &goto_model)
23+
{
24+
const auto malloc_may_fail_id = irep_idt{CPROVER_PREFIX "malloc_may_fail"};
25+
const auto malloc_failure_mode_id =
26+
irep_idt{CPROVER_PREFIX "malloc_failure_mode"};
27+
if(!goto_model.symbol_table.has_symbol(malloc_may_fail_id))
28+
{
29+
// if malloc_may_fail isn't in the symbol table (i.e. builtin library not
30+
// loaded) then we don't generate initialisation code for it.
31+
return;
32+
}
33+
34+
INVARIANT(
35+
goto_model.symbol_table.has_symbol(malloc_failure_mode_id),
36+
"if malloc_may_fail is in the symbol table then so should "
37+
"malloc_failure_mode");
38+
39+
auto const initialize_function_name = CPROVER_PREFIX "initialize";
40+
PRECONDITION(
41+
goto_model.get_goto_functions().function_map.count(
42+
initialize_function_name) == 1);
43+
auto &initialize_function =
44+
goto_model.goto_functions.function_map.find(initialize_function_name)
45+
->second;
46+
const auto initialize_function_end =
47+
--initialize_function.body.instructions.end();
48+
49+
initialize_function.body.insert_before(
50+
initialize_function_end,
51+
goto_programt::make_assignment(make_integer_assignment(
52+
goto_model.symbol_table,
53+
malloc_may_fail_id,
54+
config.ansi_c.malloc_may_fail)));
55+
56+
initialize_function.body.insert_before(
57+
initialize_function_end,
58+
goto_programt::make_assignment(make_integer_assignment(
59+
goto_model.symbol_table,
60+
malloc_failure_mode_id,
61+
config.ansi_c.malloc_failure_mode)));
62+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/// \file
2+
/// \author Diffblue Ltd.
3+
/// Adds an instrumentation to add initialisations for variables
4+
/// used by the --malloc-may-fail and related flags in cbmc
5+
6+
// NOLINT(whitespace/line_length)
7+
#ifndef CPROVER_GOTO_PROGRAMS_ADD_MALLOC_MAY_FAIL_VARIABLE_INITIALIZATIONS_H
8+
// NOLINT(whitespace/line_length)
9+
#define CPROVER_GOTO_PROGRAMS_ADD_MALLOC_MAY_FAIL_VARIABLE_INITIALIZATIONS_H
10+
11+
class goto_modelt;
12+
13+
/// Some variables have different initial values based on what flags are being
14+
/// passed to cbmc; since the _start function might've been generated by goto-cc
15+
/// before getting passed over here we need to add the initialisation of these
16+
/// variables here as a post-processing step
17+
void add_malloc_may_fail_variable_initializations(goto_modelt &goto_model);
18+
19+
// NOLINT(whitespace/line_length)
20+
#endif // CPROVER_GOTO_PROGRAMS_ADD_MALLOC_MAY_FAIL_VARIABLE_INITIALIZATIONS_H

0 commit comments

Comments
 (0)