Skip to content

Commit bd1bbe6

Browse files
author
Owen Jones
committed
Export precise EVSs unless there is a loop
Note that several tests are marked xfail. This will be fixed in SEC-226. # Conflicts: # src/pointer-analysis/local_value_set.cpp
1 parent 50c1cae commit bd1bbe6

File tree

7 files changed

+27
-89
lines changed

7 files changed

+27
-89
lines changed
-326 Bytes
Binary file not shown.

regression/LVSA/TestPreciseAccessPaths/Test.java

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -138,16 +138,4 @@ public void check_using_precise_access_paths() {
138138
simple_function_should_export_precise_access_paths(dynamic_object_2);
139139
output = dynamic_object_1.object;
140140
}
141-
142-
public void simple_function_should_export_imprecise_access_paths(A param_a) {
143-
param_a.object = new Object();
144-
static_list_node.data = null;
145-
}
146-
147-
public void check_using_imprecise_access_paths() {
148-
A dynamic_object_1 = new A();
149-
A dynamic_object_2 = new A();
150-
simple_function_should_export_imprecise_access_paths(dynamic_object_2);
151-
output = dynamic_object_1.object;
152-
}
153141
}

regression/LVSA/TestPreciseAccessPaths/test_precise_access_paths.py

Lines changed: 23 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,9 @@ def test_apply_field_getter(tmpdir):
4444

4545
value_set_expectation = lvsa_expectation.get_value_set_for_return_value()
4646

47-
value_set_expectation.check_number_of_values(1)
47+
value_set_expectation.check_number_of_values(2)
4848
value_set_expectation.check_contains_per_field_evs(access_path=['.object'])
49+
value_set_expectation.check_contains_precise_evs(access_path=['.a1', '.object'])
4950

5051

5152
def test_set_field_of_external_object(tmpdir):
@@ -113,21 +114,17 @@ def test_read_field_before_writing_to_aliasable_field(tmpdir):
113114
value_set_expectation_2.check_contains_per_field_evs(access_path=['.object'])
114115

115116

117+
@pytest.mark.xfail(strict=True)
116118
def test_apply_read_field_before_writing_to_aliasable_field(tmpdir):
117119
lvsa_driver = LvsaDriver(tmpdir, folder_name).with_test_function(
118120
'apply_read_field_before_writing_to_aliasable_field')
119121
lvsa_expectation = lvsa_driver.run()
120122

121-
value_set_expectation_1 = lvsa_expectation.get_value_set_for_per_field_evs(inner_class_name='A', suffix='.object')
122-
123-
value_set_expectation_1.check_number_of_values(2)
124-
value_set_expectation_1.check_contains_per_field_evs(access_path=['.object'], is_initializer=True)
125-
value_set_expectation_1.check_contains_dynamic_object()
126-
127-
value_set_expectation_2 = lvsa_expectation.get_value_set_for_output()
123+
value_set_expectation = lvsa_expectation.get_value_set_for_output()
128124

129-
value_set_expectation_2.check_number_of_values(1)
130-
value_set_expectation_2.check_contains_per_field_evs(access_path=['.object'])
125+
value_set_expectation.check_number_of_values(1)
126+
value_set_expectation.check_contains_precise_evs(label_suffix='this', access_path=['.a2','.object'])
127+
# value_set_expectation.check_contains_per_field_evs(access_path=['.object'], is_initializer=True)
131128

132129

133130
def test_read_field_after_writing_to_aliasable_field(tmpdir):
@@ -148,22 +145,18 @@ def test_read_field_after_writing_to_aliasable_field(tmpdir):
148145
value_set_expectation_2.check_contains_dynamic_object()
149146

150147

148+
@pytest.mark.xfail(strict=True)
151149
def test_apply_read_field_after_writing_to_aliasable_field(tmpdir):
152150
lvsa_driver = LvsaDriver(tmpdir, folder_name).with_test_function(
153151
'apply_read_field_after_writing_to_aliasable_field')
154152
lvsa_expectation = lvsa_driver.run()
155153

156-
value_set_expectation_1 = lvsa_expectation.get_value_set_for_per_field_evs(inner_class_name='A', suffix='.object')
157-
158-
value_set_expectation_1.check_number_of_values(2)
159-
value_set_expectation_1.check_contains_per_field_evs(access_path=['.object'], is_initializer=True)
160-
value_set_expectation_1.check_contains_dynamic_object()
161-
162-
value_set_expectation_2 = lvsa_expectation.get_value_set_for_output()
154+
value_set_expectation = lvsa_expectation.get_value_set_for_output()
163155

