Skip to content

Commit f32d905

Browse files
author
owen-jones-diffblue
authored
Merge pull request diffblue#294 from diffblue/owen-jones-diffblue/precise-access-paths
turn on precise access paths in very limited situations
2 parents 1e18b03 + faf5334 commit f32d905

16 files changed

+773
-252
lines changed

regression/LVSA/TestEVS/test_evs.py

+16-12
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from regression.LVSA.lvsa_driver import LvsaDriver
1+
from regression.LVSA.lvsa_driver import LvsaDriver, EvsType
22

33
folder_name = 'TestEVS'
44

@@ -7,27 +7,31 @@ def test_write_static_field_to_parameter_field(tmpdir):
77
lvsa_driver = LvsaDriver(tmpdir, folder_name).with_test_function('write_static_field_to_parameter_field')
88
lvsa_expectation = lvsa_driver.run()
99

10-
value_set_expectation = lvsa_expectation.get_value_set_for_external_value_set('Node', '.left')
10+
value_set_expectation = lvsa_expectation.get_value_set_for_per_field_evs(inner_class_name='Node', suffix='.left')
1111

12-
value_set_expectation.check_number_of_values(2)
13-
value_set_expectation.check_contains_external_value_set(expected_number=2)
12+
value_set_expectation.check_number_of_values(3)
13+
value_set_expectation.check_contains_per_field_evs(is_initializer=True, access_path=['.left'])
14+
value_set_expectation.check_contains_per_field_evs(access_path=['.left'])
15+
value_set_expectation.check_contains_precise_evs(access_path=['.left'])
1416

1517

1618
def test_write_parameter_field_to_static_field(tmpdir):
1719
lvsa_driver = LvsaDriver(tmpdir, folder_name).with_test_function('write_parameter_field_to_static_field')
1820
lvsa_expectation = lvsa_driver.run()
1921

20-
value_set_expectation = lvsa_expectation.get_value_set_for_external_value_set('Node', '.left')
22+
value_set_expectation = lvsa_expectation.get_value_set_for_per_field_evs(inner_class_name='Node', suffix='.left')
2123

22-
value_set_expectation.check_number_of_values(2)
23-
value_set_expectation.check_contains_external_value_set(expected_number=2)
24+
value_set_expectation.check_number_of_values(3)
25+
value_set_expectation.check_contains_per_field_evs(is_initializer=True, access_path=['.left'])
26+
value_set_expectation.check_contains_per_field_evs(access_path=['.left'])
27+
value_set_expectation.check_contains_precise_evs(access_path=['.left'])
2428

2529

2630
def test_write_new_class_to_parameter_field(tmpdir):
2731
lvsa_driver = LvsaDriver(tmpdir, folder_name).with_test_function('write_new_class_to_parameter_field')
2832
lvsa_expectation = lvsa_driver.run()
2933

30-
value_set_expectation = lvsa_expectation.get_value_set_for_external_value_set('Node', '.left')
34+
value_set_expectation = lvsa_expectation.get_value_set_for_per_field_evs(inner_class_name='Node', suffix='.left')
3135

3236
value_set_expectation.check_contains_dynamic_object()
3337

@@ -36,7 +40,7 @@ def test_write_new_class_to_static_field(tmpdir):
3640
lvsa_driver = LvsaDriver(tmpdir, folder_name).with_test_function('write_new_class_to_static_field')
3741
lvsa_expectation = lvsa_driver.run()
3842

39-
value_set_expectation = lvsa_expectation.get_value_set_for_external_value_set('Node', '.left')
43+
value_set_expectation = lvsa_expectation.get_value_set_for_per_field_evs(inner_class_name='Node', suffix='.left')
4044

4145
value_set_expectation.check_contains_dynamic_object()
4246

@@ -45,14 +49,14 @@ def test_is_initializer_flag(tmpdir):
4549
lvsa_driver = LvsaDriver(tmpdir, folder_name).with_test_function('is_initializer_flag')
4650
lvsa_expectation = lvsa_driver.run()
4751

48-
value_set_expectation_1 = lvsa_expectation.get_value_set_for_external_value_set('Node', '.left')
52+
value_set_expectation_1 = lvsa_expectation.get_value_set_for_per_field_evs(inner_class_name='Node', suffix='.left')
4953

