@@ -43,6 +43,13 @@ static void build_NONDET_retvals_replacements(
43
43
to_side_effect_expr (assign.rhs ());
44
44
if (side_effect.get_statement () == ID_nondet)
45
45
{
46
+ // See if we can see that this instruction is definitely
47
+ // dead. Iterate backwards through the program from the current
48
+ // instruction, looking for an unconditional GOTO or a target.
49
+ // If we find an unconditional GOTO first then the instruction
50
+ // is dead. If we find a target first then we must assume that
51
+ // it can be reached. If we reach the beginning before finding
52
+ // either then the instruction is reachable.
46
53
bool is_dead = true ;
47
54
for (auto sit = instr_it;
48
55
sit != instructions.begin ();
@@ -58,6 +65,12 @@ static void build_NONDET_retvals_replacements(
58
65
}
59
66
if (is_dead || side_effect.type ().id () == ID_pointer)
60
67
{
68
+ // Create a new static variable to put on the rhs of this
69
+ // assignment. When the instruction is dead then this is
70
+ // sound. Otherwise this is not sound, but it is
71
+ // preferable to having a pointer that could point to
72
+ // anything. A better solution would be to use the
73
+ // replace_java_nondet pass or similar.
61
74
static unsigned long counter = 0UL ;
62
75
std::stringstream sstr;
63
76
sstr << " @__CPROVER_NONDET_dead_replace_" << ++counter;
@@ -70,10 +83,8 @@ static void build_NONDET_retvals_replacements(
70
83
symbol.base_name = symbol.name ;
71
84
symbol.mode = ID_java;
72
85
symbol.pretty_name = symbol.name ;
86
+ symbol.is_static_lifetime = true ;
73
87
const_cast <symbol_tablet&>(model.symbol_table ).insert (symbol);
74
- // NOTE: This is not a sound solution. However, handling of
75
- // NONDETs is just a temporary solution, until we
76
- // get rid of them completely.
77
88
replacements.insert ({instr_it, symbol.symbol_expr ()});
78
89
}
79
90
}
0 commit comments