Skip to content

Commit 321746e

Browse files
authored
Merge pull request diffblue#389 from diffblue/bugfix/include_statics_in_func_summary
[SEC-209] Initialise new globals in function summaries
2 parents 2dbdb71 + 8ec0f3d commit 321746e

File tree

9 files changed

+67
-28
lines changed

9 files changed

+67
-28
lines changed

regression/LVSA/TestEVS/Test$A.class

0 Bytes
Binary file not shown.

regression/LVSA/TestEVS/Test$B.class

0 Bytes
Binary file not shown.

regression/LVSA/TestEVS/Test$C.class

0 Bytes
Binary file not shown.
0 Bytes
Binary file not shown.

regression/LVSA/TestEVS/Test.class

-160 Bytes
Binary file not shown.

regression/LVSA/TestEVS/Test.java

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -78,19 +78,16 @@ public void call_overridden_method_on_A(A a) {
7878
}
7979

8080
public void apply_call_overridden_method_on_A_with_A() {
81-
Node n = static_node; // workaround for SEC-209
8281
A a = new A();
8382
call_overridden_method_on_A(a);
8483
}
8584

8685
public void apply_call_overridden_method_on_A_with_B() {
87-
Node n = static_node; // workaround for SEC-209
8886
B b = new B();
8987
call_overridden_method_on_A(b);
9088
}
9189

9290
public void apply_call_overridden_method_on_A_with_C() {
93-
Node n = static_node; // workaround for SEC-209
9491
C c = new C();
9592
call_overridden_method_on_A(c);
9693
}
@@ -119,20 +116,17 @@ public static void function_with_B_parameter(B b) {
119116
}
120117

121118
public void call_function_with_B_parameter_with_C_argument(C c) {
122-
Object o = static_object; // workaround for SEC-209
123119
Test.function_with_B_parameter(c);
124120
}
125121

126122
public void call_function_with_B_parameter_with_A_argument_cast_to_C(A a) {
127-
Object o = static_object; // workaround for SEC-209
128123
if (a instanceof C) {
129124
Test.function_with_B_parameter((C)a);
130125
}
131126
}
132127

133128
public void
134129
apply_call_function_with_B_parameter_with_A_argument_cast_to_C_with_C(C c) {
135-
Object o = static_object; // workaround for SEC-209
136130
c.extra_object = new Object();
137131
call_function_with_B_parameter_with_A_argument_cast_to_C(c);
138132
}
@@ -173,7 +167,6 @@ public void function_which_sets_static_variable() {
173167
}
174168

175169
public void apply_function_which_sets_static_variable() {
176-
Object o = static_object; // workaround for SEC-209
177170
function_which_sets_static_variable();
178171
}
179172

@@ -184,7 +177,6 @@ public void function_which_may_set_static_variable(Boolean b) {
184177
}
185178

186179
public void apply_function_which_may_set_static_variable(Boolean b) {
187-
Object o = static_object; // workaround for SEC-209
188180
function_which_may_set_static_variable(b);
189181
}
190182
}

regression/LVSA/TestEscapeAnalysis/test_escape_analysis.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,10 @@ def test_outputs_dynamic_object(tmpdir):
2727

2828
value_set_expectation = lvsa_expectation.get_value_set_for_output()
2929

30-
value_set_expectation.check_number_of_values(1)
30+
value_set_expectation.check_number_of_values(2)
3131
value_set_expectation.check_contains_dynamic_object()
32+
value_set_expectation.check_contains_root_object_evs(
33+
label_suffix='java::LVSA.TestEscapeAnalysis.Test.output')
3234

3335

3436
def test_dynamic_object_assigned_to_field_of_parameter(tmpdir):

regression/LVSA/TestPreciseAccessPaths/test_precise_access_paths.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,11 @@ def test_apply_field_setter(tmpdir):
2222

2323
value_set_expectation = lvsa_expectation.get_value_set_for_output()
2424

25-
value_set_expectation.check_number_of_values(1)
25+
value_set_expectation.check_number_of_values(2)
2626
value_set_expectation.check_contains_root_object_evs(
2727
label_suffix='java::LVSA.TestPreciseAccessPaths.Test.static_object')
28+
value_set_expectation.check_contains_root_object_evs(
29+
label_suffix='java::LVSA.TestPreciseAccessPaths.Test.output')
2830

2931

3032
def test_field_getter(tmpdir):
@@ -212,8 +214,10 @@ def test_apply_get_list_node(tmpdir):
212214

213215
value_set_expectation = lvsa_expectation.get_value_set_for_output()
214216

