Skip to content

Commit ed7a3ba

Browse files
authored
Merge pull request #4407 from smowton/smowton/feature/dead-always-uses-generation-zero
Symex code_deadt: always use L2 generation zero
2 parents 294bab6 + d201bad commit ed7a3ba

File tree

5 files changed

+18
-21
lines changed

5 files changed

+18
-21
lines changed

jbmc/regression/jbmc-strings/StringToLowerCase/test_dependency.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
CORE
22
Test.class
3-
--function Test.withDependency --max-nondet-string-length 10000
3+
--function Test.withDependency --max-nondet-string-length 1000
44
^EXIT=10$
55
^SIGNAL=0$
66
assertion at file Test.java line 48 .*: SUCCESS

jbmc/regression/jbmc/throwing-function-return-value/test.desc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,13 @@ Test.class
33
--function Test.main --show-vcc
44
java::Test\.main:\(Z\)V::14::t1!0@1#\d+ = address_of\(symex_dynamic::dynamic_object\d+\)
55
java::Test\.main:\(Z\)V::9::x!0@1#\d+ = 5 \+ java::Test\.main:\(Z\)V::9::x!0@1#\d+
6+
java::Test\.g:\(\)I#return_value!0#[0-9]+ = 5
67
^EXIT=0$
78
^SIGNAL=0$
89
--
910
return_value!0#0
1011
java::Sub\.g:\(\)
12+
java::Test\.g:\(\)I#return_value!0#[0-9]+ = [^5]
1113
--
1214
This checks that when a function may throw, we can nonetheless constant-propagate
1315
and populate the value-set for the normal-return path. In particular we don't
@@ -16,3 +18,6 @@ reading the return-value when not defined), nor do we expect to see any code
1618
from the Sub class, which is not accessible and can only be reached when
1719
constant propagation has lost information to the point we're not sure which type
1820
virtual calls against Test may find.
21+
The final check ensures there is no uncertainty about whether Test.g() may throw,
22+
which would result in a nondet return-value (corresponding to the hypothetical
23+
throwing path).

src/goto-symex/goto_symex_state.cpp

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -469,19 +469,6 @@ bool goto_symex_statet::l2_thread_read_encoding(
469469
return true;
470470
}
471471

472-
/// Allocates a fresh L2 name for the given L1 identifier, and makes it the
473-
/// latest generation on this path. Does nothing if there isn't an expression
474-
/// keyed by the l1 identifier.
475-
void goto_symex_statet::increase_generation_if_exists(const irep_idt identifier)
476-
{
477-
// If we can't find the name in the local scope, this is a no-op.
478-
auto current_names_iter = level2.current_names.find(identifier);
479-
if(current_names_iter == level2.current_names.end())
480-
return;
481-
482-
current_names_iter->second.second = fresh_l2_name_provider(identifier);
483-
}
484-
485472
goto_symex_statet::write_is_shared_resultt goto_symex_statet::write_is_shared(
486473
const ssa_exprt &expr,
487474
const namespacet &ns) const

src/goto-symex/goto_symex_state.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -223,16 +223,18 @@ class goto_symex_statet final : public goto_statet
223223
l1_identifier, lhs, fresh_l2_name_provider);
224224
}
225225

226-
/// Increases the generation of the L1 identifier. Does nothing if there
227-
/// isn't an expression keyed by it.
228-
void increase_generation_if_exists(const irep_idt identifier);
229-
230226
/// Drops an L1 name from the local L2 map
231227
void drop_l1_name(symex_renaming_levelt::current_namest::const_iterator it)
232228
{
233229
level2.current_names.erase(it);
234230
}
235231

232+
/// Drops an L1 name from the local L2 map
233+
void drop_l1_name(const irep_idt &l1_identifier)
234+
{
235+
level2.current_names.erase(l1_identifier);
236+
}
237+
236238
std::function<std::size_t(const irep_idt &)> get_l2_name_provider() const
237239
{
238240
return fresh_l2_name_provider;

src/goto-symex/symex_dead.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,10 @@ void goto_symext::symex_dead(statet &state)
3030
// can no longer appear
3131
state.value_set.values.erase(l1_identifier);
3232
state.propagation.erase(l1_identifier);
33-
// increment the L2 index to ensure a merge on join points will propagate the
34-
// value for branches that are still live
35-
state.increase_generation_if_exists(l1_identifier);
33+
// Remove from the local L2 renaming map; this means any reads from the dead
34+
// identifier will use generation 0 (e.g. x!N@M#0, where N and M are positive
35+
// integers), which is never defined by any write, and will be dropped by
36+
// `goto_symext::merge_goto` on merging with branches where the identifier
37+
// is still live.
38+
state.drop_l1_name(l1_identifier);
3639
}

0 commit comments

Comments
 (0)