Skip to content

Commit cd6b7c9

Browse files
Add c-specific refinement utils
For handling byte-extract expression, string-constants etc., in places that expect string arrays. Also slightly extend the definition of char-type.
1 parent 6d21a4a commit cd6b7c9

File tree

2 files changed

+81
-3
lines changed

2 files changed

+81
-3
lines changed

src/solvers/strings/string_refinement_util.cpp

Lines changed: 76 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,19 +14,27 @@ Author: Diffblue Ltd.
1414
#include <numeric>
1515
#include <unordered_set>
1616
#include <util/arith_tools.h>
17+
#include <util/expr_cast.h>
1718
#include <util/expr_iterator.h>
1819
#include <util/expr_util.h>
1920
#include <util/graph.h>
2021
#include <util/magic.h>
2122
#include <util/make_unique.h>
2223
#include <util/ssa_expr.h>
23-
#include <util/std_expr.h>
24+
#include <util/string2int.h>
25+
#include <util/string_constant.h>
2426
#include <util/unicode.h>
2527

2628
bool is_char_type(const typet &type)
2729
{
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;
3038
}
3139

3240
bool is_char_array_type(const typet &type, const namespacet &ns)
@@ -192,3 +200,68 @@ array_exprt interval_sparse_arrayt::concretize(
192200
size, it == entries.end() ? default_value : it->second);
193201
return array;
194202
}
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+
}

src/solvers/strings/string_refinement_util.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,4 +140,9 @@ class interval_sparse_arrayt final : public sparse_arrayt
140140
}
141141
};
142142

143+
exprt maybe_remove_string_exprs(const exprt &expr);
144+
145+
exprt maybe_byte_extract_expr(const exprt &expr);
146+
147+
exprt massage_weird_arrays_into_non_weird_arrays(const exprt &expr);
143148
#endif // CPROVER_SOLVERS_REFINEMENT_STRING_REFINEMENT_UTIL_H

0 commit comments

Comments
 (0)