@@ -411,6 +411,29 @@ exprt smt2_incremental_decision_proceduret::get_expr(
411411 get_value_response->pairs ()[0 ].get ().value (), type);
412412}
413413
414+ // This is a fall back which builds resulting expression based on getting the
415+ // values of its operands. It is used during trace building in the case where
416+ // certain kinds of expression appear on the left hand side of an
417+ // assignment. For example in the following trace assignment -
418+ // `byte_extract_little_endian(x, offset) = 1`
419+ // `::get` will be called on `byte_extract_little_endian(x, offset)` and
420+ // we build a resulting expression where `x` and `offset` are substituted
421+ // with their values.
422+ static exprt build_expr_based_on_getting_operands (
423+ const exprt &expr,
424+ const stack_decision_proceduret &decision_procedure)
425+ {
426+ exprt copy = expr;
427+ for (auto &op : copy.operands ())
428+ {
429+ exprt eval_op = decision_procedure.get (op);
430+ if (eval_op.is_nil ())
431+ return nil_exprt{};
432+ op = std::move (eval_op);
433+ }
434+ return copy;
435+ }
436+
414437exprt smt2_incremental_decision_proceduret::get (const exprt &expr) const
415438{
416439 log.conditional_output (log.debug (), [&](messaget::mstreamt &debug) {
@@ -468,15 +491,7 @@ exprt smt2_incremental_decision_proceduret::get(const exprt &expr) const
468491 << symbol_expr->get_identifier () << messaget::eom;
469492 return expr;
470493 }
471- exprt copy = expr;
472- for (auto &op : copy.operands ())
473- {
474- exprt eval_op = get (op);
475- if (eval_op.is_nil ())
476- return nil_exprt{};
477- op = std::move (eval_op);
478- }
479- return copy;
494+ return build_expr_based_on_getting_operands (expr, *this );
480495 }
481496 if (const auto array_type = type_try_dynamic_cast<array_typet>(expr.type ()))
482497 {
0 commit comments