|
14 | 14 | #include <util/fixedbv.h> |
15 | 15 | #include <util/ieee_float.h> |
16 | 16 | #include <util/pointer_offset_size.h> |
| 17 | +#include <util/simplify_expr.h> |
17 | 18 | #include <util/string_container.h> |
18 | 19 |
|
19 | 20 | #include <langapi/language_util.h> |
@@ -894,52 +895,38 @@ void interpretert::evaluate( |
894 | 895 | mp_integer address=evaluate_address( |
895 | 896 | expr, |
896 | 897 | true); // fail quietly |
897 | | - if(address.is_zero() && expr.id()==ID_index) |
| 898 | + if(address.is_zero()) |
898 | 899 | { |
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) |
903 | 904 | { |
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) |
906 | 909 | { |
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()); |
940 | 912 | } |
| 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; |
941 | 929 | } |
942 | | - evaluate_address(expr); // Evaluate again to print error message. |
943 | 930 | } |
944 | 931 | else if(!address.is_zero()) |
945 | 932 | { |
|
0 commit comments