@@ -21,6 +21,7 @@ Author: Daniel Kroening
2121#include < util/merge_irep.h>
2222#include < util/namespace.h>
2323#include < util/range.h>
24+ #include < util/ssa_expr.h>
2425#include < util/string_utils.h>
2526#include < util/symbol.h>
2627
@@ -52,6 +53,34 @@ std::optional<symbol_exprt> goto_trace_stept::get_lhs_object() const
5253 return get_object_rec (full_lhs);
5354}
5455
56+ // / Remove SSA index suffixes (like !0, @1, etc.) from symbol identifiers
57+ // / in the expression tree. This is used to clean up expressions before
58+ // / displaying them in traces.
59+ static void remove_l0_l1 (exprt &expr)
60+ {
61+ if (expr.id () == ID_symbol)
62+ {
63+ if (is_ssa_expr (expr))
64+ expr = to_ssa_expr (expr).get_original_expr ();
65+ else
66+ {
67+ std::string identifier = id2string (to_symbol_expr (expr).get_identifier ());
68+
69+ std::string::size_type l0_l1 = identifier.find_first_of (" !@" );
70+ if (l0_l1 != std::string::npos)
71+ {
72+ identifier.resize (l0_l1);
73+ to_symbol_expr (expr).set_identifier (identifier);
74+ }
75+ }
76+
77+ return ;
78+ }
79+
80+ Forall_operands (it, expr)
81+ remove_l0_l1 (*it);
82+ }
83+
5584void goto_tracet::output (
5685 const class namespacet &ns,
5786 std::ostream &out) const
@@ -106,9 +135,11 @@ void goto_trace_stept::output(
106135
107136 if (is_assignment ())
108137 {
109- out << " " << format (full_lhs)
110- << " = " << format (full_lhs_value)
111- << ' \n ' ;
138+ exprt clean_lhs = full_lhs;
139+ exprt clean_value = full_lhs_value;
140+ remove_l0_l1 (clean_lhs);
141+ remove_l0_l1 (clean_value);
142+ out << " " << format (clean_lhs) << " = " << format (clean_value) << ' \n ' ;
112143 }
113144
114145 if (!pc->source_location ().is_nil ())
@@ -127,7 +158,9 @@ void goto_trace_stept::output(
127158 if (!comment.empty ())
128159 out << " " << comment << ' \n ' ;
129160
130- out << " " << format (original_condition) << ' \n ' ;
161+ exprt clean_condition = original_condition;
162+ remove_l0_l1 (clean_condition);
163+ out << " " << format (clean_condition) << ' \n ' ;
131164 out << ' \n ' ;
132165 }
133166 }
@@ -299,13 +332,20 @@ static void trace_value(
299332 if (lhs_object.has_value ())
300333 identifier=lhs_object->get_identifier ();
301334
302- out << from_expr (ns, identifier, full_lhs) << ' =' ;
335+ // Create copies to clean up SSA suffixes
336+ exprt clean_lhs = full_lhs;
337+ remove_l0_l1 (clean_lhs);
338+
339+ out << from_expr (ns, identifier, clean_lhs) << ' =' ;
303340
304341 if (value.is_nil ())
305342 out << " (assignment removed)" ;
306343 else
307344 {
308- out << from_expr (ns, identifier, value);
345+ exprt clean_value = value;
346+ remove_l0_l1 (clean_value);
347+
348+ out << from_expr (ns, identifier, clean_value);
309349
310350 // the binary representation
311351 out << ' ' << messaget::faint << ' ('
@@ -414,8 +454,9 @@ void show_compact_goto_trace(
414454
415455 if (step.pc ->is_assert ())
416456 {
417- out << " "
418- << from_expr (ns, step.function_id , step.original_condition )
457+ exprt clean_condition = step.original_condition ;
458+ remove_l0_l1 (clean_condition);
459+ out << " " << from_expr (ns, step.function_id , clean_condition)
419460 << ' \n ' ;
420461 }
421462
@@ -471,10 +512,13 @@ void show_compact_goto_trace(
471512 }
472513
473514 {
474- auto arg_strings = make_range (step.function_arguments )
475- .map ([&ns, &step](const exprt &arg) {
476- return from_expr (ns, step.function_id , arg);
477- });
515+ auto arg_strings =
516+ make_range (step.function_arguments )
517+ .map ([&ns, &step](const exprt &arg) {
518+ exprt clean_arg = arg;
519+ remove_l0_l1 (clean_arg);
520+ return from_expr (ns, step.function_id , clean_arg);
521+ });
478522
479523 out << ' (' ;
480524 join_strings (out, arg_strings.begin (), arg_strings.end (), " , " );
@@ -542,8 +586,9 @@ void show_full_goto_trace(
542586
543587 if (step.pc ->is_assert ())
544588 {
545- out << " "
546- << from_expr (ns, step.function_id , step.original_condition )
589+ exprt clean_condition = step.original_condition ;
590+ remove_l0_l1 (clean_condition);
591+ out << " " << from_expr (ns, step.function_id , clean_condition)
547592 << ' \n ' ;
548593 }
549594
@@ -560,8 +605,9 @@ void show_full_goto_trace(
560605 if (!step.pc ->source_location ().is_nil ())
561606 out << " " << step.pc ->source_location () << ' \n ' ;
562607
563- out << " " << from_expr (ns, step.function_id , step.original_condition )
564- << ' \n ' ;
608+ exprt clean_condition = step.original_condition ;
609+ remove_l0_l1 (clean_condition);
610+ out << " " << from_expr (ns, step.function_id , clean_condition) << ' \n ' ;
565611 }
566612 break ;
567613
@@ -630,7 +676,9 @@ void show_full_goto_trace(
630676 if (l_it!=step.io_args .begin ())
631677 out << ' ;' ;
632678
633- out << ' ' << from_expr (ns, step.function_id , *l_it);
679+ exprt clean_arg = *l_it;
680+ remove_l0_l1 (clean_arg);
681+ out << ' ' << from_expr (ns, step.function_id , clean_arg);
634682
635683 // the binary representation
636684 out << " (" << trace_numeric_value (*l_it, ns, options) << ' )' ;
@@ -652,7 +700,9 @@ void show_full_goto_trace(
652700 if (l_it!=step.io_args .begin ())
653701 out << ' ;' ;
654702
655- out << ' ' << from_expr (ns, step.function_id , *l_it);
703+ exprt clean_arg = *l_it;
704+ remove_l0_l1 (clean_arg);
705+ out << ' ' << from_expr (ns, step.function_id , clean_arg);
656706
657707 // the binary representation
658708 out << " (" << trace_numeric_value (*l_it, ns, options) << ' )' ;
@@ -676,7 +726,9 @@ void show_full_goto_trace(
676726 else
677727 out << " , " ;
678728
679- out << from_expr (ns, step.function_id , arg);
729+ exprt clean_arg = arg;
730+ remove_l0_l1 (clean_arg);
731+ out << from_expr (ns, step.function_id , clean_arg);
680732 }
681733
682734 out << " ) (depth " << function_depth << " ) ####\n " ;
@@ -770,7 +822,9 @@ static void show_goto_stack_trace(
770822 else
771823 out << " , " ;
772824
773- out << from_expr (ns, step.function_id , arg);
825+ exprt clean_arg = arg;
826+ remove_l0_l1 (clean_arg);
827+ out << from_expr (ns, step.function_id , clean_arg);
774828 }
775829
776830 out << ' )' ;
0 commit comments