215-
value_set_expectation.check_number_of_values(1)
217+
value_set_expectation.check_number_of_values(2)
216218
value_set_expectation.check_contains_per_field_evs(access_path=['.data'])
219+
value_set_expectation.check_contains_root_object_evs(
220+
label_suffix='java::LVSA.TestPreciseAccessPaths.Test.output')
217221

218222

219223
def test_two_field_derefs(tmpdir):

src/pointer-analysis/local_value_set_analysis.cpp

Lines changed: 58 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -62,26 +62,21 @@ static void gather_external_symbols(
6262
gather_external_symbols(it->code, ns, result);
6363
}
6464

65-
void local_value_set_analysist::initialize(const goto_programt &fun)
65+
/// Adds default external value set entries for all external symbols
66+
/// to the passed-in local value set.
67+
/// \param external_symbols: vector of external symbols to add
68+
/// \param ns: namespace for the code under analysis
69+
/// \param value_set: value set that the default entires should be put into
70+
static void add_default_evses(
71+
std::vector<symbol_exprt> &external_symbols,
72+
const namespacet &ns,
73+
local_value_sett &value_set)
6674
{
67-
baset::initialize(fun);
68-
69-
if(fun.instructions.empty())
70-
return;
71-
72-
std::vector<symbol_exprt> external_symbols;
73-
74-
for(const auto &param : function_type.parameters())
75-
external_symbols.emplace_back(param.get_identifier(), param.type());
76-
77-
gather_external_symbols(fun, ns, external_symbols);
78-
7975
std::sort(external_symbols.begin(), external_symbols.end());
8076
external_symbols.erase(
8177
std::unique(external_symbols.begin(), external_symbols.end()),
8278
external_symbols.end());
8379

84-
auto &initial_state = (*this)[fun.instructions.begin()].value_set;
8580
const external_value_set_typet default_mode_for_new_evs =
8681
external_value_set_typet::ROOT_OBJECT;
8782

@@ -99,13 +94,32 @@ void local_value_set_analysist::initialize(const goto_programt &fun)
9994
false);
10095
local_value_sett::entryt extsym_entry_blank(
10196
id2string(extsym_name), "", typet(), extsym_var);
102-
auto &extsym_entry = initial_state.get_entry(
103-
extsym_entry_blank, extsym.type().subtype(), ns);
104-
initial_state.insert(extsym_entry.object_map, extsym_var);
97+
auto &extsym_entry =
98+
value_set.get_entry(extsym_entry_blank, extsym.type().subtype(), ns);
99+
value_set.insert(extsym_entry.object_map, extsym_var);
105100
}
106101
}
107102
}
108103

104+
void local_value_set_analysist::initialize(const goto_programt &fun)
105+
{
106+
baset::initialize(fun);
107+
108+
if(fun.instructions.empty())
109+
return;
110+
111+
std::vector<symbol_exprt> external_symbols;
112+
113+
for(const auto &param : function_type.parameters())
114+
external_symbols.emplace_back(param.get_identifier(), param.type());
115+
116+
gather_external_symbols(fun, ns, external_symbols);
117+
118+
auto &initial_state = (*this)[fun.instructions.begin()].value_set;
119+
120+
add_default_evses(external_symbols, ns, initial_state);
121+
}
122+
109123
/// Collects all value-set entries that match a given field name, and optionally
110124
/// a type. For example, `get_all_field_value_sets("x", typet(), ...)` would
111125
/// get all entries concerning an "x" field, whereas
@@ -365,6 +379,33 @@ void local_value_set_analysist::transform_function_stub(
365379
// Thus start by reading all RHS values, before any changes are made:
366380

367381
auto &valuesets = static_cast<domaint &>(state).value_set;
382+
383+
// We need to find all potential static / global variables and initalize
384+
// them with default values.
385+
std::vector<symbol_exprt> external_symbols;
386+
for(const auto &assignment : assignments)
387+
{
388+
const auto &lhs = assignment.first;
389+
if(lhs.structured_lhs.id() == ID_external_value_set)
390+
{
391+
const symbolt *ext_sym;
392+
if(!ns.lookup(lhs.base_name, ext_sym) && ext_sym->is_static_lifetime)
393+
{
394+
symbol_exprt sym_expr = ext_sym->symbol_expr();
395+
const auto &sym_identifier = id2string(sym_expr.get_identifier());
396+
if(!has_suffix(sym_identifier, RETURN_VALUE_SUFFIX))
397+
{
398+
external_symbols.push_back(sym_expr);
399+
}
400+
}
401+
}
402+
}
403+
404+
if(!external_symbols.empty())
405+
{
406+
add_default_evses(external_symbols, ns, valuesets);
407+
}
408+
368409
std::map<exprt, local_value_sett::object_mapt> pre_call_rhs_value_sets;
369410

370411
for(const auto &assignment : assignments)

0 commit comments

Comments
 (0)