@@ -142,9 +142,9 @@ exprt value_set_dereferencet::dereference(
142
142
const exprt &pointer,
143
143
bool display_points_to_sets)
144
144
{
145
- if (pointer. type (). id ()!=ID_pointer)
146
- throw " dereference expected pointer type, but got " +
147
- pointer.type ().pretty ();
145
+ PRECONDITION_WITH_DIAGNOSTICS (
146
+ pointer. type (). id () == ID_pointer,
147
+ " dereference expected pointer type, but got " + pointer.type ().pretty () );
148
148
149
149
// we may get ifs due to recursive calls
150
150
if (pointer.id ()==ID_if)
@@ -465,8 +465,9 @@ value_set_dereferencet::valuet value_set_dereferencet::build_reference_to(
465
465
return valuet ();
466
466
}
467
467
468
- if (what.id ()!=ID_object_descriptor)
469
- throw " unknown points-to: " +what.id_string ();
468
+ PRECONDITION_WITH_DIAGNOSTICS (
469
+ what.id () == ID_object_descriptor,
470
+ " unknown points-to: " + what.id_string ());
470
471
471
472
const object_descriptor_exprt &o=to_object_descriptor_expr (what);
472
473
@@ -477,24 +478,28 @@ value_set_dereferencet::valuet value_set_dereferencet::build_reference_to(
477
478
std::cout << "O: " << format(root_object) << '\n';
478
479
#endif
479
480
480
- valuet result;
481
-
482
481
if (root_object.id () == ID_null_object)
483
482
{
484
- if (o.offset ().is_zero ())
485
- result.pointer = null_pointer_exprt{pointer_type};
486
- else
487
- return valuet{};
483
+ if (!o.offset ().is_zero ())
484
+ return {};
485
+
486
+ valuet result;
487
+ result.pointer = null_pointer_exprt{pointer_type};
488
+ return result;
488
489
}
489
490
else if (root_object.id ()==ID_dynamic_object)
490
491
{
492
+ valuet result;
493
+
491
494
// constraint that it actually is a dynamic object
492
495
// this is also our guard
493
496
result.pointer_guard = is_dynamic_object_exprt (pointer_expr);
494
497
495
498
// can't remove here, turn into *p
496
499
result.value = dereference_exprt{pointer_expr};
497
500
result.pointer = pointer_expr;
501
+
502
+ return result;
498
503
}
499
504
else if (root_object.id ()==ID_integer_address)
500
505
{
@@ -514,8 +519,10 @@ value_set_dereferencet::valuet value_set_dereferencet::build_reference_to(
514
519
pointer_offset (pointer_expr),
515
520
to_array_type (memory_symbol.type ).element_type ());
516
521
522
+ valuet result;
517
523
result.value =index_expr;
518
524
result.pointer = address_of_exprt{index_expr};
525
+ return result;
519
526
}
520
527
else if (dereference_type_compare (
521
528
to_array_type (memory_symbol.type ).element_type (),
@@ -526,28 +533,32 @@ value_set_dereferencet::valuet value_set_dereferencet::build_reference_to(
526
533
symbol_expr,
527
534
pointer_offset (pointer_expr),
528
535
to_array_type (memory_symbol.type ).element_type ());
536
+
537
+ valuet result;
529
538
result.value =typecast_exprt (index_expr, dereference_type);
530
539
result.pointer =
531
540
typecast_exprt{address_of_exprt{index_expr}, pointer_type};
541
+ return result;
532
542
}
533
543
else
534
544
{
535
545
// We need to use byte_extract.
536
546
// Won't do this without a commitment to an endianness.
537
547
538
548
if (config.ansi_c .endianness ==configt::ansi_ct::endiannesst::NO_ENDIANNESS)
539
- {
540
- }
541
- else
542
- {
543
- result.value = make_byte_extract (
544
- symbol_expr, pointer_offset (pointer_expr), dereference_type);
545
- result.pointer = address_of_exprt{result.value };
546
- }
549
+ return {};
550
+
551
+ valuet result;
552
+ result.value = make_byte_extract (
553
+ symbol_expr, pointer_offset (pointer_expr), dereference_type);
554
+ result.pointer = address_of_exprt{result.value };
555
+ return result;
547
556
}
548
557
}
549
558
else
550
559
{
560
+ valuet result;
561
+
551
562
// something generic -- really has to be a symbol
552
563
address_of_exprt object_pointer (object);
553
564
@@ -565,8 +576,6 @@ value_set_dereferencet::valuet value_set_dereferencet::build_reference_to(
565
576
const typet &object_type = object.type ();
566
577
const typet &root_object_type = root_object.type ();
567
578
568
- exprt root_object_subexpression=root_object;
569
-
570
579
if (
571
580
dereference_type_compare (object_type, dereference_type, ns) &&
572
581
o.offset ().is_zero ())
@@ -577,89 +586,81 @@ value_set_dereferencet::valuet value_set_dereferencet::build_reference_to(
577
586
result.value = typecast_exprt::conditional_cast (object, dereference_type);
578
587
result.pointer =
579
588
typecast_exprt::conditional_cast (object_pointer, pointer_type);
589
+
590
+ return result;
580
591
}
581
- else if (
592
+
593
+ // this is relative to the root object
594
+ exprt offset;
595
+ if (o.offset ().is_constant ())
596
+ offset = o.offset ();
597
+ else
598
+ offset = simplify_expr (pointer_offset (pointer_expr), ns);
599
+
600
+ if (
582
601
root_object_type.id () == ID_array &&
583
602
dereference_type_compare (
584
603
to_array_type (root_object_type).element_type (), dereference_type, ns) &&
585
604
pointer_offset_bits (to_array_type (root_object_type).element_type (), ns) ==
586
- pointer_offset_bits (dereference_type, ns))
605
+ pointer_offset_bits (dereference_type, ns) &&
606
+ offset.is_constant ())
587
607
{
588
608
// We have an array with a subtype that matches
589
609
// the dereferencing type.
590
- exprt offset;
591
-
592
- // this should work as the object is essentially the root object
593
- if (o.offset ().is_constant ())
594
- offset=o.offset ();
595
- else
596
- offset=pointer_offset (pointer_expr);
597
610
598
611
// are we doing a byte?
599
612
auto element_size =
600
613
pointer_offset_size (to_array_type (root_object_type).element_type (), ns);
614
+ CHECK_RETURN (element_size.has_value ());
615
+ CHECK_RETURN (*element_size > 0 );
601
616
602
- if (!element_size.has_value () || *element_size == 0 )
603
- {
604
- throw " unknown or invalid type size of:\n " +
605
- to_array_type (root_object_type).element_type ().pretty ();
606
- }
607
-
608
- exprt element_size_expr = from_integer (*element_size, offset.type ());
609
-
610
- exprt adjusted_offset =
611
- simplify_expr (div_exprt{offset, element_size_expr}, ns);
617
+ const auto offset_int =
618
+ numeric_cast_v<mp_integer>(to_constant_expr (offset));
612
619
613
- index_exprt index_expr{root_object, adjusted_offset};
614
- result.value =
615
- typecast_exprt::conditional_cast (index_expr, dereference_type);
616
- result.pointer = typecast_exprt::conditional_cast (
617
- address_of_exprt{index_expr}, pointer_type);
618
- }
619
- else
620
- {
621
- // try to build a member/index expression - do not use byte_extract
622
- auto subexpr = get_subexpression_at_offset (
623
- root_object_subexpression, o.offset (), dereference_type, ns);
624
- if (subexpr.has_value ())
625
- simplify (subexpr.value (), ns);
626
- if (
627
- subexpr.has_value () &&
628
- subexpr.value ().id () != ID_byte_extract_little_endian &&
629
- subexpr.value ().id () != ID_byte_extract_big_endian)
620
+ if (offset_int % *element_size == 0 )
630
621
{
631
- // Successfully found a member, array index, or combination thereof
632
- // that matches the desired type and offset:
633
- result.value = subexpr.value ();
622
+ index_exprt index_expr{
623
+ root_object,
624
+ from_integer (
625
+ offset_int / *element_size,
626
+ to_array_type (root_object_type).index_type ())};
627
+ result.value =
628
+ typecast_exprt::conditional_cast (index_expr, dereference_type);
634
629
result.pointer = typecast_exprt::conditional_cast (
635
- address_of_exprt{skip_typecast (subexpr.value ())}, pointer_type);
630
+ address_of_exprt{index_expr}, pointer_type);
631
+
636
632
return result;
637
633
}
634
+ }
638
635
639
- // we extract something from the root object
640
- result.value =o.root_object ();
636
+ // try to build a member/index expression - do not use byte_extract
637
+ auto subexpr = get_subexpression_at_offset (
638
+ root_object, o.offset (), dereference_type, ns);
639
+ if (subexpr.has_value ())
640
+ simplify (subexpr.value (), ns);
641
+ if (
642
+ subexpr.has_value () &&
643
+ subexpr.value ().id () != ID_byte_extract_little_endian &&
644
+ subexpr.value ().id () != ID_byte_extract_big_endian)
645
+ {
646
+ // Successfully found a member, array index, or combination thereof
647
+ // that matches the desired type and offset:
648
+ result.value = subexpr.value ();
641
649
result.pointer = typecast_exprt::conditional_cast (
642
- address_of_exprt{skip_typecast (o.root_object ())}, pointer_type);
650
+ address_of_exprt{skip_typecast (subexpr.value ())}, pointer_type);
651
+ return result;
652
+ }
643
653
644
- // this is relative to the root object
645
- exprt offset;
646
- if (o.offset ().id ()==ID_unknown)
647
- offset=pointer_offset (pointer_expr);
648
- else
649
- offset=o.offset ();
654
+ // we extract something from the root object
655
+ result.value = o.root_object ();
656
+ result.pointer = typecast_exprt::conditional_cast (
657
+ address_of_exprt{skip_typecast (o.root_object ())}, pointer_type);
650
658
651
- if (memory_model (result.value , dereference_type, offset, ns))
652
- {
653
- // ok, done
654
- }
655
- else
656
- {
657
- return valuet (); // give up, no way that this is ok
658
- }
659
- }
660
- }
659
+ if (!memory_model (result.value , dereference_type, offset, ns))
660
+ return {}; // give up, no way that this is ok
661
661
662
- return result;
662
+ return result;
663
+ }
663
664
}
664
665
665
666
static bool is_a_bv_type (const typet &type)
0 commit comments