Skip to content

Commit a985eae

Browse files
committed
Interpreter: deal with member-of-constant-struct expressions
It could already do index-of-constant-array -- by replacing its custom code with simplify_expr we can expand that to also support member-of-constant-struct, as occurs when symex's deref'ing and then the interpreter's environment translate a variable-length array type like int[obj->length] into int[particular_object.length] and then int[{.length = 1, .data = &xyz}.length].
1 parent 361469b commit a985eae

File tree

1 file changed

+28
-41
lines changed

1 file changed

+28
-41
lines changed

src/goto-programs/interpreter_evaluate.cpp

Lines changed: 28 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ Author: Daniel Kroening, [email protected]
1414
#include <util/fixedbv.h>
1515
#include <util/ieee_float.h>
1616
#include <util/pointer_offset_size.h>
17+
#include <util/simplify_expr.h>
1718
#include <util/string_container.h>
1819

1920
#include <langapi/language_util.h>
@@ -894,52 +895,38 @@ void interpretert::evaluate(
894895
mp_integer address=evaluate_address(
895896
expr,
896897
true); // fail quietly
897-
if(address.is_zero() && expr.id()==ID_index)
898+
if(address.is_zero())
898899
{
899-
// Try reading from a constant array:
900-
mp_vectort idx;
901-
evaluate(expr.op1(), idx);
902-
if(idx.size()==1)
900+
exprt simplified;
901+
// In case of being an indexed access, try to evaluate the index, then
902+
// simplify.
903+
if(expr.id() == ID_index)
903904
{
904-
mp_integer read_from_index=idx[0];
905-
if(expr.op0().id()==ID_array)
905+
exprt evaluated_index = expr;
906+
mp_vectort idx;
907+
evaluate(expr.op1(), idx);
908+
if(idx.size() == 1)
906909
{
907-
const auto &ops=expr.op0().operands();
908-
DATA_INVARIANT(read_from_index.is_long(), "index is too large");
909-
if(read_from_index>=0 && read_from_index<ops.size())
910-
{
911-
evaluate(ops[read_from_index.to_long()], dest);
912-
if(dest.size()!=0)
913-
return;
914-
}
915-
}
916-
else if(expr.op0().id() == ID_array_list)
917-
{
918-
// This sort of construct comes from boolbv_get, but doesn't seem
919-
// to have an exprt yet. Its operands are a list of key-value pairs.
920-
const auto &ops=expr.op0().operands();
921-
DATA_INVARIANT(
922-
ops.size()%2==0,
923-
"array-list has odd number of operands");
924-
for(size_t listidx=0; listidx!=ops.size(); listidx+=2)
925-
{
926-
mp_vectort elem_idx;
927-
evaluate(ops[listidx], elem_idx);
928-
CHECK_RETURN(elem_idx.size()==1);
929-
if(elem_idx[0]==read_from_index)
930-
{
931-
evaluate(ops[listidx+1], dest);
932-
if(dest.size()!=0)
933-
return;
934-
else
935-
break;
936-
}
937-
}
938-
// If we fall out the end of this loop then the constant array-list
939-
// didn't define an element matching the index we're looking for.
910+
evaluated_index.op1() =
911+
constant_exprt(integer2string(idx[0]), expr.op1().type());
940912
}
913+
simplified = simplify_expr(evaluated_index, ns);
914+
}
915+
else
916+
{
917+
// Try reading from a constant -- simplify_expr has all the relevant
918+
// cases (index-of-constant-array, member-of-constant-struct and so on)
919+
// Note we complain of a problem even if simplify did *something* but
920+
// still left us with an unresolved index, member, etc.
921+
simplified = simplify_expr(expr, ns);
922+
}
923+
if(simplified.id() == expr.id())
924+
evaluate_address(expr); // Evaluate again to print error message.
925+
else
926+
{
927+
evaluate(simplified, dest);
928+
return;
941929
}
942-
evaluate_address(expr); // Evaluate again to print error message.
943930
}
944931
else if(!address.is_zero())
945932
{

0 commit comments

Comments
 (0)