5054
value_set_expectation_1.check_number_of_values(2)
5155
value_set_expectation_1.check_contains_dynamic_object(is_most_recent_allocation=True)
52-
value_set_expectation_1.check_contains_external_value_set(is_initializer=True)
56+
value_set_expectation_1.check_contains_per_field_evs(is_initializer=True, access_path=['.left'])
5357

5458
value_set_expectation_2 = lvsa_expectation.get_value_set_for_public_static('static_object')
5559

5660
value_set_expectation_2.check_number_of_values(2)
5761
value_set_expectation_2.check_contains_dynamic_object(is_most_recent_allocation=True)
58-
value_set_expectation_2.check_contains_external_value_set(is_initializer=False)
62+
value_set_expectation_2.check_contains_per_field_evs(access_path=['.left'])
149 Bytes
Binary file not shown.

regression/LVSA/TestEscapeAnalysis/Test.java

+5
Original file line numberDiff line numberDiff line change
@@ -47,4 +47,9 @@ public void apply_dynamic_object_assigned_to_field_of_parameter(A param) {
4747
public void dynamic_object_assigned_to_field_of_field_of_parameter(B param) {
4848
param.a.object = new Object();
4949
}
50+
51+
public void apply_dynamic_object_assigned_to_field_of_field_of_parameter(
52+
B param) {
53+
dynamic_object_assigned_to_field_of_field_of_parameter(param);
54+
}
5055
}

regression/LVSA/TestEscapeAnalysis/test_escape_analysis.py

+14-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
from regression.LVSA.lvsa_driver import LvsaDriver
22

3-
43
folder_name = 'TestEscapeAnalysis'
54

65

@@ -32,10 +31,21 @@ def test_outputs_dynamic_object(tmpdir):
3231
value_set_expectation.check_contains_dynamic_object()
3332

3433

35-
def test_dynamic_object_assigned_to_parameter(tmpdir):
36-
lvsa_driver = LvsaDriver(tmpdir, folder_name).with_test_function('apply_dynamic_object_assigned_to_field_of_parameter')
34+
def test_dynamic_object_assigned_to_field_of_parameter(tmpdir):
35+
lvsa_driver = LvsaDriver(tmpdir, folder_name).with_test_function(
36+
'apply_dynamic_object_assigned_to_field_of_parameter')
37+
lvsa_expectation = lvsa_driver.run()
38+
39+
value_set_expectation = lvsa_expectation.get_value_set_for_per_field_evs(inner_class_name='A', suffix='.object')
40+
41+
value_set_expectation.check_contains_dynamic_object()
42+
43+
44+
def test_dynamic_object_assigned_to_field_of_field_of_parameter(tmpdir):
45+
lvsa_driver = LvsaDriver(tmpdir, folder_name).with_test_function(
46+
'apply_dynamic_object_assigned_to_field_of_field_of_parameter')
3747
lvsa_expectation = lvsa_driver.run()
3848

39-
value_set_expectation = lvsa_expectation.get_value_set_for_external_value_set(inner_class='A', suffix='.object')
49+
value_set_expectation = lvsa_expectation.get_value_set_for_per_field_evs(inner_class_name='A', suffix='.object')
4050

4151
value_set_expectation.check_contains_dynamic_object()
-28 Bytes
Binary file not shown.
473 Bytes
Binary file not shown.
Binary file not shown.
Binary file not shown.

regression/LVSA/TestPreciseAccessPaths/Test.java

+98-18
Original file line numberDiff line numberDiff line change
@@ -2,47 +2,98 @@
22

