22
22
23
23
#include " java_object_factory.h" // gen_nondet_init
24
24
25
+ // / Return whether `expr` is a nondet pointer that we should convert
26
+ static bool is_nondet_pointer (exprt expr)
27
+ {
28
+ // If the expression type doesn't have a subtype then I guess it's primitive
29
+ // and we do not want to convert it. If the type is a ptr-to-void or a
30
+ // function pointer then we also do not want to convert it.
31
+ const typet &type = expr.type ();
32
+ const bool non_void_non_function_pointer = type.id () == ID_pointer &&
33
+ type.subtype ().id () != ID_empty &&
34
+ type.subtype ().id () != ID_code;
35
+ return can_cast_expr<side_effect_expr_nondett>(expr) &&
36
+ non_void_non_function_pointer;
37
+ }
38
+
25
39
// / Checks an instruction to see whether it contains an assignment from
26
40
// / side_effect_expr_nondet. If so, replaces the instruction with a range of
27
41
// / instructions to properly nondet-initialize the lhs.
@@ -44,72 +58,59 @@ static std::pair<goto_programt::targett, bool> insert_nondet_init_code(
44
58
{
45
59
const auto next_instr = std::next (target);
46
60
47
- // We only expect to find nondets in the rhs of an assignments or in return
48
- // statements
61
+ // We only expect to find nondets in the rhs of an assignments, and in return
62
+ // statements if remove_returns has not been run, but we do a more general
63
+ // check on all operands in case this changes
49
64
for (exprt &op : target->code .operands ())
50
65
{
51
- if (!can_cast_expr<side_effect_expr_nondett> (op))
66
+ if (!is_nondet_pointer (op))
52
67
{
53
68
continue ;
54
69
}
55
70
56
- const auto &nondet_expr = to_side_effect_expr_nondet (op);
57
-
58
- // If the lhs type doesn't have a subtype then I guess it's primitive and
59
- // we want to bail out now. If the type is a ptr-to-void or a function
60
- // pointer then we also want to bail.
61
- const typet &type = nondet_expr.type ();
62
- if (
63
- type.id () != ID_pointer || type.subtype ().id () == ID_empty ||
64
- type.subtype ().id () == ID_code)
65
- {
66
- continue ;
67
- }
71
+ const auto &nondet_expr = to_side_effect_expr_nondet (op);
68
72
69
73
if (!nondet_expr.get_nullable ())
70
74
object_factory_parameters.max_nonnull_tree_depth = 1 ;
71
75
72
76
const auto source_loc = target->source_location ;
73
77
74
78
// Currently the code looks like this
75
- // target: original instruction
79
+ // target: instruction containing op
76
80
// When we are done it will look like this
77
81
// target : declare aux_symbol
78
82
// . <gen_nondet_init_instructions - many lines>
79
83
// . <gen_nondet_init_instructions - many lines>
80
84
// . <gen_nondet_init_instructions - many lines>
81
- // target2: orig instruction with op replaced by aux_symbol
85
+ // target2: instruction containing op, with op replaced by aux_symbol
82
86
// dead aux_symbol
83
87
84
88
symbolt &aux_symbol = get_fresh_aux_symbol (
85
- type,
89
+ op. type () ,
86
90
id2string (goto_programt::get_function_id (goto_program)),
87
91
" nondet_tmp" ,
88
92
source_loc,
89
93
ID_java,
90
94
symbol_table);
91
- aux_symbol.is_static_lifetime = false ;
92
95
93
96
const symbol_exprt aux_symbol_expr = aux_symbol.symbol_expr ();
94
97
op = aux_symbol_expr;
95
98
96
- // It is simplest to insert the final instruction first, before everything
97
- // gets moved around
98
- goto_programt::targett dead_aux_symbol = goto_program.insert_after (target);
99
- dead_aux_symbol->type = DEAD;
100
- dead_aux_symbol->code = code_deadt (aux_symbol_expr);
101
- dead_aux_symbol->source_location = source_loc;
102
-
103
99
// Insert an instruction declaring `aux_symbol` before `target`, being
104
100
// careful to preserve jumps to `target`
105
- goto_programt::instructiont decl_aux_symbol (DECL) ;
106
- decl_aux_symbol.code = code_declt (aux_symbol_expr);
101
+ goto_programt::instructiont decl_aux_symbol;
102
+ decl_aux_symbol.make_decl ( code_declt (aux_symbol_expr) );
107
103
decl_aux_symbol.source_location = source_loc;
108
104
goto_program.insert_before_swap (target, decl_aux_symbol);
109
105
110
- // Keep track of the new location of the original instruction.
106
+ // Keep track of the new location of the instruction containing op .
111
107
const goto_programt::targett target2 = std::next (target);
112
108
109
+ goto_programt::targett dead_aux_symbol = goto_program.insert_after (target2);
110
+ dead_aux_symbol->type = DEAD;
111
+ dead_aux_symbol->code = code_deadt (aux_symbol_expr);
112
+ dead_aux_symbol->source_location = source_loc;
113
+
113
114
code_blockt gen_nondet_init_code;
114
115
const bool skip_classid = true ;
115
116
gen_nondet_init (
@@ -159,9 +160,8 @@ void convert_nondet(
159
160
{
160
161
bool changed = false ;
161
162
auto instruction_iterator = goto_program.instructions .begin ();
162
- auto end = goto_program.instructions .end ();
163
163
164
- while (instruction_iterator != end)
164
+ while (instruction_iterator != goto_program. instructions . end () )
165
165
{
166
166
auto ret = insert_nondet_init_code (
167
167
goto_program,
0 commit comments