Skip to content

Commit eb51d47

Browse files
author
Owen
committed
Add tests for value-set filtering for virtual method calls
The test without a deref in the this argument works with value-set filtering on its own. The test with a deref in the this argument also requires the use temporary variable for the this argument of virtual method calls (though we only need to do this when a dispatch table is made and when the this argument contains a dereference).
1 parent 8e87635 commit eb51d47

File tree

7 files changed

+76
-0
lines changed

7 files changed

+76
-0
lines changed
Binary file not shown.
Binary file not shown.
Binary file not shown.
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
CORE
2+
virtual_filter_value_sets.class
3+
--show-vcc --function virtual_filter_value_sets.test_with_deref
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
java::B\.f:\(\)I#return_value!0#.* = 9$
7+
--
8+
java::B\.f:\(\)I#return_value!0#.* = .*byte_extract_.*_endian
9+
^warning: ignoring
10+
--
11+
When B.f is called on `c.a_field`, it is guarded by a conditional which implies
12+
that `c.a_field` must be a B. Symex should filter the value set for `c.a_field`
13+
to remove anything which doesn't satisfy that condition. It will then be able
14+
to determine that the return value of B.f is 9. If it thinks that `c.a_field`
15+
might contain an A then it will create a more complicated expression for the
16+
return value of B.f, which will include byte_extract_little_endian or
17+
byte_extract_big_endian, as this is what it will produce when trying to read
18+
the field `int flag` from a class that doesn't have any fields.
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
CORE
2+
virtual_filter_value_sets.class
3+
--show-vcc --function virtual_filter_value_sets.test_without_deref
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
java::B\.f:\(\)I#return_value!0#.* = 9$
7+
--
8+
java::B\.f:\(\)I#return_value!0#.* = .*byte_extract_.*_endian
9+
^warning: ignoring
10+
--
11+
When B.f is called on `a_or_b`, it is guarded by a conditional which implies
12+
that `a_or_b` must be a B. Symex should filter the value set for `a_or_b` to
13+
remove anything which doesn't satisfy that condition. It will then be able
14+
to determine that the return value of B.f is 9. If it thinks that `a_or_b`
15+
might contain an A then it will create a more complicated expression for the
16+
return value of B.f, which will include byte_extract_little_endian or
17+
byte_extract_big_endian, as this is what it will produce when trying to read
18+
the field `int flag` from a class that doesn't have any fields.
Binary file not shown.
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
class A {
2+
public int f() { return 1; }
3+
};
4+
5+
class B extends A {
6+
public int flag;
7+
8+
public int f() { return flag; }
9+
};
10+
11+
class Container {
12+
public A a_field;
13+
}
14+
15+
class virtual_filter_value_sets {
16+
public static void test_without_deref(boolean nondet_bool) {
17+
A a = new A();
18+
19+
B b = new B();
20+
b.flag = 9;
21+
22+
A a_or_b = nondet_bool ? a : b;
23+
int retval = a_or_b.f();
24+
25+
assert false;
26+
}
27+
28+
public static void test_with_deref(boolean nondet_bool) {
29+
A a = new A();
30+
31+
B b = new B();
32+
b.flag = 9;
33+
34+
Container c = new Container();
35+
c.a_field = nondet_bool ? a : b;
36+
int retval = c.a_field.f();
37+
38+
assert false;
39+
}
40+
}

0 commit comments

Comments
 (0)