164-
value_set_expectation_2.check_number_of_values(2)
165-
value_set_expectation_2.check_contains_per_field_evs(access_path=['.object'])
166-
value_set_expectation_2.check_contains_dynamic_object()
156+
value_set_expectation.check_number_of_values(2)
157+
value_set_expectation.check_contains_precise_evs(label_suffix='this', access_path=['.a2', '.object'])
158+
value_set_expectation.check_contains_dynamic_object()
159+
# value_set_expectation.check_contains_per_field_evs(access_path=['.object'], is_initializer=True)
167160

168161

169162
def test_call_function_to_allocate_new_object(tmpdir):
@@ -178,15 +171,17 @@ def test_call_function_to_allocate_new_object(tmpdir):
178171
value_set_expectation.check_contains_dynamic_object()
179172

180173

174+
@pytest.mark.xfail(strict=True)
181175
def test_apply_call_function_to_allocate_new_object(tmpdir):
182176
lvsa_driver = LvsaDriver(tmpdir, folder_name).with_test_function('apply_call_function_to_allocate_new_object')
183177
lvsa_expectation = lvsa_driver.run()
184178

185179
value_set_expectation = lvsa_expectation.get_value_set_for_output()
186180

187181
value_set_expectation.check_number_of_values(2)
188-
value_set_expectation.check_contains_per_field_evs(access_path=['.object'])
182+
value_set_expectation.check_contains_precise_evs(label_suffix='param_A', access_path=['.object'])
189183
value_set_expectation.check_contains_dynamic_object()
184+
# value_set_expectation.check_contains_per_field_evs(access_path=['.object'], is_initializer=True)
190185

191186

192187
def test_get_list_node(tmpdir):
@@ -208,7 +203,7 @@ def test_apply_get_list_node(tmpdir):
208203
value_set_expectation = lvsa_expectation.get_value_set_for_output()
209204

210205
value_set_expectation.check_number_of_values(1)
211-
value_set_expectation.check_contains_per_field_evs()
206+
value_set_expectation.check_contains_per_field_evs(access_path=['.data'])
212207

213208

214209
def test_two_field_derefs(tmpdir):
@@ -222,14 +217,16 @@ def test_two_field_derefs(tmpdir):
222217
value_set_expectation.check_contains_per_field_evs(access_path=['.object'])
223218

224219

220+
@pytest.mark.xfail(strict=True)
225221
def test_apply_two_field_derefs(tmpdir):
226222
lvsa_driver = LvsaDriver(tmpdir, folder_name).with_test_function('apply_two_field_derefs')
227223
lvsa_expectation = lvsa_driver.run()
228224

229225
value_set_expectation = lvsa_expectation.get_value_set_for_output()
230226

231227
value_set_expectation.check_number_of_values(1)
232-
value_set_expectation.check_contains_per_field_evs(access_path=['.object'])
228+
value_set_expectation.check_contains_precise_evs(label_suffix='parameter_b', access_path=['.a', '.object'])
229+
# value_set_expectation.check_contains_per_field_evs(access_path=['.object'], is_initializer=True)
233230

234231

235232
def test_array_deref(tmpdir):
@@ -243,32 +240,13 @@ def test_array_deref(tmpdir):
243240
value_set_expectation.check_contains_per_field_evs(access_path=['[]'])
244241

245242

243+
@pytest.mark.xfail(strict=True)
246244
def test_apply_array_deref(tmpdir):
247245
lvsa_driver = LvsaDriver(tmpdir, folder_name).with_test_function('apply_array_deref')
248246
lvsa_expectation = lvsa_driver.run()
249247

250248
value_set_expectation = lvsa_expectation.get_value_set_for_output()
251249

252250
value_set_expectation.check_number_of_values(1)
253-
value_set_expectation.check_contains_per_field_evs(access_path=['[]'])
254-
255-
256-
def test_check_using_precise_access_paths(tmpdir):
257-
lvsa_driver = LvsaDriver(tmpdir, folder_name).with_test_function('check_using_precise_access_paths')
258-
lvsa_expectation = lvsa_driver.run()
259-
260-
value_set_expectation = lvsa_expectation.get_value_set_for_public_static('output')
261-
262-
value_set_expectation.check_number_of_values(1)
263-
value_set_expectation.check_contains_null_object()
264-
265-
266-
def test_check_using_imprecise_access_paths(tmpdir):
267-
lvsa_driver = LvsaDriver(tmpdir, folder_name).with_test_function('check_using_imprecise_access_paths')
268-
lvsa_expectation = lvsa_driver.run()
269-
270-
value_set_expectation = lvsa_expectation.get_value_set_for_public_static('output')
271-
272-
value_set_expectation.check_number_of_values(2)
273-
value_set_expectation.check_contains_null_object()
274-
value_set_expectation.check_contains_dynamic_object()
251+
value_set_expectation.check_contains_precise_evs(label_suffix='object_array', access_path=['.data', '[]'])
252+
# value_set_expectation.check_contains_per_field_evs(access_path=['.object'], is_initializer=True)

