@@ -22,6 +22,7 @@ Author: Peter Schrammel
2222#include < util/pointer_offset_size.h>
2323#include < util/ssa_expr.h>
2424#include < util/std_expr.h>
25+ #include < util/string_constant.h>
2526
2627#include < langapi/language_util.h>
2728#include < solvers/flattening/boolbv_width.h>
@@ -34,12 +35,14 @@ irep_idt extract_field_name(const exprt &string_expr)
3435 return extract_field_name (to_address_of_expr (string_expr).object ());
3536 else if (can_cast_expr<index_exprt>(string_expr))
3637 return extract_field_name (to_index_expr (string_expr).array ());
37- else if (string_expr. id () == ID_string_constant )
38+ else if (can_cast_expr<string_constantt>(string_expr) )
3839 {
3940 return string_expr.get (ID_value);
4041 }
4142 else
42- UNREACHABLE;
43+ {
44+ UNREACHABLE_BECAUSE (" Failed to extract shadow memory field name." );
45+ }
4346}
4447
4548// / If the given type is an array type, then remove the L2 level renaming
@@ -311,7 +314,11 @@ static void extract_bytes_of_bv(
311314 const typet &field_type,
312315 exprt::operandst &values)
313316{
314- const size_t size = to_bitvector_type (type).get_width () / 8 ;
317+ INVARIANT (
318+ can_cast_type<bitvector_typet>(type),
319+ " Cannot combine with *or* elements of a non-bitvector type." );
320+ const size_t size =
321+ to_bitvector_type (type).get_width () / config.ansi_c .char_width ;
315322 values.push_back (typecast_exprt::conditional_cast (value, field_type));
316323 for (size_t i = 1 ; i < size; ++i)
317324 {
@@ -372,6 +379,10 @@ exprt compute_or_over_bytes(
372379 const messaget &log,
373380 const bool is_union)
374381{
382+ INVARIANT (
383+ can_cast_type<c_bool_typet>(field_type) ||
384+ can_cast_type<bool_typet>(field_type),
385+ " Can aggregate bytes with *or* only if the shadow memory type is _Bool." );
375386 const typet type = ns.follow (expr.type ());
376387
377388 if (type.id () == ID_struct || type.id () == ID_union)
@@ -601,29 +612,32 @@ are_types_compatible(const typet &expr_type, const typet &shadow_type)
601612// / equality for exact matching.
602613static void clean_string_constant (exprt &expr)
603614{
615+ const auto *index_expr = expr_try_dynamic_cast<index_exprt>(expr);
604616 if (
605- expr. id () == ID_index && to_index_expr (expr). index ().is_zero () &&
606- to_index_expr (expr). array (). id () == ID_string_constant )
617+ index_expr && index_expr-> index ().is_zero () &&
618+ can_cast_expr<string_constantt>(index_expr-> array ()) )
607619 {
608- expr = to_index_expr (expr). array ();
620+ expr = index_expr-> array ();
609621 }
610622}
611623
612624// TODO: doxygen?
613625static void adjust_array_types (typet &type)
614626{
615- if (type.id () != ID_pointer)
627+ auto *pointer_type = type_try_dynamic_cast<pointer_typet>(type);
628+ if (!pointer_type)
616629 {
617630 return ;
618631 }
619- const typet &subtype = to_pointer_type (type).base_type ();
620- if (subtype.id () == ID_array)
632+ if (
633+ const auto *array_type =
634+ type_try_dynamic_cast<array_typet>(pointer_type->base_type ()))
621635 {
622- to_pointer_type (type). base_type () = to_array_type (subtype). element_type ();
636+ pointer_type-> base_type () = array_type-> element_type ();
623637 }
624- if (subtype .id () == ID_string_constant)
638+ if (pointer_type-> base_type () .id () == ID_string_constant)
625639 {
626- to_pointer_type (type). base_type () = char_type ();
640+ pointer_type-> base_type () = char_type ();
627641 }
628642}
629643
@@ -927,6 +941,10 @@ bool check_value_set_contains_only_null_ptr(
927941 const std::vector<exprt> &value_set,
928942 const exprt &expr)
929943{
944+ INVARIANT (
945+ can_cast_type<pointer_typet>(expr.type ()),
946+ " Cannot check if value_set contains only NULL as `expr` type is not a "
947+ " pointer." );
930948 const null_pointer_exprt null_pointer (to_pointer_type (expr.type ()));
931949 if (value_set.size () == 1 && contains_null_or_invalid (value_set, null_pointer))
932950 {
0 commit comments