33
public class Test {
44
static Object output;
5-
A left_a;
6-
A right_a;
5+
static Object static_object;
6+
static A output_a;
7+
static ListNode static_list_node;
8+
A a1;
9+
A a2;
710

811
public static class A {
9-
Object left_object;
10-
Object right_object;
12+
Object object;
1113
}
1214

1315
// Precise access paths should work fine
1416
public void field_setter(A parameter_a) {
15-
output = parameter_a.left_object;
17+
output = parameter_a.object;
18+
}
19+
20+
public void apply_field_setter() {
21+
A dynamic_object_a = new A();
22+
dynamic_object_a.object = static_object;
23+
field_setter(dynamic_object_a);
24+
output_a = dynamic_object_a;
1625
}
1726

1827
// Precise access paths should work fine
1928
public Object field_getter() {
20-
return left_a.left_object;
29+
return a1.object;
30+
}
31+
32+
public Object apply_field_getter() {
33+
return field_getter();
34+
}
35+
36+
// Precise access paths should work fine
37+
public void set_field_of_external_object(
38+
A parameter_a, Object parameter_object) {
39+
parameter_a.object = parameter_object;
40+
}
41+
42+
public void apply_set_field_of_external_object(
43+
A parameter_a, Object parameter_object) {
44+
set_field_of_external_object(parameter_a, parameter_object);
45+
}
46+
47+
// Precise access paths should work fine
48+
public void conditionally_set_field_of_external_object(
49+
A parameter_a, Object parameter_object, boolean b) {
50+
if (b) {
51+
parameter_a.object = parameter_object;
52+
}
53+
}
54+
55+
public void apply_conditionally_set_field_of_external_object(
56+
A parameter_a, Object parameter_object, boolean b) {
57+
conditionally_set_field_of_external_object(
58+
parameter_a, parameter_object, b);
2159
}
2260

2361
// Precise access paths should work fine
2462
public void read_field_before_writing_to_aliasable_field() {
25-
output = right_a.left_object;
26-
left_a.left_object = new Object();
63+
output = a2.object;
64+
a1.object = new Object();
2765
}
2866

29-
// Precise access paths must be careful that right_a.left_object could be
30-
// aliased by left_a.left_object, so it might be changed by the first line,
31-
// and thus we cannot just return "right_a.left_object"
67+
// Precise access paths should work fine
68+
public void apply_read_field_before_writing_to_aliasable_field() {
69+
read_field_before_writing_to_aliasable_field();
70+
}
71+
72+
// Precise access paths must be careful that a2.object could be
73+
// aliased by a1.object, so it might be changed by the first line,
74+
// and thus we cannot just return "a2.object"
3275
public void read_field_after_writing_to_aliasable_field() {
33-
left_a.left_object = new Object();
34-
output = right_a.left_object;
76+
a1.object = new Object();
77+
output = a2.object;
78+
}
79+
80+
public void apply_read_field_after_writing_to_aliasable_field() {
81+
read_field_after_writing_to_aliasable_field();
3582
}
3683

3784
// Helper function for call_function_to_allocate_new_object()
3885
public void allocate_new_object(A input_A) {
39-
input_A.left_object = new Object();
40-
}
86+
input_A.object = new Object();
87+
}
4188

4289
// Precise access paths should work fine
4390
public void call_function_to_allocate_new_object(A param_A) {
4491
allocate_new_object(param_A);
45-
output = param_A.left_object;
92+
output = param_A.object;
93+
}
94+
95+
public void apply_call_function_to_allocate_new_object(A param_A) {
96+
call_function_to_allocate_new_object(param_A);
4697
}
4798

4899
public static class ListNode {
@@ -60,14 +111,43 @@ public void get_list_node(ListNode list_node, int index) {
60111
output = list_node.data;
61112
}
62113

114+
public void apply_get_list_node(ListNode list_node, int index) {
115+
get_list_node(list_node, index);
116+
}
117+
118+
public static class B {
119+
A a;
120+
}
121+
122+
// Precise access paths should work fine
123+
public void two_derefs(B parameter_b) {
124+
output = parameter_b.a.object;
125+
}
126+
127+
public void apply_two_derefs(B parameter_b) {
128+
two_derefs(parameter_b);
129+
}
130+
131+
public void simple_function_should_export_precise_access_paths(A param_a) {
132+
param_a.object = static_object;
133+
}
134+
135+
public void check_using_precise_access_paths() {
136+
A dynamic_object_1 = new A();
137+
A dynamic_object_2 = new A();
138+
simple_function_should_export_precise_access_paths(dynamic_object_2);
139+
output = dynamic_object_1.object;
140+
}
141+
63142
public void simple_function_should_export_imprecise_access_paths(A param_a) {
64-
param_a.left_object = new Object();
143+
param_a.object = new Object();
144+
static_list_node.data = null;
65145
}
66146

67147
public void check_using_imprecise_access_paths() {
68148
A dynamic_object_1 = new A();
69149
A dynamic_object_2 = new A();
70150
simple_function_should_export_imprecise_access_paths(dynamic_object_2);
71-
output = dynamic_object_1.left_object;
151+
output = dynamic_object_1.object;
72152
}
73153
}

0 commit comments

Comments
 (0)