Skip to content

Commit 78d811f

Browse files
author
Daniel Kroening
authored
Merge pull request #2204 from diffblue/remove-lhs-object
remove lhs_object from goto_trace_stept
2 parents 575ff4a + df868b8 commit 78d811f

File tree

10 files changed

+166
-129
lines changed

10 files changed

+166
-129
lines changed
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
int global_var;
2+
3+
struct S
4+
{
5+
int f;
6+
int array[3];
7+
} my_nested[2];
8+
9+
int main()
10+
{
11+
static int static_var;
12+
int local_var;
13+
int *p=&my_nested[0].array[1];
14+
int *q=&my_nested[1].f;
15+
int *null=0;
16+
int *junk;
17+
18+
global_var=1;
19+
static_var=2;
20+
local_var=3;
21+
*p=4;
22+
*q=5;
23+
*null=6;
24+
*junk=7;
25+
26+
// dynamic
27+
p=malloc(sizeof(int)*2);
28+
p[1]=8;
29+
30+
// not even a pointer variable
31+
*(int *)0=9;
32+
33+
// assign entire struct
34+
my_nested[1]=my_nested[0];
35+
36+
// get a trace
37+
__CPROVER_assert(0, "");
38+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
CORE
2+
trace-values.c
3+
--trace
4+
^EXIT=10$
5+
^SIGNAL=0$
6+
^ local_var=0 .*$
7+
^ global_var=1 .*$
8+
^ static_var=2 .*$
9+
^ local_var=3 .*$
10+
^ my_nested\[0.*\].array\[1.*\]=4 .*$
11+
^ my_nested\[1.*\].f=5 .*$
12+
^ null\$object=6 .*$
13+
^ junk\$object=7 .*$
14+
^ dynamic_object1\[1.*\]=8 .*$
15+
^ my_nested\[1.*\]={ .f=0, .array={ 0, 4, 0 } } .*$
16+
^VERIFICATION FAILED$
17+
--
18+
^warning: ignoring

src/goto-programs/goto_trace.cpp

Lines changed: 31 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,25 @@ Author: Daniel Kroening
2424

2525
#include "printf_formatter.h"
2626

27+
static optionalt<symbol_exprt> get_object_rec(const exprt &src)
28+
{
29+
if(src.id()==ID_symbol)
30+
return to_symbol_expr(src);
31+
else if(src.id()==ID_member)
32+
return get_object_rec(to_member_expr(src).struct_op());
33+
else if(src.id()==ID_index)
34+
return get_object_rec(to_index_expr(src).array());
35+
else if(src.id()==ID_typecast)
36+
return get_object_rec(to_typecast_expr(src).op());
37+
else
38+
return {}; // give up
39+
}
40+
41+
optionalt<symbol_exprt> goto_trace_stept::get_lhs_object() const
42+
{
43+
return get_object_rec(full_lhs);
44+
}
45+
2746
void goto_tracet::output(
2847
const class namespacet &ns,
2948
std::ostream &out) const
@@ -217,15 +236,15 @@ std::string trace_numeric_value(
217236
void trace_value(
218237
std::ostream &out,
219238
const namespacet &ns,
220-
const ssa_exprt &lhs_object,
239+
const optionalt<symbol_exprt> &lhs_object,
221240
const exprt &full_lhs,
222241
const exprt &value,
223242
const trace_optionst &options)
224243
{
225244
irep_idt identifier;
226245

227-
if(lhs_object.is_not_nil())
228-
identifier=lhs_object.get_object_name();
246+
if(lhs_object.has_value())
247+
identifier=lhs_object->get_identifier();
229248

230249
std::string value_string;
231250

@@ -346,7 +365,7 @@ void show_full_goto_trace(
346365
if(step.pc->is_assign() ||
347366
step.pc->is_return() || // returns have a lhs!
348367
step.pc->is_function_call() ||
349-
(step.pc->is_other() && step.lhs_object.is_not_nil()))
368+
(step.pc->is_other() && step.full_lhs.is_not_nil()))
350369
{
351370
if(prev_step_nr!=step.step_nr || first_step)
352371
{
@@ -356,23 +375,13 @@ void show_full_goto_trace(
356375
out, ns, step, step.pc->source_location, step.step_nr, options);
357376
}
358377

359-
// see if the full lhs is something clean
360-
if(is_index_member_symbol(step.full_lhs))
361-
trace_value(
362-
out,
363-
ns,
364-
step.lhs_object,
365-
step.full_lhs,
366-
step.full_lhs_value,
367-
options);
368-
else
369-
trace_value(
370-
out,
371-
ns,
372-
step.lhs_object,
373-
step.lhs_object,
374-
step.lhs_object_value,
375-
options);
378+
trace_value(
379+
out,
380+
ns,
381+
step.get_lhs_object(),
382+
step.full_lhs,
383+
step.full_lhs_value,
384+
options);
376385
}
377386
break;
378387

@@ -386,7 +395,7 @@ void show_full_goto_trace(
386395
}
387396

388397
trace_value(
389-
out, ns, step.lhs_object, step.full_lhs, step.full_lhs_value, options);
398+
out, ns, step.get_lhs_object(), step.full_lhs, step.full_lhs_value, options);
390399
break;
391400

392401
case goto_trace_stept::typet::OUTPUT:

src/goto-programs/goto_trace.h

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -104,14 +104,14 @@ class goto_trace_stept
104104
// for assert
105105
std::string comment;
106106

107-
// the object being assigned
108-
ssa_exprt lhs_object;
109-
110-
// the full, original lhs expression
107+
// the full, original lhs expression, after dereferencing
111108
exprt full_lhs;
112109

113-
// A constant with the new value
114-
exprt lhs_object_value, full_lhs_value;
110+
// the object being assigned
111+
optionalt<symbol_exprt> get_lhs_object() const;
112+
113+
// A constant with the new value of the lhs
114+
exprt full_lhs_value;
115115

116116
// for INPUT/OUTPUT
117117
irep_idt format_string, io_id;
@@ -141,8 +141,6 @@ class goto_trace_stept
141141
cond_value(false),
142142
formatted(false)
143143
{
144-
lhs_object.make_nil();
145-
lhs_object_value.make_nil();
146144
full_lhs.make_nil();
147145
full_lhs_value.make_nil();
148146
cond_expr.make_nil();
@@ -245,9 +243,10 @@ void show_goto_trace(
245243
void trace_value(
246244
std::ostream &out,
247245
const namespacet &,
248-
const ssa_exprt &lhs_object,
246+
const optionalt<symbol_exprt> &lhs_object,
249247
const exprt &full_lhs,
250-
const exprt &value);
248+
const exprt &value,
249+
const trace_optionst &);
251250

252251
#define OPT_GOTO_TRACE \
253252
"(trace-json-extended)" \

src/goto-programs/graphml_witness.cpp

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -278,24 +278,17 @@ void graphml_witnesst::operator()(const goto_tracet &goto_trace)
278278
}
279279

280280
if(it->type==goto_trace_stept::typet::ASSIGNMENT &&
281-
it->lhs_object_value.is_not_nil() &&
281+
it->full_lhs_value.is_not_nil() &&
282282
it->full_lhs.is_not_nil())
283283
{
284-
if(!it->lhs_object_value.is_constant() ||
285-
!it->lhs_object_value.has_operands() ||
286-
!has_prefix(id2string(it->lhs_object_value.op0().get(ID_value)),
287-
"INVALID-"))
288-
{
289-
xmlt &val=edge.new_element("data");
290-
val.set_attribute("key", "assumption");
291-
code_assignt assign(it->lhs_object, it->lhs_object_value);
292-
irep_idt identifier=it->lhs_object.get_identifier();
293-
val.data=convert_assign_rec(identifier, assign);
294-
295-
xmlt &val_s=edge.new_element("data");
296-
val_s.set_attribute("key", "assumption.scope");
297-
val_s.data=id2string(it->pc->source_location.get_function());
298-
}
284+
xmlt &val=edge.new_element("data");
285+
val.set_attribute("key", "assumption");
286+
val.data=from_expr(ns, it->pc->function, it->full_lhs)+" = "+
287+
from_expr(ns, it->pc->function, it->full_lhs_value)+";";
288+
289+
xmlt &val_s=edge.new_element("data");
290+
val_s.set_attribute("key", "assumption.scope");
291+
val_s.data=id2string(it->pc->source_location.get_function());
299292
}
300293
else if(it->type==goto_trace_stept::typet::GOTO &&
301294
it->pc->is_goto())

src/goto-programs/interpreter.cpp

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -677,15 +677,7 @@ void interpretert::execute_assign()
677677
goto_trace_stept &trace_step=steps.get_last_step();
678678
assign(address, rhs);
679679
trace_step.full_lhs=code_assign.lhs();
680-
681-
// TODO: need to look at other cases on ssa_exprt
682-
// (dereference should be handled on ssa)
683-
if(ssa_exprt::can_build_identifier(trace_step.full_lhs))
684-
{
685-
trace_step.lhs_object=ssa_exprt(trace_step.full_lhs);
686-
}
687680
trace_step.full_lhs_value=get_value(trace_step.full_lhs.type(), rhs);
688-
trace_step.lhs_object_value=trace_step.full_lhs_value;
689681
}
690682
}
691683
else if(code_assign.rhs().id()==ID_side_effect)

