Skip to content

Commit 673e789

Browse files
committed
Explicitly initialise non-static objects with non-deterministic values
1 parent 9d44f13 commit 673e789

File tree

9 files changed

+125
-13
lines changed

9 files changed

+125
-13
lines changed

regression/cbmc/constant_folding2/test.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
KNOWNBUG
1+
CORE
22
main.c
33

44
^EXIT=0$

regression/cbmc/graphml_witness1/test.desc

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -54,12 +54,6 @@ main.c
5454
<data key="startline">21</data>
5555
</edge>
5656
<node id="[0-9\.]*"/>
57-
<edge source="[0-9\.]*" target="[0-9\.]*">
58-
<data key="originfile">main.c</data>
59-
<data key="startline">29</data>
60-
<data key="assumption.scope">main</data>
61-
</edge>
62-
<node id="[0-9\.]*"/>
6357
<edge source="[0-9\.]*" target="[0-9\.]*">
6458
<data key="originfile">main.c</data>
6559
<data key="startline">15</data>

regression/cbmc/struct10/main.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
<<<<<<< HEAD
12
#include <assert.h>
23

34
struct S
@@ -8,12 +9,25 @@ struct S
89
struct T
910
{
1011
struct S a[2];
12+
=======
13+
struct test_struct
14+
{
15+
int a[2];
16+
int b;
17+
>>>>>>> 2846e8c... Explicitly initialise non-static objects with non-deterministic values
1118
};
1219

1320
int main()
1421
{
22+
<<<<<<< HEAD
1523
struct T t;
1624
t.a[1].x = 42;
1725
assert(t.a[1].x == 42);
1826
return 0;
27+
=======
28+
struct test_struct test;
29+
test.a[1] = 1;
30+
test.b = 1;
31+
__CPROVER_assert(test.a[1] == 0, "");
32+
>>>>>>> 2846e8c... Explicitly initialise non-static objects with non-deterministic values
1933
}

regression/cbmc/struct10/test.desc

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,24 @@
11
CORE
22
main.c
3+
<<<<<<< HEAD
34

45
^EXIT=0$
56
^SIGNAL=0$
67
^VERIFICATION SUCCESSFUL$
78
--
89
^warning: ignoring
10+
=======
11+
--trace
12+
test.a\[1ll?\]=1 \(00000000000000000000000000000001\)$
13+
^EXIT=10$
14+
^SIGNAL=0$
15+
^VERIFICATION FAILED$
16+
--
17+
^warning: ignoring
18+
\(\?\)
19+
--
20+
Earlier versions of non-deterministic initialisation would cause trace output
21+
including
22+
23+
test.a[1l]={ .a={ 0, 1 }, .b=0 }.a[1l] (?)
24+
>>>>>>> 2846e8c... Explicitly initialise non-static objects with non-deterministic values

src/goto-programs/graphml_witness.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,13 +145,15 @@ static bool filter_out(
145145
const goto_tracet::stepst::const_iterator &prev_it,
146146
goto_tracet::stepst::const_iterator &it)
147147
{
148+
// use the goto program's assignment type as declarations may be
149+
// recorded as (non-deterministic) assignments in the trace
148150
if(it->hidden &&
149151
(!it->pc->is_assign() ||
150152
to_code_assign(it->pc->code).rhs().id()!=ID_side_effect ||
151153
to_code_assign(it->pc->code).rhs().get(ID_statement)!=ID_nondet))
152154
return true;
153155

154-
if(!it->is_assignment() && !it->is_goto() && !it->is_assert())
156+
if(!it->pc->is_assign() && !it->is_goto() && !it->is_assert())
155157
return true;
156158

157159
// we filter out steps with the same source location

src/goto-symex/goto_symex.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ Author: Daniel Kroening, [email protected]
1212
#include "goto_symex.h"
1313

1414
#include <util/simplify_expr.h>
15+
#include <util/zero_initializer.h>
1516

1617
unsigned goto_symext::dynamic_counter=0;
1718

@@ -27,3 +28,31 @@ nondet_symbol_exprt symex_nondet_generatort::operator()(typet &type)
2728
nondet_symbol_exprt new_expr(identifier, type);
2829
return new_expr;
2930
}
31+
<<<<<<< HEAD
32+
=======
33+
34+
void goto_symext::replace_nondet(exprt &expr)
35+
{
36+
if(expr.id()==ID_side_effect &&
37+
expr.get(ID_statement)==ID_nondet)
38+
{
39+
exprt nondet = nondet_initializer(
40+
expr.type(), expr.source_location(), ns, log.get_message_handler());
41+
42+
// recursively replace nondet fields in structs or arrays
43+
if(nondet.id() != ID_side_effect)
44+
{
45+
replace_nondet(nondet);
46+
expr.swap(nondet);
47+
return;
48+
}
49+
50+
nondet_symbol_exprt new_expr = build_symex_nondet(expr.type());
51+
new_expr.add_source_location()=expr.source_location();
52+
expr.swap(new_expr);
53+
}
54+
else
55+
Forall_operands(it, expr)
56+
replace_nondet(*it);
57+
}
58+
>>>>>>> 2846e8c... Explicitly initialise non-static objects with non-deterministic values

src/goto-symex/goto_symex.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,26 @@ class goto_symext
250250

251251
// guards
252252

253+
<<<<<<< HEAD
253254
const irep_idt guard_identifier;
255+
=======
256+
irep_idt guard_identifier;
257+
258+
// symex
259+
irep_idt init_l1;
260+
261+
virtual void symex_transition(
262+
statet &,
263+
goto_programt::const_targett to,
264+
bool is_backwards_goto=false);
265+
266+
virtual void symex_transition(statet &state)
267+
{
268+
goto_programt::const_targett next=state.source.pc;
269+
++next;
270+
symex_transition(state, next);
271+
}
272+
>>>>>>> 2846e8c... Explicitly initialise non-static objects with non-deterministic values
254273

255274
virtual void symex_goto(statet &);
256275
virtual void symex_start_thread(statet &);

src/goto-symex/symex_builtin_functions.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,9 +178,23 @@ void goto_symext::symex_allocate(
178178
}
179179
else
180180
{
181+
<<<<<<< HEAD
181182
const exprt nondet = build_symex_nondet(object_type);
182183
const code_assignt assignment(value_symbol.symbol_expr(), nondet);
183184
symex_assign(state, assignment);
185+
=======
186+
side_effect_expr_nondett init(object_type);
187+
replace_nondet(init);
188+
189+
guardt guard;
190+
symex_assign_symbol(
191+
state,
192+
ssa_exprt(value_symbol.symbol_expr()),
193+
nil_exprt(),
194+
init,
195+
guard,
196+
symex_targett::assignment_typet::HIDDEN);
197+
>>>>>>> 2846e8c... Explicitly initialise non-static objects with non-deterministic values
184198
}
185199

186200
exprt rhs;

src/goto-symex/symex_decl.cpp

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@ Author: Daniel Kroening, [email protected]
1515

1616
#include <util/std_expr.h>
1717

18-
#include <pointer-analysis/add_failed_symbols.h>
19-
2018
#include <analyses/dirty.h>
2119

2220
void goto_symext::symex_decl(statet &state)
@@ -45,6 +43,7 @@ void goto_symext::symex_decl(statet &state, const symbol_exprt &expr)
4543
state.rename(ssa.type(), l1_identifier, ns);
4644
ssa.update_type();
4745

46+
<<<<<<< HEAD
4847
// in case of pointers, put something into the value set
4948
if(ns.follow(expr.type()).id()==ID_pointer)
5049
{
@@ -76,6 +75,25 @@ void goto_symext::symex_decl(statet &state, const symbol_exprt &expr)
7675
state.record_events=false;
7776
state.rename(ssa, ns);
7877
state.record_events=record_events;
78+
=======
79+
// L2 renaming
80+
// inlining may yield multiple declarations of the same identifier
81+
// within the same L1 context
82+
if(state.level2.current_names.find(l1_identifier)==
83+
state.level2.current_names.end())
84+
state.level2.current_names[l1_identifier]=std::make_pair(ssa, 0);
85+
init_l1 = l1_identifier;
86+
87+
// optimisation: skip non-deterministic initialisation if the next instruction
88+
// will take care of initialisation (but ensure int x=x; is handled properly)
89+
goto_programt::const_targett next = std::next(state.source.pc);
90+
if(
91+
next->is_assign() && to_code_assign(next->code).lhs() == expr &&
92+
to_code_assign(next->code).rhs().is_constant())
93+
{
94+
return;
95+
}
96+
>>>>>>> 2846e8c... Explicitly initialise non-static objects with non-deterministic values
7997

8098
// we hide the declaration of auxiliary variables
8199
// and if the statement itself is hidden
@@ -84,10 +102,16 @@ void goto_symext::symex_decl(statet &state, const symbol_exprt &expr)
84102
state.top().hidden_function ||
85103
state.source.pc->source_location.get_hide();
86104

87-
target.decl(
88-
state.guard.as_expr(),
105+
side_effect_expr_nondett init(ssa.type());
106+
replace_nondet(init);
107+
108+
guardt guard;
109+
symex_assign_symbol(
110+
state,
89111
ssa,
90-
state.source,
112+
nil_exprt(),
113+
init,
114+
guard,
91115
hidden?
92116
symex_targett::assignment_typet::HIDDEN:
93117
symex_targett::assignment_typet::STATE);

0 commit comments

Comments
 (0)