@@ -110,6 +110,22 @@ class java_object_factoryt
110
110
bool create_dynamic_objects,
111
111
bool override =false ,
112
112
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);
113
129
};
114
130
115
131
// / \param assignments: The code block to add code to
@@ -250,6 +266,144 @@ void java_object_factoryt::gen_pointer_target_init(
250
266
}
251
267
}
252
268
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
+
253
407
// / Creates a nondet for expr, including calling itself recursively to make
254
408
// / appropriate symbols to point to if expr is a pointer or struct
255
409
// / \param expr: The expression which we are generating a non-determinate value
@@ -277,110 +431,23 @@ void java_object_factoryt::gen_nondet_init(
277
431
{
278
432
// dereferenced type
279
433
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,
299
436
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);
328
440
}
329
441
else if (type.id ()==ID_struct)
330
442
{
331
- typedef struct_typet::componentst componentst;
332
-
333
443
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);
384
451
}
385
452
else
386
453
{
0 commit comments