Skip to content

Commit df12fce

Browse files
author
Enrico Steffinlongo
committed
Improvements to shadow memory util implementation
Improved typet and exprt conversion to use the more modern try_cast and can_cast instead of using expr.id() Added few INVARIANTS with meaningful messages where necessary
1 parent 25e3a47 commit df12fce

File tree

2 files changed

+32
-13
lines changed

2 files changed

+32
-13
lines changed

src/goto-symex/shadow_memory.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,8 @@ void shadow_memoryt::symex_get_field(
315315
#ifdef DEBUG_SHADOW_MEMORY
316316
log.debug() << "Shadow memory: RHS: " << format(rhs) << messaget::eom;
317317
#endif
318-
// TODO: create the assignment of __CPROVER_shadow_memory_get_field
318+
319+
// create the assignment of __CPROVER_shadow_memory_get_field
319320
symex_assign(state, lhs, typecast_exprt::conditional_cast(rhs, lhs.type()));
320321
}
321322
else

src/goto-symex/shadow_memory_util.cpp

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -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.
602613
static 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?
613625
static 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

Comments
 (0)