Skip to content

Commit fe906d1

Browse files
committed
Restore member-of-union expressions in trace output
byte_extract operations precisely capture the semantics, but aren't meaningful to users.
1 parent 416b744 commit fe906d1

File tree

5 files changed

+58
-8
lines changed

5 files changed

+58
-8
lines changed

regression/cbmc/xml-trace/test.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ VERIFICATION FAILED
77
<assignment assignment_type="state" base_name="u" display_name="test::u" hidden="false" identifier="test::u" mode="C" step_nr="\d+" thread="0">
88
<location file=".*" function="test" line="\d+" working-directory=".*"/>
99
<type>union myunion</type>
10-
<full_lhs>byte_extract_little_endian\(u, 0ll?, .*int.*\)</full_lhs>
10+
<full_lhs>u</full_lhs>
1111
<full_lhs_value binary="[01]+">\d+ll?</full_lhs_value>
1212
<value>\{ \.i=\d+ll? \}</value>
1313
<value_expression>

src/goto-programs/goto_trace.cpp

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ void goto_trace_stept::output(
126126
if(!comment.empty())
127127
out << " " << comment << '\n';
128128

129-
out << " " << format(pc->get_condition()) << '\n';
129+
out << " " << format(cond_expr) << '\n';
130130
out << '\n';
131131
}
132132
}
@@ -397,9 +397,7 @@ void show_compact_goto_trace(
397397

398398
if(step.pc->is_assert())
399399
{
400-
out << " "
401-
<< from_expr(ns, step.function_id, step.pc->get_condition())
402-
<< '\n';
400+
out << " " << from_expr(ns, step.function_id, cond_expr) << '\n';
403401
}
404402

405403
out << '\n';
@@ -524,9 +522,7 @@ void show_full_goto_trace(
524522

525523
if(step.pc->is_assert())
526524
{
527-
out << " "
528-
<< from_expr(ns, step.function_id, step.pc->get_condition())
529-
<< '\n';
525+
out << " " << from_expr(ns, step.function_id, cond_expr) << '\n';
530526
}
531527

532528
out << '\n';

src/goto-programs/rewrite_union.cpp

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,3 +124,51 @@ void rewrite_union(goto_modelt &goto_model)
124124
{
125125
rewrite_union(goto_model.goto_functions);
126126
}
127+
128+
/// Undo the union access -> byte_extract replacement that rewrite_union did for
129+
/// the purpose of displaying expressions to users.
130+
/// \param expr: expression to inspect and possibly transform
131+
/// \param ns: namespace
132+
/// \return True if, and only if, the expression is unmodified
133+
static bool restore_union_rec(exprt &expr, const namespacet &ns)
134+
{
135+
bool unmodified = true;
136+
137+
Forall_operands(it, expr)
138+
unmodified &= restore_union_rec(*it, ns);
139+
140+
if(expr.id() == byte_extract_id())
141+
{
142+
byte_extract_exprt &be = to_byte_extract_expr(expr);
143+
if(
144+
(be.op().type().id() == ID_union ||
145+
be.op().type().id() == ID_union_tag) &&
146+
be.offset().is_zero())
147+
{
148+
const union_typet &union_type = to_union_type(ns.follow(be.op().type()));
149+
150+
for(const auto &comp : union_type.components())
151+
{
152+
if(be.type() == comp.type())
153+
{
154+
expr = member_exprt{be.op(), comp.get_name(), be.type()};
155+
return false;
156+
}
157+
}
158+
}
159+
}
160+
161+
return unmodified;
162+
}
163+
164+
/// Undo the union access -> byte_extract replacement that rewrite_union did for
165+
/// the purpose of displaying expressions to users.
166+
/// \param expr: expression to inspect and possibly transform
167+
/// \param ns: namespace
168+
void restore_union(exprt &expr, const namespacet &ns)
169+
{
170+
exprt tmp = expr;
171+
172+
if(!restore_union_rec(tmp, ns))
173+
expr.swap(tmp);
174+
}

src/goto-programs/rewrite_union.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,6 @@ void rewrite_union(goto_functionst::goto_functiont &);
2424
void rewrite_union(goto_functionst &);
2525
void rewrite_union(goto_modelt &);
2626

27+
void restore_union(exprt &, const namespacet &);
28+
2729
#endif // CPROVER_GOTO_PROGRAMS_REWRITE_UNION_H

src/goto-symex/build_goto_trace.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ Author: Daniel Kroening
2222

2323
#include <solvers/decision_procedure.h>
2424

25+
#include <goto-programs/rewrite_union.h>
26+
2527
#include "partial_order_concurrency.h"
2628

2729
static exprt build_full_lhs_rec(
@@ -378,6 +380,7 @@ void build_goto_trace(
378380
SSA_step.ssa_full_lhs),
379381
ns);
380382
replace_nondet_in_type(goto_trace_step.full_lhs, decision_procedure);
383+
restore_union(goto_trace_step.full_lhs, ns);
381384
}
382385

383386
if(SSA_step.ssa_full_lhs.is_not_nil())
@@ -405,6 +408,7 @@ void build_goto_trace(
405408
if(SSA_step.is_assert() || SSA_step.is_assume() || SSA_step.is_goto())
406409
{
407410
goto_trace_step.cond_expr = SSA_step.cond_expr;
411+
restore_union(goto_trace_step.cond_expr, ns);
408412

409413
goto_trace_step.cond_value =
410414
decision_procedure.get(SSA_step.cond_handle).is_true();

0 commit comments

Comments
 (0)