@@ -14,19 +14,27 @@ Author: Diffblue Ltd.
14
14
#include < numeric>
15
15
#include < unordered_set>
16
16
#include < util/arith_tools.h>
17
+ #include < util/expr_cast.h>
17
18
#include < util/expr_iterator.h>
18
19
#include < util/expr_util.h>
19
20
#include < util/graph.h>
20
21
#include < util/magic.h>
21
22
#include < util/make_unique.h>
22
23
#include < util/ssa_expr.h>
23
- #include < util/std_expr.h>
24
+ #include < util/string2int.h>
25
+ #include < util/string_constant.h>
24
26
#include < util/unicode.h>
25
27
26
28
bool is_char_type (const typet &type)
27
29
{
28
- return type.id () == ID_unsignedbv && to_unsignedbv_type (type).get_width () <=
29
- STRING_REFINEMENT_MAX_CHAR_WIDTH;
30
+ if (type.id () == ID_unsignedbv)
31
+ return to_unsignedbv_type (type).get_width () <=
32
+ STRING_REFINEMENT_MAX_CHAR_WIDTH;
33
+
34
+ if (type.id () == ID_signedbv)
35
+ return to_signedbv_type (type).get_width () <= 8 ;
36
+
37
+ return false ;
30
38
}
31
39
32
40
bool is_char_array_type (const typet &type, const namespacet &ns)
@@ -192,3 +200,68 @@ array_exprt interval_sparse_arrayt::concretize(
192
200
size, it == entries.end () ? default_value : it->second );
193
201
return array;
194
202
}
203
+
204
+ exprt maybe_byte_extract_expr (const exprt &expr)
205
+ {
206
+ if (!can_cast_expr<byte_extract_exprt>(expr))
207
+ return expr;
208
+
209
+ const auto &byte_extract_expr = to_byte_extract_expr (expr);
210
+ const auto &offset = byte_extract_expr.offset ();
211
+ PRECONDITION (offset.id () == ID_constant);
212
+ if (offset.id () != ID_constant)
213
+ {
214
+ return expr;
215
+ }
216
+ const auto &constant_offset = to_constant_expr (offset);
217
+ const auto &op = byte_extract_expr.op ();
218
+ auto numeric_offset =
219
+ string2optional_int (id2string (constant_offset.get_value ()));
220
+ PRECONDITION (numeric_offset.has_value ());
221
+ if (*numeric_offset == 0 )
222
+ {
223
+ return op;
224
+ }
225
+
226
+ array_exprt::operandst offset_operands;
227
+ offset_operands.insert (
228
+ offset_operands.end (),
229
+ op.operands ().begin () + *numeric_offset,
230
+ op.operands ().end ());
231
+ const auto extracted_array_suffix =
232
+ array_exprt{offset_operands, to_array_type (op.type ())};
233
+
234
+ return extracted_array_suffix;
235
+ }
236
+
237
+ exprt maybe_remove_string_exprs (const exprt &expr)
238
+ {
239
+ return [&]() {
240
+ if (
241
+ auto const &maybe_string_constant =
242
+ expr_try_dynamic_cast<string_constantt>(expr))
243
+ {
244
+ return static_cast <const exprt &>(maybe_string_constant->to_array_expr ());
245
+ }
246
+ else
247
+ {
248
+ return expr;
249
+ }
250
+ }();
251
+ }
252
+
253
+ exprt massage_weird_arrays_into_non_weird_arrays (const exprt &expr)
254
+ {
255
+ auto const byte_extracted = maybe_byte_extract_expr (expr);
256
+ auto const string_removed = maybe_remove_string_exprs (byte_extracted);
257
+ PRECONDITION (string_removed.type ().id () == ID_array);
258
+ if (string_removed.id () == ID_if)
259
+ {
260
+ return if_exprt{
261
+ string_removed.op0 (),
262
+ massage_weird_arrays_into_non_weird_arrays (string_removed.op1 ()),
263
+ massage_weird_arrays_into_non_weird_arrays (string_removed.op2 ()),
264
+ string_removed.type ()};
265
+ }
266
+ return string_removed;
267
+ }
0 commit comments