CBMC
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
simple_method_stubbing.cpp
Go to the documentation of this file.
1/*******************************************************************\
2
3Module: Simple Java method stubbing
4
5Author: Diffblue Ltd.
6
7\*******************************************************************/
8
11
13
18
19#include "java_utils.h"
21#include <util/namespace.h>
22#include <util/std_code.h>
24
60
82 const typet &expected_type,
83 const exprt &ptr,
84 const source_locationt &loc,
85 const irep_idt &function_id,
87 const unsigned insert_before_index,
88 const bool is_constructor,
89 const bool update_in_place)
90{
91 // At this point we know 'ptr' points to an opaque-typed object.
92 // We should nondet-initialize it and insert the instructions *after*
93 // the offending call at (*parent_block)[insert_before_index].
94
97 "Nondet initializer result type: expected a pointer",
99
100 if(to_pointer_type(expected_type).base_type().id() != ID_struct_tag)
101 return;
102
104 const exprt cast_ptr =
106
108 // If it's a constructor the thing we're constructing has already
109 // been allocated by this point.
112
115 parameters.min_null_tree_depth = 1;
116
117 // Generate new instructions.
119 parameters.function_id = function_id;
121 to_init,
124 loc,
127 parameters,
131
132 // Insert new_instructions into parent block.
133 if(!new_instructions.statements().empty())
134 {
135 auto insert_position = parent_block.statements().begin();
137 parent_block.statements().insert(
139 new_instructions.statements().begin(),
140 new_instructions.statements().end());
141 }
142}
143
149{
152
153 // synthetic source location that contains the opaque function name only
155 synthesized_source_location.set_function(symbol.name);
156
157 // make sure all parameters are named
158 for(auto &parameter : required_type.parameters())
159 {
160 if(parameter.get_identifier().empty())
161 {
163 parameter.type(),
164 "#anon",
166 symbol.name,
168 parameter_symbol.is_parameter = true;
169 parameter.set_base_name(parameter_symbol.base_name);
170 parameter.set_identifier(parameter_symbol.name);
171 }
172 }
173
174 // Initialize the return value or `this` parameter under construction.
175 // Note symbol.type is required_type, but with write access
176 // Probably required_type should not be const
177 const bool is_constructor = required_type.get_is_constructor();
179 {
180 const auto &this_argument = required_type.parameters()[0];
181 const typet &this_type = this_argument.type();
183 this_type,
184 "to_construct",
186 symbol.name,
188 const symbol_exprt &init_symbol_expression = init_symbol.symbol_expr();
191 symbol_exprt(this_argument.get_identifier(), this_type));
192 get_argument.add_source_location() = synthesized_source_location;
195 this_type,
198 symbol.name,
200 1,
201 true,
202 false);
203 }
204 else
205 {
206 const typet &required_return_type = required_type.return_type();
208 {
211 "to_return",
213 symbol.name,
215 const exprt &to_return = to_return_symbol.symbol_expr();
216 if(to_return_symbol.type.id() != ID_pointer)
217 {
220 parameters.min_null_tree_depth = 1;
221
223 to_return,
227 false,
228 lifetimet::AUTOMATIC_LOCAL, // Irrelevant as type is primitive
229 parameters,
232 }
233 else
236 to_return,
238 symbol.name,
240 0,
241 false,
242 false);
244 }
245 }
246
247 symbol.value = new_instructions;
248}
249
254{
256 if(!sym.is_type && sym.value.id() == ID_nil &&
257 sym.type.id() == ID_code &&
258 // do not stub internal locking calls as 'create_method_stub' does not
259 // automatically create the appropriate symbols for the formal parameters.
260 // This means that symex will (rightfully) crash when it encounters the
261 // function call as it will not be able to find symbols for the fromal
262 // parameters.
263 sym.name !=
264 "java::java.lang.Object.monitorenter:(Ljava/lang/Object;)V" &&
265 sym.name !=
266 "java::java.lang.Object.monitorexit:(Ljava/lang/Object;)V")
267 {
269 }
270}
271
273 const irep_idt &function_name,
274 symbol_table_baset &symbol_table,
275 bool assume_non_null,
276 const java_object_factory_parameterst &object_factory_parameters,
277 message_handlert &message_handler)
278{
280 symbol_table, assume_non_null, object_factory_parameters, message_handler);
281
282 stub_generator.check_method_stub(function_name);
283}
284
295 symbol_table_baset &symbol_table,
296 bool assume_non_null,
297 const java_object_factory_parameterst &object_factory_parameters,
298 message_handlert &message_handler)
299{
300 // The intent here is to apply stub_generator.check_method_stub() to
301 // all the identifiers in the symbol table. However this method may alter the
302 // symbol table and iterating over a container which is being modified has
303 // undefined behaviour. Therefore in order for this to work reliably, we must
304 // take a copy of the identifiers in the symbol table and iterate over that,
305 // instead of iterating over the symbol table itself.
306 std::vector<irep_idt> identifiers;
307 identifiers.reserve(symbol_table.symbols.size());
308 for(const auto &symbol : symbol_table)
309 identifiers.push_back(symbol.first);
310
312 symbol_table, assume_non_null, object_factory_parameters, message_handler);
313
314 for(const auto &identifier : identifiers)
315 {
316 stub_generator.check_method_stub(identifier);
317 }
318}
@ DYNAMIC
Allocate dynamic objects (using ALLOCATE)
@ AUTOMATIC_LOCAL
Allocate local objects with automatic lifetime.
ait supplies three of the four components needed: an abstract interpreter (in this case handling func...
Definition ai.h:562
A codet representing sequential composition of program statements.
Definition std_code.h:130
A codet representing an assignment in the program.
Definition std_code.h:24
codet representation of a "return from a function" statement.
Definition std_code.h:893
Operator to dereference a pointer.
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
void check_method_stub(const irep_idt &)
Replaces sym with a function stub per the function above if it is of suitable type.
const java_object_factory_parameterst & object_factory_parameters
java_simple_method_stubst(symbol_table_baset &_symbol_table, bool _assume_non_null, const java_object_factory_parameterst &_object_factory_parameters, message_handlert &_message_handler)
void create_method_stub_at(const typet &expected_type, const exprt &ptr, const source_locationt &loc, const irep_idt &function_id, code_blockt &parent_block, unsigned insert_before_index, bool is_constructor, bool update_in_place)
Nondet-initialize an object, including allocating referees for reference fields and nondet-initialisi...
void create_method_stub(symbolt &symbol)
Replaces sym's value with an opaque method stub.
A namespacet is essentially one or two symbol tables bound together, to allow for symbol lookups in t...
Definition namespace.h:91
Expression to hold a symbol (variable)
Definition std_expr.h:131
The symbol table base class interface.
symbolt & get_writeable_ref(const irep_idt &name)
Find a symbol in the symbol table for read-write access.
const symbolst & symbols
Read-only field, used to look up symbols given their names.
const symbolt & lookup_ref(const irep_idt &name) const
Find a symbol in the symbol table for read-only access.
Symbol table entry.
Definition symbol.h:28
typet type
Type of symbol.
Definition symbol.h:31
irep_idt name
The unique identifier.
Definition symbol.h:40
exprt value
Initial value of symbol.
Definition symbol.h:34
The type of an expression, extends irept.
Definition type.h:29
#define INVARIANT_WITH_IREP(CONDITION, DESCRIPTION, IREP)
Equivalent to INVARIANT_STRUCTURED(CONDITION, invariant_failedt, pretty_print_invariant_with_irep(I...
static bool is_constructor(const irep_idt &method_name)
static std::unordered_set< irep_idt > init_symbol(const symbolt &sym, code_blockt &code_block, symbol_table_baset &symbol_table, const source_locationt &source_location, bool assume_init_pointers_not_null, const java_object_factory_parameterst &object_factory_parameters, const select_pointer_typet &pointer_type_selector, bool string_refinement_enabled, message_handlert &message_handler)
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) ...
exprt make_clean_pointer_cast(const exprt &rawptr, const pointer_typet &target_type, const namespacet &ns)
JAVA Pointer Casts.
empty_typet java_void_type()
const java_method_typet & to_java_method_type(const typet &type)
Definition java_types.h:183
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)
const pointer_typet & to_pointer_type(const typet &type)
Cast a typet to a pointer_typet.
void java_generate_simple_method_stub(const irep_idt &function_name, symbol_table_baset &symbol_table, bool assume_non_null, const java_object_factory_parameterst &object_factory_parameters, message_handlert &message_handler)
void java_generate_simple_method_stubs(symbol_table_baset &symbol_table, bool assume_non_null, const java_object_factory_parameterst &object_factory_parameters, message_handlert &message_handler)
Generates function stubs for most undefined functions in the symbol table, except as forbidden in jav...
Java simple opaque stub generation.
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.
Author: Diffblue Ltd.