regression/LVSA/TestTest/.gitignore

Whitespace-only changes.

src/pointer-analysis/local_value_set.cpp

Lines changed: 2 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -248,11 +248,6 @@ void local_value_sett::get_value_set_rec(
248248
expr.type(), suffix, ns, declared_on_type, suffix_without_supertypes);
249249
if(field_type.id() == ID_pointer)
250250
{
251-
// Temporary: keep track of whether we read from an EVS, so we can
252-
// ignore precise access path EVSs when applying function summaries if
253-
// there are any reads from EVSs.
254-
++num_reads_of_field_of_external_object;
255-
256251
const auto &extinit = to_external_value_set(expr);
257252

258253
// If we're reading from `EVS(A.b)` then initialize an entry for that
@@ -563,14 +558,6 @@ void local_value_sett::assign_rec(
563558
const typet &field_type = type_from_suffix(
564559
lhs.type(), suffix, ns, declared_on_type, suffix_without_supertypes);
565560

566-
if(field_type.id() == ID_pointer)
567-
{
568-
// Temporary: keep track of how many times we write to a field of an EVS,
569-
// so we can ignore precise access path EVSs when applying function
570-
// summaries if there is more than one write to a field of an EVS.
571-
++num_writes_to_field_of_external_object;
572-
}
573-
574561
if(evsi.can_extend_to_imprecise())
575562
{
576563
std::string access_path_suffix =
@@ -692,19 +679,9 @@ void local_value_sett::apply_code_rec(const codet &code, const namespacet &ns)
692679
bool local_value_sett::make_union_bookkeeping_data_structures(
693680
const local_value_sett &other)
694681
{
695-
bool original_curtailed = precise_evs_curtailed_because_of_loop;
696-
bool original_reads = num_reads_of_field_of_external_object;
697-
bool original_writes = num_writes_to_field_of_external_object;
698-
682+
bool original_value = precise_evs_curtailed_because_of_loop;
699683
precise_evs_curtailed_because_of_loop =
700684
precise_evs_curtailed_because_of_loop ||
701685
other.precise_evs_curtailed_because_of_loop;
702-
num_reads_of_field_of_external_object +=
703-
other.num_reads_of_field_of_external_object;
704-
num_writes_to_field_of_external_object +=
705-
other.num_writes_to_field_of_external_object;
706-
707-
return (precise_evs_curtailed_because_of_loop != original_curtailed) ||
708-
(num_reads_of_field_of_external_object != original_reads) ||
709-
(num_writes_to_field_of_external_object != original_writes);
686+
return precise_evs_curtailed_because_of_loop != original_value;
710687
}

src/pointer-analysis/local_value_set.h

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,6 @@ class local_value_sett : public value_sett
1818
public:
1919
typedef value_sett baset;
2020

21-
mutable unsigned int num_reads_of_field_of_external_object = 0;
22-
mutable unsigned int num_writes_to_field_of_external_object = 0;
2321
mutable bool precise_evs_curtailed_because_of_loop = false;
2422

2523
/// Determines whether we should export precise or per_field external value
@@ -30,10 +28,7 @@ class local_value_sett : public value_sett
3028
#ifdef DO_NOT_USE_PRECISE_EXTERNAL_VALUE_SETS
3129
return false;
3230
#else
33-
return !precise_evs_curtailed_because_of_loop &&
34-
(num_reads_of_field_of_external_object +
35-
num_writes_to_field_of_external_object <=
36-
1);
31+
return !precise_evs_curtailed_because_of_loop;
3732
#endif
3833
}
3934

src/pointer-analysis/local_value_set_analysis.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ static const exprt get_expr_from_root_object(
216216
/// accessing a field of A then access_path_label will be
217217
/// ".@Y.@X.@W. ... [email protected]_name". For an array dereference, the access
218218
/// path will have the label "[]", and the access path entry before
219-
/// it will have the label ".data".
219+
/// it will have a label ending in ".data".
220220
DATA_INVARIANT(
221221
access_path_label.size() >= 2,
222222
"Access path label must have length at least 2");

0 commit comments

Comments
 (0)