Skip to content

Commit bc6c41e

Browse files
authored
Merge pull request #2064 from tautschnig/pointer-overflow-check
Assert type consistency in the simplifier
2 parents b1aadb6 + 8616586 commit bc6c41e

File tree

4 files changed

+51
-3
lines changed

4 files changed

+51
-3
lines changed

src/solvers/strings/string_constraint_generator_main.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,8 @@ array_string_exprt array_poolt::make_char_array_for_char_pointer(
120120
if_expr.cond(),
121121
to_array_type(t.type()).size(),
122122
to_array_type(f.type()).size()));
123+
// BEWARE: this expression is possibly type-inconsistent and must not be
124+
// used for any purposes other than passing it to concretisation
123125
return to_array_string_expr(if_exprt(if_expr.cond(), t, f, array_type));
124126
}
125127
const bool is_constant_array =

src/solvers/strings/string_refinement.cpp

+47-1
Original file line numberDiff line numberDiff line change
@@ -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();

src/util/simplify_expr.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -2548,6 +2548,7 @@ bool simplify_exprt::simplify_rec(exprt &expr)
25482548

25492549
if(!result)
25502550
{
2551+
POSTCONDITION(tmp.type() == expr.type());
25512552
expr.swap(tmp);
25522553

25532554
#ifdef USE_CACHE

src/util/simplify_expr_struct.cpp

+1-2
Original file line numberDiff line numberDiff line change
@@ -265,8 +265,7 @@ bool simplify_exprt::simplify_member(exprt &expr)
265265
if(
266266
equivalent_member.has_value() &&
267267
equivalent_member.value().id() != ID_byte_extract_little_endian &&
268-
equivalent_member.value().id() != ID_byte_extract_big_endian &&
269-
equivalent_member.value().type() == expr.type())
268+
equivalent_member.value().id() != ID_byte_extract_big_endian)
270269
{
271270
expr = equivalent_member.value();
272271
simplify_rec(expr);

0 commit comments

Comments
 (0)