CBMC
convert_java_nondet.cpp
Go to the documentation of this file.
1 /*******************************************************************\
2 
3 Module: Convert side_effect_expr_nondett expressions
4 
5 Author: Reuben Thomas, reuben.thomas@diffblue.com
6 
7 \*******************************************************************/
8 
11 
12 #include "convert_java_nondet.h"
13 
17 
18 #include "java_object_factory.h" // gen_nondet_init
20 #include "java_utils.h"
21 
24 static bool is_nondet_pointer(exprt expr)
25 {
26  // If the expression type doesn't have a subtype then I guess it's primitive
27  // and we do not want to convert it. If the type is a ptr-to-void or a
28  // function pointer then we also do not want to convert it.
29  const typet &type = expr.type();
30  const bool non_void_non_function_pointer =
31  type.id() == ID_pointer &&
32  to_pointer_type(type).base_type().id() != ID_empty &&
33  to_pointer_type(type).base_type().id() != ID_code;
35  non_void_non_function_pointer;
36 }
37 
41  const symbol_exprt &aux_symbol_expr,
42  const source_locationt &source_loc,
43  symbol_table_baset &symbol_table,
44  message_handlert &message_handler,
45  const java_object_factory_parameterst &object_factory_parameters,
46  const irep_idt &mode)
47 {
48  code_blockt gen_nondet_init_code;
49  const bool skip_classid = true;
51  aux_symbol_expr,
52  gen_nondet_init_code,
53  symbol_table,
54  source_loc,
55  skip_classid,
57  object_factory_parameters,
59  message_handler);
60 
61  goto_programt instructions;
63  gen_nondet_init_code, symbol_table, instructions, message_handler, mode);
64  return instructions;
65 }
66 
80 static std::pair<goto_programt::targett, bool> insert_nondet_init_code(
81  const irep_idt &function_identifier,
82  goto_programt &goto_program,
83  const goto_programt::targett &target,
84  symbol_table_baset &symbol_table,
85  message_handlert &message_handler,
86  java_object_factory_parameterst object_factory_parameters,
87  const irep_idt &mode)
88 {
89  const auto next_instr = std::next(target);
90 
91  // We only expect to find nondets in the rhs of an assignments, and in return
92  // statements if remove_returns has not been run, but we do a more general
93  // check on all operands in case this changes
94  for(exprt &op : target->code_nonconst().operands())
95  {
96  if(!is_nondet_pointer(op))
97  {
98  continue;
99  }
100 
101  const auto &nondet_expr = to_side_effect_expr_nondet(op);
102 
103  if(!nondet_expr.get_nullable())
104  object_factory_parameters.min_null_tree_depth = 1;
105 
106  const source_locationt &source_loc = target->source_location();
107 
108  // Currently the code looks like this
109  // target: instruction containing op
110  // When we are done it will look like this
111  // target : declare aux_symbol
112  // . <gen_nondet_init_instructions - many lines>
113  // . <gen_nondet_init_instructions - many lines>
114  // . <gen_nondet_init_instructions - many lines>
115  // target2: instruction containing op, with op replaced by aux_symbol
116  // dead aux_symbol
117 
118  symbolt &aux_symbol = fresh_java_symbol(
119  op.type(), "nondet_tmp", source_loc, function_identifier, symbol_table);
120 
121  const symbol_exprt aux_symbol_expr = aux_symbol.symbol_expr();
122  op = aux_symbol_expr;
123 
124  // Insert an instruction declaring `aux_symbol` before `target`, being
125  // careful to preserve jumps to `target`
126  goto_programt::instructiont decl_aux_symbol =
127  goto_programt::make_decl(code_declt(aux_symbol_expr), source_loc);
128  goto_program.insert_before_swap(target, decl_aux_symbol);
129 
130  // Keep track of the new location of the instruction containing op.
131  const goto_programt::targett target2 = std::next(target);
132 
133  goto_programt gen_nondet_init_instructions =
135  aux_symbol_expr,
136  source_loc,
137  symbol_table,
138  message_handler,
139  object_factory_parameters,
140  mode);
141  goto_program.destructive_insert(target2, gen_nondet_init_instructions);
142 
143  goto_program.insert_after(
144  target2, goto_programt::make_dead(aux_symbol_expr, source_loc));
145 
146  // In theory target could have more than one operand which should be
147  // replaced by convert_nondet, so we return target2 so that it
148  // will be checked again
149  return std::make_pair(target2, true);
150  }
151 
152  return std::make_pair(next_instr, false);
153 }
154 
166  const irep_idt &function_identifier,
167  goto_programt &goto_program,
168  symbol_table_baset &symbol_table,
169  message_handlert &message_handler,
170  const java_object_factory_parameterst &user_object_factory_parameters,
171  const irep_idt &mode)
172 {
173  java_object_factory_parameterst object_factory_parameters =
174  user_object_factory_parameters;
175  object_factory_parameters.function_id = function_identifier;
176 
177  bool changed = false;
178  auto instruction_iterator = goto_program.instructions.begin();
179 
180  while(instruction_iterator != goto_program.instructions.end())
181  {
182  auto ret = insert_nondet_init_code(
183  function_identifier,
184  goto_program,
185  instruction_iterator,
186  symbol_table,
187  message_handler,
188  object_factory_parameters,
189  mode);
190  instruction_iterator = ret.first;
191  changed |= ret.second;
192  }
193 
194  if(changed)
195  {
196  goto_program.update();
197  }
198 }
199 
201  goto_model_functiont &function,
202  message_handlert &message_handler,
203  const java_object_factory_parameterst &object_factory_parameters,
204  const irep_idt &mode)
205 {
207  function.get_function_id(),
208  function.get_goto_function().body,
209  function.get_symbol_table(),
210  message_handler,
211  object_factory_parameters,
212  mode);
213 
214  function.compute_location_numbers();
215 }
216 
218  goto_functionst &goto_functions,
219  symbol_table_baset &symbol_table,
220  message_handlert &message_handler,
221  const java_object_factory_parameterst &object_factory_parameters)
222 {
223  const namespacet ns(symbol_table);
224 
225  for(auto &f_it : goto_functions.function_map)
226  {
227  const symbolt &symbol=ns.lookup(f_it.first);
228 
229  if(symbol.mode==ID_java)
230  {
232  f_it.first,
233  f_it.second.body,
234  symbol_table,
235  message_handler,
236  object_factory_parameters,
237  symbol.mode);
238  }
239  }
240 
241  goto_functions.compute_location_numbers();
242 
243  remove_skip(goto_functions);
244 }
245 
247  goto_modelt &goto_model,
248  message_handlert &message_handler,
249  const java_object_factory_parameterst &object_factory_parameters)
250 {
252  goto_model.goto_functions,
253  goto_model.symbol_table,
254  message_handler,
255  object_factory_parameters);
256 }
@ DYNAMIC
Allocate dynamic objects (using ALLOCATE)
A codet representing sequential composition of program statements.
Definition: std_code.h:130
A goto_instruction_codet representing the declaration of a local variable.
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
Definition: dstring.h:38
Base class for all expressions.
Definition: expr.h:56
typet & type()
Return the type of the expression.
Definition: expr.h:84
operandst & operands()
Definition: expr.h:94
A collection of goto functions.
function_mapt function_map
void compute_location_numbers()
Interface providing access to a single function in a GOTO model, plus its associated symbol table.
Definition: goto_model.h:190
symbol_tablet symbol_table
Symbol table.
Definition: goto_model.h:31
goto_functionst goto_functions
GOTO functions.
Definition: goto_model.h:34
This class represents an instruction in the GOTO intermediate representation.
Definition: goto_program.h:181
A generic container class for the GOTO intermediate representation of one function.
Definition: goto_program.h:73
instructionst instructions
The list of instructions in the goto program.
Definition: goto_program.h:622
static instructiont make_dead(const symbol_exprt &symbol, const source_locationt &l=source_locationt::nil())
Definition: goto_program.h:971
void update()
Update all indices.
void insert_before_swap(targett target)
Insertion that preserves jumps to "target".
Definition: goto_program.h:643
void destructive_insert(const_targett target, goto_programt &p)
Inserts the given program p before target.
Definition: goto_program.h:730
instructionst::iterator targett
Definition: goto_program.h:614
targett insert_after(const_targett target)
Insertion after the instruction pointed-to by the given instruction iterator target.
Definition: goto_program.h:708
static instructiont make_decl(const symbol_exprt &symbol, const source_locationt &l=source_locationt::nil())
Definition: goto_program.h:964
const irep_idt & id() const
Definition: irep.h:384
A namespacet is essentially one or two symbol tables bound together, to allow for symbol lookups in t...
Definition: namespace.h:94
bool lookup(const irep_idt &name, const symbolt *&symbol) const override
See documentation for namespace_baset::lookup().
Definition: namespace.cpp:148
const typet & base_type() const
The type of the data what we point to.
Definition: pointer_expr.h:35
Expression to hold a symbol (variable)
Definition: std_expr.h:131
The symbol table base class interface.
Symbol table entry.
Definition: symbol.h:28
class symbol_exprt symbol_expr() const
Produces a symbol_exprt for a symbol.
Definition: symbol.cpp:121
irep_idt mode
Language mode.
Definition: symbol.h:49
The type of an expression, extends irept.
Definition: type.h:29
static bool is_nondet_pointer(exprt expr)
Returns true if expr is a nondet pointer that isn't a function pointer or a void* pointer as these ca...
static goto_programt get_gen_nondet_init_instructions(const symbol_exprt &aux_symbol_expr, const source_locationt &source_loc, symbol_table_baset &symbol_table, message_handlert &message_handler, const java_object_factory_parameterst &object_factory_parameters, const irep_idt &mode)
Populate instructions with goto instructions to nondet init aux_symbol_expr
void convert_nondet(const irep_idt &function_identifier, goto_programt &goto_program, symbol_table_baset &symbol_table, message_handlert &message_handler, const java_object_factory_parameterst &user_object_factory_parameters, const irep_idt &mode)
For each instruction in the goto program, checks if it is an assignment from nondet and replaces it w...
static std::pair< goto_programt::targett, bool > insert_nondet_init_code(const irep_idt &function_identifier, goto_programt &goto_program, const goto_programt::targett &target, symbol_table_baset &symbol_table, message_handlert &message_handler, java_object_factory_parameterst object_factory_parameters, const irep_idt &mode)
Checks an instruction to see whether it contains an assignment from side_effect_expr_nondet.
Convert side_effect_expr_nondett expressions using java_object_factory.
void goto_convert(const codet &code, symbol_table_baset &symbol_table, goto_programt &dest, message_handlert &message_handler, const irep_idt &mode)
Program Transformation.
Symbol Table + CFG.
void gen_nondet_init(const exprt &expr, code_blockt &init_code, symbol_table_baset &symbol_table, const source_locationt &loc, bool skip_classid, lifetimet lifetime, const java_object_factory_parameterst &object_factory_parameters, const select_pointer_typet &pointer_type_selector, update_in_placet update_in_place, message_handlert &log)
Initializes a primitive-typed or reference-typed object tree rooted at expr, allocating child objects...
This module is responsible for the synthesis of code (in the form of a sequence of codet statements) ...
symbolt & fresh_java_symbol(const typet &type, const std::string &basename_prefix, const source_locationt &source_location, const irep_idt &function_name, symbol_table_baset &symbol_table)
Definition: java_utils.cpp:555
const pointer_typet & to_pointer_type(const typet &type)
Cast a typet to a pointer_typet.
Definition: pointer_expr.h:93
void remove_skip(goto_programt &goto_program, goto_programt::targett begin, goto_programt::targett end)
remove unnecessary skip statements
Definition: remove_skip.cpp:87
Program Transformation.
bool can_cast_expr< side_effect_expr_nondett >(const exprt &base)
Definition: std_code.h:1540
side_effect_expr_nondett & to_side_effect_expr_nondet(exprt &expr)
Definition: std_code.h:1548
irep_idt function_id
Function id, used as a prefix for identifiers of temporaries.
size_t min_null_tree_depth
To force a certain depth of non-null objects.