@@ -18,7 +18,9 @@ Author: Daniel Kroening, kroening@kroening.com
1818#include " expr_util.h"
1919#include " fixedbv.h"
2020#include " ieee_float.h"
21+ #include " invariant.h"
2122#include " namespace.h"
23+ #include " pointer_offset_size.h"
2224#include " rational.h"
2325#include " rational_tools.h"
2426#include " std_expr.h"
@@ -1101,45 +1103,47 @@ bool simplify_exprt::simplify_power(exprt &expr)
11011103}
11021104
11031105// / Simplifies extracting of bits from a constant.
1104- bool simplify_exprt::simplify_extractbits (exprt &expr)
1106+ bool simplify_exprt::simplify_extractbits (extractbits_exprt &expr)
11051107{
1106- assert (expr.operands ().size ()==3 );
1107-
1108- const typet &op0_type=expr.op0 ().type ();
1108+ const typet &op0_type = expr.src ().type ();
11091109
11101110 if (!is_bitvector_type (op0_type) &&
11111111 !is_bitvector_type (expr.type ()))
11121112 return true ;
11131113
1114- if (expr.op0 ().is_constant ())
1115- {
1116- std::size_t width=to_bitvector_type (op0_type).get_width ();
1117- mp_integer start, end;
1114+ mp_integer start, end;
11181115
1119- if (to_integer (expr.op1 (), start))
1120- return true ;
1116+ if (to_integer (expr.upper (), start))
1117+ return true ;
11211118
1122- if (to_integer (expr.op2 (), end))
1123- return true ;
1119+ if (to_integer (expr.lower (), end))
1120+ return true ;
11241121
1125- if (start<0 || start>=width ||
1126- end<0 || end>=width)
1127- return true ;
1122+ const mp_integer width = pointer_offset_bits (op0_type, ns);
11281123
1129- assert (start>=end); // is this always the case??
1124+ if (start < 0 || start >= width || end < 0 || end >= width)
1125+ return true ;
11301126
1131- const irep_idt &value=expr.op0 ().get (ID_value);
1127+ DATA_INVARIANT (
1128+ start >= end,
1129+ " extractbits must have upper() >= lower()" );
1130+
1131+ if (expr.src ().is_constant ())
1132+ {
1133+ const irep_idt &value = to_constant_expr (expr.src ()).get_value ();
11321134
11331135 if (value.size ()!=width)
11341136 return true ;
11351137
11361138 std::string svalue=id2string (value);
11371139
1138- std::string extracted_value=
1139- svalue.substr (width-integer2size_t (start)-1 ,
1140- integer2size_t (start-end+1 ));
1140+ std::string extracted_value =
1141+ svalue.substr (
1142+ integer2size_t (width - start - 1 ),
1143+ integer2size_t (start - end + 1 ));
11411144
1142- expr = constant_exprt (extracted_value, expr.type ());
1145+ constant_exprt result (extracted_value, expr.type ());
1146+ expr.swap (result);
11431147
11441148 return false ;
11451149 }
0 commit comments