Skip to content

Commit df6a841

Browse files
author
Joel Allred
authored
Merge pull request #1190 from allredj/bugfix/string-exception-847
Fix crash with exceptions and --string-refine
2 parents 86f1d28 + 6ec155b commit df6a841

File tree

1 file changed

+40
-49
lines changed

1 file changed

+40
-49
lines changed

src/solvers/refinement/string_refinement.cpp

Lines changed: 40 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -415,52 +415,50 @@ void string_refinementt::concretize_lengths()
415415
/// \par parameters: an expression and the value to set it to
416416
void string_refinementt::set_to(const exprt &expr, bool value)
417417
{
418-
INVARIANT(
419-
equality_propagation,
420-
string_refinement_invariantt("set_to should only be called when equality "
421-
"propagation is enabled"));
418+
PRECONDITION(expr.type().id()==ID_bool);
419+
PRECONDITION(equality_propagation);
422420

423421
if(expr.id()==ID_equal)
424422
{
425423
equal_exprt eq_expr=to_equal_expr(expr);
424+
const exprt &lhs=eq_expr.lhs();
425+
const exprt &rhs=eq_expr.rhs();
426+
427+
// The assignment of a string equality to false is not supported.
428+
PRECONDITION(value || !is_char_array(rhs.type()));
429+
PRECONDITION(value ||
430+
!refined_string_typet::is_refined_string_type(rhs.type()));
431+
432+
PRECONDITION(lhs.id()==ID_symbol || !is_char_array(rhs.type()));
433+
PRECONDITION(lhs.id()==ID_symbol ||
434+
!refined_string_typet::is_refined_string_type(rhs.type()));
426435

427-
if(eq_expr.lhs().type()!=eq_expr.rhs().type())
436+
// If lhs is not a symbol, let supert::set_to() handle it.
437+
if(lhs.id()!=ID_symbol)
428438
{
429-
warning() << "ignoring " << from_expr(ns, "", expr)
430-
<< " [inconsistent types]" << eom;
431-
debug() << "lhs has type: " << eq_expr.lhs().type().pretty(12) << eom;
432-
debug() << "rhs has type: " << eq_expr.rhs().type().pretty(12) << eom;
439+
non_string_axioms.push_back(std::make_pair(expr, value));
433440
return;
434441
}
435442

436-
if(expr.type().id()!=ID_bool)
443+
if(lhs.type()!=rhs.type())
437444
{
438-
error() << "string_refinementt::set_to got non-boolean operand: "
439-
<< expr.pretty() << eom;
440-
INVARIANT(
441-
false,
442-
string_refinement_invariantt("set_to should only be called with exprs "
443-
"of type bool"));
445+
warning() << "ignoring " << from_expr(ns, "", expr)
446+
<< " [inconsistent types]" << eom;
447+
debug() << "lhs has type: " << lhs.type().pretty(12) << eom;
448+
debug() << "rhs has type: " << rhs.type().pretty(12) << eom;
449+
return;
444450
}
445451

446452
// Preprocessing to remove function applications.
447-
const exprt &lhs=eq_expr.lhs();
448453
debug() << "(sr::set_to) " << from_expr(ns, "", lhs)
449-
<< " = " << from_expr(ns, "", eq_expr.rhs()) << eom;
450-
451-
// TODO: See if this happens at all.
452-
if(lhs.id()!=ID_symbol)
453-
{
454-
warning() << "ignoring " << from_expr(ns, "", expr) << eom;
455-
return;
456-
}
454+
<< " = " << from_expr(ns, "", rhs) << eom;
457455

458-
exprt subst_rhs=substitute_function_applications(eq_expr.rhs());
459-
if(eq_expr.lhs().type()!=subst_rhs.type())
456+
const exprt subst_rhs=substitute_function_applications(rhs);
457+
if(lhs.type()!=subst_rhs.type())
460458
{
461-
if(eq_expr.lhs().type().id() != ID_array ||
462-
subst_rhs.type().id() != ID_array ||
463-
eq_expr.lhs().type().subtype() != subst_rhs.type().subtype())
459+
if(lhs.type().id()!=ID_array ||
460+
subst_rhs.type().id()!=ID_array ||
461+
lhs.type().subtype()!=subst_rhs.type().subtype())
464462
{
465463
warning() << "ignoring " << from_expr(ns, "", expr)
466464
<< " [inconsistent types after substitution]" << eom;
@@ -473,29 +471,22 @@ void string_refinementt::set_to(const exprt &expr, bool value)
473471
}
474472
}
475473

476-
if(value)
477-
{
478-
if(!add_axioms_for_string_assigns(lhs, subst_rhs))
479-
return;
480-
}
481-
else
482-
{
483-
// TODO: Something should also be done if value is false.
484-
INVARIANT(
485-
!is_char_array(eq_expr.rhs().type()),
486-
string_refinement_invariantt("set_to cannot set a char_array"));
487-
INVARIANT(
488-
!refined_string_typet::is_refined_string_type(eq_expr.rhs().type()),
489-
string_refinement_invariantt("set_to cannot set a refined_string"));
490-
}
474+
if(value && !add_axioms_for_string_assigns(lhs, subst_rhs))
475+
return;
491476

492-
non_string_axioms.push_back(std::make_pair(equal_exprt(lhs, subst_rhs),
493-
value));
477+
// Push the substituted equality to the list of axioms to be given to
478+
// supert::set_to.
479+
non_string_axioms.push_back(
480+
std::make_pair(equal_exprt(lhs, subst_rhs), value));
494481
}
495-
// We keep a list of the axioms to give to supert::set_to in order to
496-
// substitute the symbols in dec_solve().
482+
// Push the unmodified equality to the list of axioms to be given to
483+
// supert::set_to.
497484
else
485+
{
486+
// TODO: Verify that the expression contains no string.
487+
// This will be easy once exprt iterators will have been implemented.
498488
non_string_axioms.push_back(std::make_pair(expr, value));
489+
}
499490
}
500491

501492
/// use a refinement loop to instantiate universal axioms, call the sat solver,

0 commit comments

Comments
 (0)