@@ -106,17 +106,16 @@ SCENARIO(
106
106
code_blockt block;
107
107
for (auto code_with_references : code.list )
108
108
block.append (code_with_references->to_code (reference_substitution));
109
- THEN (" The instruction is the declaration of a symbol of TestClass* type" )
109
+ THEN (
110
+ " The instruction is the declaration of a symbol of TestClass* type,"
111
+ " followed by its allocation" )
110
112
{
111
113
const symbol_exprt declared_symbol =
112
114
make_query (block)[0 ].as <code_declt>()[0 ].as <symbol_exprt>().get ();
113
115
REQUIRE (declared_symbol.type () == test_class_type);
114
- THEN (" The instruction allocates the symbol" )
115
- {
116
- REQUIRE (
117
- make_query (block)[1 ].as <code_assignt>()[0 ].as <symbol_exprt>().get () ==
118
- declared_symbol);
119
- }
116
+ REQUIRE (
117
+ make_query (block)[1 ].as <code_assignt>()[0 ].as <symbol_exprt>().get () ==
118
+ declared_symbol);
120
119
}
121
120
THEN (" The instruction assigns the symbol to `symbol_to_assign`" )
122
121
{
@@ -427,4 +426,210 @@ SCENARIO(
427
426
.get ()) == 42 );
428
427
}
429
428
}
429
+ GIVEN (" An object with two fields referencing the same array" )
430
+ {
431
+ const json_objectt json = [] {
432
+ json_objectt entry{};
433
+ entry[" array_field_1" ] = [] {
434
+ json_objectt json;
435
+ json[" @ref" ] = json_stringt{" id_of_array_2" };
436
+ return json;
437
+ }();
438
+ entry[" array_field_2" ] = [] {
439
+ json_objectt int_json;
440
+ int_json[" @items" ] = json_arrayt{json_numbert{" 42" }};
441
+ int_json[" @type" ] = json_stringt{" [I" };
442
+ int_json[" @id" ] = json_stringt{" id_of_array_2" };
443
+ return int_json;
444
+ }();
445
+ entry[" @type" ] = json_stringt{" TestClass" };
446
+ return entry;
447
+ }();
448
+ class_to_declared_symbols.emplace (" java::TestClass" , [] {
449
+ symbolt field_symbol;
450
+ field_symbol.base_name = " array_field_1" ;
451
+ field_symbol.name = " field_name_1_for_codet" ;
452
+ field_symbol.type = java_int_type ();
453
+ field_symbol.is_static_lifetime = true ;
454
+ return field_symbol;
455
+ }());
456
+ class_to_declared_symbols.emplace (" java::TestClass" , [] {
457
+ symbolt field_symbol;
458
+ field_symbol.base_name = " array_field_2" ;
459
+ field_symbol.name = " field_name_2_for_codet" ;
460
+ field_symbol.type = java_int_type ();
461
+ field_symbol.is_static_lifetime = true ;
462
+ return field_symbol;
463
+ }());
464
+ const irep_idt clinit_name = add_clinit (symbol_table, " TestClass" );
465
+ add_class_with_components (
466
+ symbol_table,
467
+ " TestClass" ,
468
+ {std::pair<std::string, typet>(" @class_identifier" , string_typet{}),
469
+ std::pair<std::string, typet>(" array_field_1" , java_array_type (' i' )),
470
+ std::pair<std::string, typet>(" array_field_2" , java_array_type (' i' ))});
471
+ // For array[int]
472
+ add_java_array_types (symbol_table);
473
+
474
+ const reference_typet test_class_type =
475
+ reference_type (struct_tag_typet{" java::TestClass" });
476
+ optionalt<ci_lazy_methods_neededt> option{};
477
+ const code_with_references_listt code = assign_from_json (
478
+ symbol_exprt{" symbol_to_assign" , test_class_type},
479
+ json,
480
+ clinit_name,
481
+ symbol_table,
482
+ option,
483
+ max_user_array_length,
484
+ references);
485
+
486
+ code_with_referencest::reference_substitutiont reference_substitution =
487
+ [&](const std::string &reference_id) -> object_creation_referencet & {
488
+ REQUIRE (reference_id == " id_of_array_2" );
489
+ auto it = references.find (reference_id);
490
+ REQUIRE (it != references.end ());
491
+ return it->second ;
492
+ };
493
+ code_blockt block;
494
+ for (auto code_with_references : code.list )
495
+ block.append (code_with_references->to_code (reference_substitution));
496
+
497
+ THEN (
498
+ " The instruction declares a symbol of TestClass* type: "
499
+ " TestClass* malloc_site;" )
500
+ {
501
+ const symbol_exprt allocation_symbol =
502
+ make_query (block)[0 ].as <code_declt>()[0 ].as <symbol_exprt>().get ();
503
+ REQUIRE (allocation_symbol.type () == test_class_type);
504
+ }
505
+ THEN (
506
+ " declares the array data: "
507
+ " int[] user_specified_array_ref;" )
508
+ {
509
+ REQUIRE (
510
+ make_query (block)[1 ]
511
+ .as <code_declt>()[0 ]
512
+ .as <symbol_exprt>()
513
+ .get ()
514
+ .type () == java_array_type (' i' ));
515
+ }
516
+ THEN (
517
+ " declares the length: "
518
+ " int user_specified_array_length;" )
519
+ {
520
+ REQUIRE (
521
+ make_query (block)[2 ]
522
+ .as <code_declt>()[0 ]
523
+ .as <symbol_exprt>()
524
+ .get ()
525
+ .type () == java_int_type ());
526
+ }
527
+ THEN (
528
+ " declares the data:"
529
+ " int* user_specified_array_data_init;" )
530
+ {
531
+ REQUIRE (
532
+ make_query (block)[3 ]
533
+ .as <code_declt>()[0 ]
534
+ .as <symbol_exprt>()
535
+ .get ()
536
+ .type () == java_reference_type (java_int_type ()));
537
+ }
538
+ THEN (
539
+ " allocates the object:"
540
+ " malloc_site = new TestClass();" )
541
+ {
542
+ REQUIRE (
543
+ make_query (block)[4 ]
544
+ .as <code_assignt>()[0 ]
545
+ .as <symbol_exprt>()
546
+ .get ()
547
+ .type () == test_class_type);
548
+ REQUIRE (
549
+ make_query (block)[4 ]
550
+ .as <code_assignt>()[1 ]
551
+ .as <side_effect_exprt>()
552
+ .get ()
553
+ .get_statement () == ID_allocate);
554
+ }
555
+
556
+ THEN (
557
+ " assigns the allocated object:"
558
+ " symbol_to_assign = malloc_site;" )
559
+ {
560
+ REQUIRE (
561
+ make_query (block)[5 ]
562
+ .as <code_assignt>()[0 ]
563
+ .as <symbol_exprt>()
564
+ .get ()
565
+ .get_identifier () == " symbol_to_assign" );
566
+ }
567
+ THEN (
568
+ " zero-initialize the object:"
569
+ " *malloc_site = {\" java::\" , NULL, NULL};" )
570
+ {
571
+ REQUIRE (
572
+ make_query (block)[6 ]
573
+ .as <code_assignt>()[0 ]
574
+ .as <dereference_exprt>()[0 ]
575
+ .get ()
576
+ .type () == test_class_type);
577
+ }
578
+ THEN (
579
+ " allocate the array :"
580
+ " user_specified_array_ref = new int[1];" )
581
+ {
582
+ REQUIRE (
583
+ make_query (block)[7 ].as <code_assignt>()[0 ].get ().type () ==
584
+ java_array_type (' i' ));
585
+ const auto side_effect_expr = make_query (block)[7 ]
586
+ .as <code_assignt>()[1 ]
587
+ .as <side_effect_exprt>()
588
+ .get ();
589
+ REQUIRE (side_effect_expr.get_statement () == ID_java_new_array);
590
+ REQUIRE (
591
+ numeric_cast_v<mp_integer>(
592
+ make_query (side_effect_expr)[0 ].as <constant_exprt>().get ()) == 1 );
593
+ }
594
+ THEN (
595
+ " assign array_field_1 :"
596
+ " malloc_site->array_field_1 = user_specified_array_ref;" )
597
+ {
598
+ REQUIRE (
599
+ make_query (block)[8 ]
600
+ .as <code_assignt>()[0 ]
601
+ .as <member_exprt>()
602
+ .get ()
603
+ .get_component_name () == " array_field_1" );
604
+ }
605
+ THEN (
606
+ " assign pointer to the data for initializing it:"
607
+ " user_specified_array_data_init = user_specified_array_ref->data;" )
608
+ {
609
+ REQUIRE (
610
+ make_query (block)[9 ].as <code_assignt>()[0 ].get ().type () ==
611
+ java_reference_type (java_int_type ()));
612
+ }
613
+ THEN (
614
+ " assign the array cell value :"
615
+ " user_specified_array_data_init[0] = 42;" )
616
+ {
617
+ REQUIRE (
618
+ numeric_cast_v<mp_integer>(make_query (block)[10 ]
619
+ .as <code_assignt>()[1 ]
620
+ .as <constant_exprt>()
621
+ .get ()) == 42 );
622
+ }
623
+ THEN (
624
+ " assign array_field_2 :"
625
+ " malloc_site->array_field_2 = user_specified_array_ref;" )
626
+ {
627
+ REQUIRE (
628
+ make_query (block)[11 ]
629
+ .as <code_assignt>()[0 ]
630
+ .as <member_exprt>()
631
+ .get ()
632
+ .get_component_name () == " array_field_2" );
633
+ }
634
+ }
430
635
}
0 commit comments