Skip to content

Commit 8522f9a

Browse files
author
Owen Jones
committed
Try 3
Restructure code to be easier to understand, and fix some correctness issues
1 parent e81d00c commit 8522f9a

File tree

2 files changed

+51
-52
lines changed

2 files changed

+51
-52
lines changed

jbmc/src/java_bytecode/convert_java_nondet.cpp

+49-51
Original file line numberDiff line numberDiff line change
@@ -43,46 +43,44 @@ static std::pair<goto_programt::targett, bool> insert_nondet_init_code(
4343
const irep_idt &mode)
4444
{
4545
const auto next_instr = std::next(target);
46-
bool changed = false;
4746

4847
// We only expect to find nondets in the rhs of an assignments or in return
4948
// statements
5049
for(exprt &op : target->code.operands())
5150
{
52-
if(op.id() != ID_side_effect)
51+
if(!can_cast_expr<side_effect_expr_nondett>(op))
5352
{
5453
continue;
5554
}
5655

57-
const auto &side_effect = to_side_effect_expr(op);
58-
if(side_effect.get_statement() != ID_nondet)
59-
{
60-
continue;
61-
}
56+
const auto &nondet_expr = to_side_effect_expr_nondet(op);
6257

63-
const typet &type = side_effect.type();
6458
// If the lhs type doesn't have a subtype then I guess it's primitive and
65-
// we want to bail out now
66-
if(type.id() != ID_pointer)
67-
{
68-
continue;
69-
}
70-
71-
// Although, if the type is a ptr-to-void or a function pointer then we also
72-
// want to bail
73-
if(type.subtype().id() == ID_empty || type.subtype().id() == ID_code)
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)
7465
{
7566
continue;
7667
}
7768

78-
if(!to_side_effect_expr_nondet(side_effect).get_nullable())
69+
if(!nondet_expr.get_nullable())
7970
object_factory_parameters.max_nonnull_tree_depth = 1;
8071

81-
// Get the symbol to nondet-init
8272
const auto source_loc = target->source_location;
8373

84-
// Create symbol for storing nondet object. We will replace `op` with this
85-
// symbol.
74+
// Currently the code looks like this
75+
// target: original instruction
76+
// When we are done it will look like this
77+
// target : declare aux_symbol
78+
// . <gen_nondet_init_instructions - many lines>
79+
// . <gen_nondet_init_instructions - many lines>
80+
// . <gen_nondet_init_instructions - many lines>
81+
// target2: orig instruction with op replaced by aux_symbol
82+
// dead aux_symbol
83+
8684
symbolt &aux_symbol = get_fresh_aux_symbol(
8785
type,
8886
id2string(goto_programt::get_function_id(goto_program)),
@@ -93,54 +91,54 @@ static std::pair<goto_programt::targett, bool> insert_nondet_init_code(
9391
aux_symbol.is_static_lifetime = false;
9492

9593
const symbol_exprt aux_symbol_expr = aux_symbol.symbol_expr();
96-
code_declt decl(aux_symbol_expr);
97-
decl.add_source_location() = source_loc;
94+
op = aux_symbol_expr;
9895

99-
// Create goto instructions for declaring and deading aux_symbol
100-
goto_programt aux_instructions;
101-
code_blockt aux_block;
102-
aux_block.move(decl);
103-
goto_convert(
104-
aux_block, symbol_table, aux_instructions, message_handler, mode);
105-
CHECK_RETURN(aux_instructions.instructions.size() == 2);
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+
// Insert an instruction declaring `aux_symbol` before `target`, being
104+
// careful to preserve jumps to `target`
105+
goto_programt::instructiont decl_aux_symbol(DECL);
106+
decl_aux_symbol.code = code_declt(aux_symbol_expr);
107+
decl_aux_symbol.source_location = source_loc;
108+
goto_program.insert_before_swap(target, decl_aux_symbol);
106109

107-
code_blockt init_code;
110+
// Keep track of the new location of the original instruction.
111+
const goto_programt::targett target2 = std::next(target);
108112

113+
code_blockt gen_nondet_init_code;
109114
const bool skip_classid = true;
110115
gen_nondet_init(
111116
aux_symbol_expr,
112-
init_code,
117+
gen_nondet_init_code,
113118
symbol_table,
114119
source_loc,
115120
skip_classid,
116121
allocation_typet::DYNAMIC,
117122
object_factory_parameters,
118123
update_in_placet::NO_UPDATE_IN_PLACE);
119124

120-
goto_programt nondet_init_instructions;
125+
goto_programt gen_nondet_init_instructions;
121126
goto_convert(
122-
init_code, symbol_table, nondet_init_instructions, message_handler, mode);
123-
124-
// First insert the declaration of aux_symbol at the front of
125-
// nondet_init_instructions
126-
nondet_init_instructions.insert_before_swap(
127-
nondet_init_instructions.instructions.begin(),
128-
aux_instructions.instructions.front());
129-
130-
// Insert nondet_init_instructions into the instruction list before target
131-
goto_program.destructive_insert(target, nondet_init_instructions);
132-
133-
// Replace op with aux symbol in target
134-
op = aux_symbol_expr;
127+
gen_nondet_init_code,
128+
symbol_table,
129+
gen_nondet_init_instructions,
130+
message_handler,
131+
mode);
135132

136-
// Finally insert the dead instruction for aux_symbol after target
137-
goto_program.insert_after(target)->swap(
138-
aux_instructions.instructions.back());
133+
goto_program.destructive_insert(target2, gen_nondet_init_instructions);
139134

140-
changed = true;
135+
// In theory target could have more than one operand which should be
136+
// replaced by convert_nondet, so we return target2 so that it
137+
// will be checked again
138+
return std::make_pair(target2, true);
141139
}
142140

143-
return std::make_pair(next_instr, changed);
141+
return std::make_pair(next_instr, false);
144142
}
145143

146144
/// For each instruction in the goto program, checks if it is an assignment from

jbmc/unit/java_bytecode/java_replace_nondet/replace_nondet.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,8 @@ void validate_nondets_converted(
124124
REQUIRE_FALSE(nondet_exists);
125125
REQUIRE(allocate_exists);
126126
}
127-
127+
#include<iostream>
128+
#include<cout_message.h>
128129
void load_and_test_method(
129130
const std::string &method_signature,
130131
goto_functionst &functions,

0 commit comments

Comments
 (0)