src/goto-programs/json_goto_trace.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,10 @@ void convert_decl(
7777
const jsont &json_location = conversion_dependencies.location;
7878
const namespacet &ns = conversion_dependencies.ns;
7979

80-
irep_idt identifier = step.lhs_object.get_identifier();
80+
auto lhs_object=step.get_lhs_object();
81+
82+
irep_idt identifier =
83+
lhs_object.has_value()?lhs_object->get_identifier():irep_idt();
8184

8285
json_assignment["stepType"] = json_stringt("assignment");
8386

src/goto-programs/vcd_goto_trace.cpp

Lines changed: 36 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -89,16 +89,20 @@ void output_vcd(
8989
{
9090
if(step.is_assignment())
9191
{
92-
irep_idt identifier=step.lhs_object.get_identifier();
93-
const typet &type=step.lhs_object.type();
92+
auto lhs_object=step.get_lhs_object();
93+
if(lhs_object.has_value())
94+
{
95+
irep_idt identifier=lhs_object->get_identifier();
96+
const typet &type=lhs_object->type();
9497

95-
const auto number=n.number(identifier);
98+
const auto number=n.number(identifier);
9699

97-
const mp_integer width = pointer_offset_bits(type, ns);
100+
const mp_integer width = pointer_offset_bits(type, ns);
98101

99-
if(width>=1)
100-
out << "$var reg " << width << " V" << number << " "
101-
<< identifier << " $end" << "\n";
102+
if(width>=1)
103+
out << "$var reg " << width << " V" << number << " "
104+
<< identifier << " $end" << "\n";
105+
}
102106
}
103107
}
104108

@@ -113,30 +117,34 @@ void output_vcd(
113117
{
114118
case goto_trace_stept::typet::ASSIGNMENT:
115119
{
116-
irep_idt identifier=step.lhs_object.get_identifier();
117-
const typet &type=step.lhs_object.type();
118-
119-
out << '#' << timestamp << "\n";
120-
timestamp++;
121-
122-
const auto number=n.number(identifier);
123-
124-
// booleans are special in VCD
125-
if(type.id()==ID_bool)
120+
auto lhs_object=step.get_lhs_object();
121+
if(lhs_object.has_value())
126122
{
127-
if(step.lhs_object_value.is_true())
128-
out << "1" << "V" << number << "\n";
129-
else if(step.lhs_object_value.is_false())
130-
out << "0" << "V" << number << "\n";
123+
irep_idt identifier=lhs_object->get_identifier();
124+
const typet &type=lhs_object->type();
125+
126+
out << '#' << timestamp << "\n";
127+
timestamp++;
128+
129+
const auto number=n.number(identifier);
130+
131+
// booleans are special in VCD
132+
if(type.id()==ID_bool)
133+
{
134+
if(step.full_lhs_value.is_true())
135+
out << "1" << "V" << number << "\n";
136+
else if(step.full_lhs_value.is_false())
137+
out << "0" << "V" << number << "\n";
138+
else
139+
out << "x" << "V" << number << "\n";
140+
}
131141
else
132-
out << "x" << "V" << number << "\n";
133-
}
134-
else
135-
{
136-
std::string binary=as_vcd_binary(step.lhs_object_value, ns);
142+
{
143+
std::string binary=as_vcd_binary(step.full_lhs_value, ns);
137144

138-
if(binary!="")
139-
out << "b" << binary << " V" << number << " " << "\n";
145+
if(binary!="")
146+
out << "b" << binary << " V" << number << " " << "\n";
147+
}
140148
}
141149
}
142150
break;

0 commit comments

Comments
 (0)