3333#include < solvers/refinement/string_constraint_instantiation.h>
3434#include < langapi/language_util.h>
3535#include < java_bytecode/java_types.h>
36+ #include < util/optional.h>
3637
3738static bool validate (const string_refinementt::infot &info)
3839{
@@ -300,19 +301,26 @@ bool string_refinementt::add_axioms_for_string_assigns(
300301// / Generic case doesn't exist, specialize for different types accordingly
301302// / TODO: this should go to util
302303template <typename T>
303- T expr_cast (const exprt&);
304+ optionalt<T> expr_cast (const exprt&);
304305
305306template <>
306- std:: size_t expr_cast<std:: size_t >(const exprt& val_expr )
307+ optionalt<mp_integer> expr_cast<mp_integer >(const exprt& expr )
307308{
308- mp_integer val_mb;
309- if (to_integer (val_expr, val_mb))
310- throw std::bad_cast ();
311- if (!val_mb.is_long ())
312- throw std::bad_cast ();
313- if (val_mb<0 )
314- throw std::bad_cast ();
315- return val_mb.to_long ();
309+ mp_integer out;
310+ if (to_integer (expr, out))
311+ return { };
312+ return out;
313+ }
314+
315+ template <>
316+ optionalt<std::size_t > expr_cast<std::size_t >(const exprt& expr)
317+ {
318+ if (const auto tmp=expr_cast<mp_integer>(expr))
319+ {
320+ if (tmp->is_long () && *tmp >= 0 )
321+ return tmp->to_long ();
322+ }
323+ return { };
316324}
317325
318326// / If the expression is of type string, then adds constants to the index set to
@@ -336,8 +344,9 @@ void string_refinementt::concretize_string(const exprt &expr)
336344 replace_expr (symbol_resolve, content);
337345 found_length[content]=length;
338346 const auto string_length=expr_cast<std::size_t >(length);
347+ INVARIANT (string_length, " Bad integer conversion" );
339348 INVARIANT (
340- string_length<=generator.max_string_length ,
349+ * string_length<=generator.max_string_length ,
341350 string_refinement_invariantt (" string length must be less than the max "
342351 " length" ));
343352 if (index_set[str.content ()].empty ())
@@ -350,7 +359,7 @@ void string_refinementt::concretize_string(const exprt &expr)
350359 const exprt simple_i=simplify_expr (get (i), ns);
351360 mp_integer mpi_index;
352361 bool conversion_failure=to_integer (simple_i, mpi_index);
353- if (!conversion_failure && mpi_index>=0 && mpi_index<string_length)
362+ if (!conversion_failure && mpi_index>=0 && mpi_index<* string_length)
354363 {
355364 const exprt str_i=simplify_expr (str[simple_i], ns);
356365 const exprt value=simplify_expr (get (str_i), ns);
@@ -896,8 +905,9 @@ exprt fill_in_array_with_expr(const exprt &expr, std::size_t string_max_length)
896905 const with_exprt with_expr=to_with_expr (it);
897906 const exprt &then_expr=with_expr.new_value ();
898907 const auto index=expr_cast<std::size_t >(with_expr.where ());
899- if (index<string_max_length)
900- initial_map.emplace (index, then_expr);
908+ INVARIANT (index, " Bad integer conversion" );
909+ if (*index<string_max_length)
910+ initial_map.emplace (*index, then_expr);
901911 }
902912
903913 array_exprt result (to_array_type (expr.type ()));
0 commit comments