Skip to content

Commit 21f8b0d

Browse files
committed
Remove SSA thread suffix in goto trace address-of expressions
SSA thread suffixes (e.g., "!0", "@1") are internal SSA identifiers that should be removed when displaying trace information to users. Similar SSA suffix removal logic already existed in `src/goto-programs/graphml_witness.cpp` (the `remove_l0_l1` function), but this logic was not being applied to expressions in the goto trace formatting code. Fixes: #902
1 parent 4fe3ade commit 21f8b0d

File tree

3 files changed

+81
-27
lines changed

3 files changed

+81
-27
lines changed

regression/cbmc-cover/pointer-function-parameters-2/test.desc

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@ main.c
66
a=\(\(signed int \*\*\)NULL\)
77
tmp(\$\d+)?=[^,]*
88
tmp(\$\d+)?=[^,]*
9-
a=&tmp(\$\d+)?!0
9+
a=&tmp(\$\d+)?
1010
tmp(\$\d+)?=\(\(signed int \*\)NULL\)
1111
tmp(\$\d+)?=[^,]*
12-
a=&tmp(\$\d+)?!0
13-
tmp(\$\d+)?=&tmp\$\d+!0
12+
a=&tmp(\$\d+)?
13+
tmp(\$\d+)?=&tmp(\$\d+)?
1414
tmp(\$\d+)?=(-[0-9]+|[012356789][0-9]*|4[0-9]+)
15-
a=&tmp(\$\d+)?!0
16-
tmp(\$\d+)?=&tmp(\$\d+)?!0
15+
a=&tmp(\$\d+)?
16+
tmp(\$\d+)?=&tmp(\$\d+)?
1717
tmp(\$\d+)?=4
1818
^EXIT=0$
1919
^SIGNAL=0$

regression/cbmc-cover/pointer-function-parameters/test.desc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ main.c
44
^\*\* 5 of 5 covered \(100\.0%\)$
55
^Test suite:$
66
^(tmp(\$\d+)?=[^,]*, a=\(\(signed int \*\)NULL\))|(a=\(\(signed int \*\)NULL\), tmp(\$\d+)?=[^,]*)$
7-
^(a=&tmp(\$\d+)?!0@1, tmp(\$\d+)?=4)|(tmp(\$\d+)?=4, a=&tmp(\$\d+)?!0@1)$
8-
^(a=&tmp(\$\d+)?!0@1, tmp(\$\d+)?=([012356789]\d*|4\d+|-\d+))|(tmp(\$\d+)?=([012356789]\d*|4\d+|-\d+), a=&tmp(\$\d+)?!0@1)$
7+
^(a=&tmp(\$\d+)?, tmp(\$\d+)?=4)|(tmp(\$\d+)?=4, a=&tmp(\$\d+)?)$
8+
^(a=&tmp(\$\d+)?, tmp(\$\d+)?=([012356789]\d*|4\d+|-\d+))|(tmp(\$\d+)?=([012356789]\d*|4\d+|-\d+), a=&tmp(\$\d+)?)$
99
^EXIT=0$
1010
^SIGNAL=0$
1111
--

src/goto-programs/goto_trace.cpp

Lines changed: 74 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
5584
void 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

Comments
 (0)