@@ -110,6 +110,22 @@ class java_object_factoryt
110110 bool create_dynamic_objects,
111111 bool override =false ,
112112 const typet &override_type=empty_typet());
113+
114+ private:
115+ void gen_nondet_pointer_init (
116+ code_blockt &assignments,
117+ const exprt &expr,
118+ const irep_idt &class_identifier,
119+ bool create_dynamic_objects,
120+ const pointer_typet &pointer_type);
121+
122+ void gen_nondet_struct_init (
123+ code_blockt &assignments,
124+ const exprt &expr,
125+ bool is_sub,
126+ irep_idt class_identifier,
127+ bool create_dynamic_objects,
128+ const struct_typet &struct_type);
113129};
114130
115131// / \param assignments: The code block to add code to
@@ -250,6 +266,144 @@ void java_object_factoryt::gen_pointer_target_init(
250266 }
251267}
252268
269+ // / Initialises a primitive or object tree rooted at `expr`, of type pointer. It
270+ // / allocates child objects as necessary and nondet-initialising their members,
271+ // / \param assignments - the code block we are building with
272+ // / initilisation code
273+ // / \param expr: lvalue expression to initialise
274+ // / \param class_identifier - the name of the class so we can identify
275+ // / special cases where a null pointer is not applicable.
276+ // / \param create_dynamic_objects: if true, use malloc to allocate objects;
277+ // / otherwise generate fresh static symbols.
278+ // / \param pointer_type - The type of the pointer we are initalising
279+ void java_object_factoryt::gen_nondet_pointer_init (
280+ code_blockt &assignments,
281+ const exprt &expr,
282+ const irep_idt &class_identifier,
283+ bool create_dynamic_objects,
284+ const pointer_typet &pointer_type)
285+ {
286+ const typet &subtype=ns.follow (pointer_type.subtype ());
287+
288+ if (subtype.id ()==ID_struct)
289+ {
290+ const struct_typet &struct_type=to_struct_type (subtype);
291+ const irep_idt struct_tag=struct_type.get_tag ();
292+ // set to null if found in recursion set and not a sub-type
293+ if (recursion_set.find (struct_tag)!=recursion_set.end () &&
294+ struct_tag==class_identifier)
295+ {
296+ assignments.copy_to_operands (
297+ get_null_assignment (expr, pointer_type));
298+ return ;
299+ }
300+ }
301+
302+ code_blockt non_null_inst;
303+ gen_pointer_target_init (
304+ non_null_inst,
305+ expr,
306+ subtype,
307+ create_dynamic_objects);
308+
309+ if (assume_non_null)
310+ {
311+ // Add the following code to assignments:
312+ // <expr> = <aoe>;
313+ assignments.append (non_null_inst);
314+ }
315+ else
316+ {
317+ // if(NONDET(_Bool)
318+ // {
319+ // <expr> = <null pointer>
320+ // }
321+ // else
322+ // {
323+ // <code from recursive call to gen_nondet_init() with
324+ // tmp$<temporary_counter>>
325+ // }
326+ auto set_null_inst=get_null_assignment (expr, pointer_type);
327+
328+ code_ifthenelset null_check;
329+ null_check.cond ()=side_effect_expr_nondett (bool_typet ());
330+ null_check.then_case ()=set_null_inst;
331+ null_check.else_case ()=non_null_inst;
332+
333+ assignments.add (null_check);
334+ }
335+ }
336+
337+ // / Initialises an object tree rooted at `expr`, allocating child objects as
338+ // / necessary and nondet-initialising their members.
339+ // / \param assignments: The code block to append the new
340+ // / instructions to
341+ // / \param expr: pointer-typed lvalue expression to initialise
342+ // / \param is_sub: If true, `expr` is a substructure of a larger object, which
343+ // / in Java necessarily means a base class. not match *expr (for example, expr
344+ // / might be void*)
345+ // / \param class_identifier: clsid to initialise @java.lang.Object.
346+ // / @class_identifier
347+ // / \param create_dynamic_objects: if true, use malloc to allocate objects;
348+ // / otherwise generate fresh static symbols.
349+ // / \param struct_type - The type of the struct we are initalising
350+ void java_object_factoryt::gen_nondet_struct_init (
351+ code_blockt &assignments,
352+ const exprt &expr,
353+ bool is_sub,
354+ irep_idt class_identifier,
355+ bool create_dynamic_objects,
356+ const struct_typet &struct_type)
357+ {
358+ typedef struct_typet::componentst componentst;
359+
360+ const irep_idt struct_tag=struct_type.get_tag ();
361+
362+ const componentst &components=struct_type.components ();
363+
364+ if (!is_sub)
365+ class_identifier=struct_tag;
366+
367+ recursion_set.insert (struct_tag);
368+
369+ for (const auto &component : components)
370+ {
371+ const typet &component_type=component.type ();
372+ irep_idt name=component.get_name ();
373+
374+ member_exprt me (expr, name, component_type);
375+
376+ if (name==" @class_identifier" )
377+ {
378+ irep_idt qualified_clsid=" java::" +as_string (class_identifier);
379+ constant_exprt ci (qualified_clsid, string_typet ());
380+ code_assignt code (me, ci);
381+ code.add_source_location ()=loc;
382+ assignments.copy_to_operands (code);
383+ }
384+ else if (name==" @lock" )
385+ {
386+ code_assignt code (me, from_integer (0 , me.type ()));
387+ code.add_source_location ()=loc;
388+ assignments.copy_to_operands (code);
389+ }
390+ else
391+ {
392+ INVARIANT (!name.empty (), " Each component of a struct must have a name" );
393+
394+ bool _is_sub=name[0 ]==' @' ;
395+
396+ gen_nondet_init (
397+ assignments,
398+ me,
399+ _is_sub,
400+ class_identifier,
401+ create_dynamic_objects);
402+ }
403+ }
404+ recursion_set.erase (struct_tag);
405+ }
406+
253407// / Creates a nondet for expr, including calling itself recursively to make
254408// / appropriate symbols to point to if expr is a pointer or struct
255409// / \param expr: The expression which we are generating a non-determinate value
@@ -277,110 +431,23 @@ void java_object_factoryt::gen_nondet_init(
277431 {
278432 // dereferenced type
279433 const pointer_typet &pointer_type=to_pointer_type (type);
280- const typet &subtype=ns.follow (pointer_type.subtype ());
281-
282- if (subtype.id ()==ID_struct)
283- {
284- const struct_typet &struct_type=to_struct_type (subtype);
285- const irep_idt struct_tag=struct_type.get_tag ();
286- // set to null if found in recursion set and not a sub-type
287- if (recursion_set.find (struct_tag)!=recursion_set.end () &&
288- struct_tag==class_identifier)
289- {
290- assignments.copy_to_operands (
291- get_null_assignment (expr, pointer_type));
292- return ;
293- }
294- }
295-
296- code_blockt non_null_inst;
297- gen_pointer_target_init (
298- non_null_inst,
434+ gen_nondet_pointer_init (
435+ assignments,
299436 expr,
300- subtype,
301- create_dynamic_objects);
302-
303- if (assume_non_null)
304- {
305- // Add the following code to assignments:
306- // <expr> = <aoe>;
307- assignments.append (non_null_inst);
308- }
309- else
310- {
311- // Add the following code to assignments:
312- // IF !NONDET(_Bool) THEN GOTO <label1>
313- // <expr> = <null pointer>
314- // GOTO <label2>
315- // <label1>: <expr> = &tmp$<temporary_counter>;
316- // <code from recursive call to gen_nondet_init() with
317- // tmp$<temporary_counter>>
318- // And the next line is labelled label2
319- auto set_null_inst=get_null_assignment (expr, pointer_type);
320-
321- code_ifthenelset null_check;
322- null_check.cond ()=side_effect_expr_nondett (bool_typet ());
323- null_check.then_case ()=set_null_inst;
324- null_check.else_case ()=non_null_inst;
325-
326- assignments.add (null_check);
327- }
437+ class_identifier,
438+ create_dynamic_objects,
439+ pointer_type);
328440 }
329441 else if (type.id ()==ID_struct)
330442 {
331- typedef struct_typet::componentst componentst;
332-
333443 const struct_typet &struct_type=to_struct_type (type);
334- const irep_idt struct_tag=struct_type.get_tag ();
335-
336- const componentst &components=struct_type.components ();
337-
338- if (!is_sub)
339- class_identifier=struct_tag;
340-
341- recursion_set.insert (struct_tag);
342- assert (!recursion_set.empty ());
343-
344- for (const auto &component : components)
345- {
346- const typet &component_type=component.type ();
347- irep_idt name=component.get_name ();
348-
349- member_exprt me (expr, name, component_type);
350-
351- if (name==" @class_identifier" )
352- {
353- irep_idt qualified_clsid=" java::" +as_string (class_identifier);
354- constant_exprt ci (qualified_clsid, string_typet ());
355- code_assignt code (me, ci);
356- code.add_source_location ()=loc;
357- assignments.copy_to_operands (code);
358- }
359- else if (name==" @lock" )
360- {
361- code_assignt code (me, from_integer (0 , me.type ()));
362- code.add_source_location ()=loc;
363- assignments.copy_to_operands (code);
364- }
365- else
366- {
367- assert (!name.empty ());
368-
369- bool _is_sub=name[0 ]==' @' ;
370- #if 0
371- irep_idt _class_identifier=
372- _is_sub?(class_identifier.empty()?struct_tag:class_identifier):"";
373- #endif
374-
375- gen_nondet_init (
376- assignments,
377- me,
378- _is_sub,
379- class_identifier,
380- create_dynamic_objects);
381- }
382- }
383- recursion_set.erase (struct_tag);
444+ gen_nondet_struct_init (
445+ assignments,
446+ expr,
447+ is_sub,
448+ class_identifier,
449+ create_dynamic_objects,
450+ struct_type);
384451 }
385452 else
386453 {
0 commit comments