@@ -854,6 +854,49 @@ decision_proceduret::resultt string_refinementt::dec_solve()
854854 return resultt::D_ERROR;
855855}
856856
857+ // / In a best-effort manner, try to clean up the type inconsistencies introduced
858+ // / by \ref array_poolt::make_char_array_for_char_pointer, which creates
859+ // / conditional expressions for the size of arrays. The cleanup is achieved by
860+ // / removing branches that are found to be infeasible, and by simplifying the
861+ // / conditional size expressions previously generated.
862+ // / \param expr: Expression to be cleaned
863+ // / \param ns: Namespace
864+ // / \return Cleaned expression
865+ static exprt adjust_if_recursive (exprt expr, const namespacet &ns)
866+ {
867+ for (auto it = expr.depth_begin (); it != expr.depth_end ();)
868+ {
869+ if (it->id () == ID_if)
870+ {
871+ if_exprt if_expr = to_if_expr (*it);
872+ const exprt simp_cond = simplify_expr (if_expr.cond (), ns);
873+ if (simp_cond.is_true ())
874+ {
875+ it.mutate () = adjust_if_recursive (if_expr.true_case (), ns);
876+ it.next_sibling_or_parent ();
877+ }
878+ else if (simp_cond.is_false ())
879+ {
880+ it.mutate () = adjust_if_recursive (if_expr.false_case (), ns);
881+ it.next_sibling_or_parent ();
882+ }
883+ else if (
884+ it->type ().id () == ID_array &&
885+ to_array_type (it->type ()).size ().id () == ID_if)
886+ {
887+ simplify (to_array_type (it.mutate ().type ()).size (), ns);
888+ ++it;
889+ }
890+ else
891+ ++it;
892+ }
893+ else
894+ ++it;
895+ }
896+
897+ return expr;
898+ }
899+
857900// / Add the given lemma to the solver.
858901// / \param lemma: a Boolean expression
859902// / \param simplify_lemma: whether the lemma should be simplified before being
@@ -869,7 +912,10 @@ void string_refinementt::add_lemma(
869912
870913 exprt simple_lemma = lemma;
871914 if (simplify_lemma)
915+ {
916+ simple_lemma = adjust_if_recursive (std::move (simple_lemma), ns);
872917 simplify (simple_lemma, ns);
918+ }
873919
874920 if (simple_lemma.is_true ())
875921 {
@@ -917,7 +963,7 @@ static optionalt<exprt> get_array(
917963{
918964 const auto eom = messaget::eom;
919965 const exprt &size = arr.length ();
920- exprt arr_val = simplify_expr (super_get (arr), ns);
966+ exprt arr_val = simplify_expr (adjust_if_recursive ( super_get (arr), ns ), ns);
921967 exprt size_val = super_get (size);
922968 size_val = simplify_expr (size_val, ns);
923969 const typet char_type = arr.type ().subtype ();
0 commit comments