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